Add NIU Actions buttons to the Go Overview

The buttons send Intents to the designated app (specified by
niu_actions_package) to do the following:
Listen - Read the contents of the screen aloud
Translate - Translate the contents of the screen
Search - Perform a visual search on the contents of the screen

The Intents also include (via URI) the screenshot of current app used as
a thumbnail by Recents.

The feature is controlled by the enable_niu_actions flag, set to false
here. Both this flag and the niu_actions_package String must be set for
a given Launcher to use these buttons.

Bug: 177955244
Bug: 177955748
Test: Manual (enabled on LauncherGoGoogle and sent Intents to demo Lens
app)

Change-Id: I3d1f870bb176ed0cbae637a45c072bd8acac1d4b
This commit is contained in:
Jon Spivack 2021-01-11 17:20:00 -08:00
parent d028812c9e
commit 3a1cfc9082
15 changed files with 527 additions and 32 deletions

View File

@ -145,7 +145,9 @@ LOCAL_SRC_FILES := \
$(call all-java-files-under, quickstep/src) \
$(call all-java-files-under, src_shortcuts_overrides)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/res \
$(LOCAL_PATH)/quickstep/overview_ui_overrides/res
LOCAL_PROGUARD_ENABLED := disabled
@ -174,7 +176,9 @@ LOCAL_SYSTEM_EXT_MODULE := true
LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/res \
$(LOCAL_PATH)/quickstep/overview_ui_overrides/res
LOCAL_FULL_LIBS_MANIFEST_FILES := \
$(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \
@ -213,7 +217,8 @@ LOCAL_SRC_FILES := \
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/res \
$(LOCAL_PATH)/go/res \
$(LOCAL_PATH)/go/quickstep/res
$(LOCAL_PATH)/go/quickstep/res \
$(LOCAL_PATH)/go/quickstep/overview_ui_overrides/res
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
LOCAL_PROGUARD_ENABLED := full

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.quickstep.views.GoOverviewActionsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/overview_actions_height"
android:layout_gravity="center_horizontal|bottom">
<LinearLayout
android:id="@+id/action_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
android:id="@+id/action_listen"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_listen"
android:drawablePadding="1dp"
android:text="@string/action_listen"
android:theme="@style/ThemeControlHighlightWorkspaceColor" />
<Button
android:id="@+id/action_translate"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_translate"
android:drawablePadding="1dp"
android:text="@string/action_translate"
android:theme="@style/ThemeControlHighlightWorkspaceColor" />
<Button
android:id="@+id/action_search"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_search"
android:drawablePadding="1dp"
android:text="@string/action_search"
android:theme="@style/ThemeControlHighlightWorkspaceColor" />
<Button
android:id="@+id/action_screenshot"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_screenshot"
android:drawablePadding="1dp"
android:text="@string/action_screenshot"
android:theme="@style/ThemeControlHighlightWorkspaceColor" />
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Button
android:id="@+id/action_share"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_share"
android:text="@string/action_share"
android:theme="@style/ThemeControlHighlightWorkspaceColor"
android:visibility="gone" />
<Space
android:id="@+id/oav_three_button_space"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"
android:visibility="gone" />
</LinearLayout>
</com.android.quickstep.views.GoOverviewActionsView>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<resources>
<string name="task_overlay_factory_class" translatable="false">
com.android.quickstep.TaskOverlayFactoryGo</string>
</resources>

View File

@ -0,0 +1,32 @@
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:pathData="M10.5,15.17c2.58,0 4.67,-2.09 4.67,-4.67s-2.09,-4.67 -4.67,-4.67c-2.58,0 -4.67,2.09 -4.67,4.67S7.92,15.17 10.5,15.17zM10.5,8.17c1.28,0 2.33,1.05 2.33,2.33s-1.05,2.33 -2.33,2.33c-1.28,0 -2.33,-1.05 -2.33,-2.33S9.22,8.17 10.5,8.17z"
android:fillColor="#4285F4"/>
<path
android:pathData="M10.5,17.5c-3.11,0 -9.33,1.56 -9.33,4.67v2.33h18.67v-2.33C19.83,19.06 13.62,17.5 10.5,17.5zM3.5,22.17c0.26,-0.84 3.86,-2.33 7,-2.33c3.15,0 6.77,1.5 7,2.33H3.5z"
android:fillColor="#4285F4"/>
<path
android:pathData="M25.67,10.5c0,0.36 -0.02,0.71 -0.05,1.05c-0.01,0.15 -0.03,0.29 -0.05,0.43c-0.02,0.18 -0.05,0.36 -0.08,0.54c-0.04,0.2 -0.07,0.39 -0.12,0.58c-0.01,0.06 -0.03,0.11 -0.04,0.17c-0.59,2.34 -1.81,4.01 -2.52,4.82c-0.09,0.1 -0.18,0.2 -0.28,0.3c-0.17,0.18 -0.27,0.27 -0.27,0.27l-1.65,-1.63c1.34,-1.33 2.27,-3.07 2.6,-5.01c0.01,-0.08 0.02,-0.16 0.04,-0.24c0.06,-0.42 0.1,-0.85 0.1,-1.29c0,-0.44 -0.04,-0.88 -0.1,-1.3c-0.01,-0.06 -0.02,-0.13 -0.03,-0.19c-0.32,-1.95 -1.25,-3.7 -2.6,-5.04l1.65,-1.63c0,0 0.11,0.1 0.27,0.27c0.09,0.1 0.19,0.2 0.28,0.3c0.71,0.82 1.93,2.48 2.52,4.82c0.01,0.06 0.03,0.11 0.04,0.17c0.04,0.19 0.08,0.38 0.12,0.58c0.03,0.18 0.06,0.36 0.08,0.54c0.02,0.14 0.04,0.28 0.05,0.43C25.65,9.79 25.67,10.14 25.67,10.5z"
android:fillColor="#EA4335"/>
<path
android:pathData="M20.61,8.4C20.85,9.06 21,9.76 21,10.5s-0.15,1.44 -0.39,2.1c-0.28,0.77 -0.71,1.46 -1.25,2.05l-1.66,-1.64c0.56,-0.63 0.91,-1.44 0.95,-2.34c0,-0.06 0.02,-0.11 0.02,-0.17s-0.01,-0.11 -0.02,-0.17c-0.04,-0.9 -0.39,-1.71 -0.95,-2.34l1.66,-1.64C19.9,6.94 20.32,7.63 20.61,8.4z"
android:fillColor="#FBBC04"/>
</vector>

View File

@ -0,0 +1,32 @@
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:pathData="M24.5,22.75l-6.84,-6.84c1,-1.35 1.59,-3.02 1.59,-4.83h-2.33c0,3.22 -2.62,5.83 -5.83,5.83v2.33c1.81,0 3.47,-0.6 4.83,-1.59l6.84,6.84L24.5,22.75z"
android:fillColor="#4285F4"/>
<path
android:pathData="M11.08,2.92v2.33c3.22,0 5.83,2.62 5.83,5.83h2.33C19.25,6.57 15.59,2.92 11.08,2.92z"
android:fillColor="#34A853"/>
<path
android:pathData="M5.25,11.08H2.92c0,4.51 3.66,8.17 8.17,8.17v-2.33C7.87,16.92 5.25,14.3 5.25,11.08z"
android:fillColor="#EA4335"/>
<path
android:pathData="M2.92,11.08h2.33c0,-3.22 2.62,-5.83 5.83,-5.83V2.92C6.57,2.92 2.92,6.57 2.92,11.08z"
android:fillColor="#FBBC04"/>
</vector>

View File

@ -0,0 +1,32 @@
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:pathData="M12.28,15.19l-0.07,-0.05c-0.61,-0.49 -1.15,-1.05 -1.65,-1.63c-1.05,-1.22 -1.88,-2.63 -2.39,-4.17H5.83c0.54,2.17 1.58,4.16 3.01,5.85l-5.93,5.23l1.75,1.75l5.91,-5.26c0.05,0.04 0.1,0.09 0.15,0.13l3.42,2.79l1.02,-2.33L12.28,15.19z"
android:fillColor="#FBBC04"/>
<path
android:pathData="M21.58,11.67h-2.33l-5.25,14h2.33l1.31,-3.5h5.54l1.32,3.5h2.33L21.58,11.67zM18.53,19.83l1.89,-5.05l1.89,5.05H18.53z"
android:fillColor="#4285F4"/>
<path
android:pathData="M11.67,2.33l-2.34,0l0,2.34l-8.16,0l0,2.33l10.5,0l0,-2.33z"
android:fillColor="#EA4335"/>
<path
android:pathData="M11.67,4.67V7H14c-0.61,2.42 -1.79,4.65 -3.44,6.5c0.5,0.59 1.04,1.15 1.65,1.63l0.07,0.05c2.03,-2.32 3.44,-5.14 4.05,-8.19h3.5V4.67H11.67z"
android:fillColor="#34A853"/>
</vector>

View File

@ -14,5 +14,11 @@
limitations under the License.
-->
<resources>
<!-- The component to receive app sharing Intents -->
<string name="app_sharing_component" translatable="false"/>
<!-- The package to receive Listen, Translate, and Search Intents -->
<string name="niu_actions_package" translatable="false"/>
<!-- Feature Flags -->
<bool name="enable_niu_actions">false</bool>
</resources>

View File

@ -3,4 +3,12 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Label for app share drop target. [CHAR_LIMIT=20] -->
<string name="app_share_drop_target_label">Share App</string>
<!-- ******* Overview ******* -->
<!-- Label for a button that lets the user listen to the content of the current app. [CHAR_LIMIT=40] -->
<string name="action_listen">Listen</string>
<!-- Label for a button that translates a screenshot of the current app. [CHAR_LIMIT=40] -->
<string name="action_translate">Translate</string>
<!-- Label for a button that triggers Search on a screenshot of the current app. [CHAR_LIMIT=40] -->
<string name="action_search">Search</string>
</resources>

View File

@ -0,0 +1,147 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep;
import static com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBNAIL;
import static com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Matrix;
import android.os.SystemClock;
import android.text.TextUtils;
import com.android.launcher3.R;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
/**
* Go-specific extension of the factory class that adds an overlay to TaskView
*/
public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
public static final String ACTION_LISTEN = "com.android.quickstep.ACTION_LISTEN";
public static final String ACTION_TRANSLATE = "com.android.quickstep.ACTION_TRANSLATE";
public static final String ACTION_SEARCH = "com.android.quickstep.ACTION_SEARCH";
public static final String ELAPSED_NANOS = "niu_actions_elapsed_realtime_nanos";
// Empty constructor required for ResourceBasedOverride
public TaskOverlayFactoryGo(Context context) {}
/**
* Create a new overlay instance for the given View
*/
public TaskOverlayGo createOverlay(TaskThumbnailView thumbnailView) {
return new TaskOverlayGo(thumbnailView);
}
/**
* Overlay on each task handling Overview Action Buttons.
* @param <T> The type of View in which the overlay will be placed
*/
public static final class TaskOverlayGo<T extends OverviewActionsView> extends TaskOverlay {
private String mPackageName;
private TaskOverlayGo(TaskThumbnailView taskThumbnailView) {
super(taskThumbnailView);
}
/**
* Called when the current task is interactive for the user
*/
@Override
public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix,
boolean rotated) {
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
mPackageName =
mApplicationContext.getResources().getString(R.string.niu_actions_package);
if (thumbnail == null || TextUtils.isEmpty(mPackageName)) {
return;
}
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
}
private void sendNIUIntent(String actionType) {
Intent intent = createNIUIntent(actionType);
mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent);
}
private Intent createNIUIntent(String actionType) {
return new Intent(actionType)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
.setPackage(mPackageName)
.putExtra(ELAPSED_NANOS, SystemClock.elapsedRealtimeNanos());
}
protected class OverlayUICallbacksGoImpl extends OverlayUICallbacksImpl
implements OverlayUICallbacksGo {
public OverlayUICallbacksGoImpl(boolean isAllowedByPolicy, Task task) {
super(isAllowedByPolicy, task);
}
@SuppressLint("NewApi")
public void onListen() {
if (mIsAllowedByPolicy) {
sendNIUIntent(ACTION_LISTEN);
} else {
showBlockedByPolicyMessage();
}
}
@SuppressLint("NewApi")
public void onTranslate() {
if (mIsAllowedByPolicy) {
sendNIUIntent(ACTION_TRANSLATE);
} else {
showBlockedByPolicyMessage();
}
}
@SuppressLint("NewApi")
public void onSearch() {
if (mIsAllowedByPolicy) {
sendNIUIntent(ACTION_SEARCH);
} else {
showBlockedByPolicyMessage();
}
}
}
}
/**
* Callbacks the Ui can generate. This is the only way for a Ui to call methods on the
* controller.
*/
public interface OverlayUICallbacksGo extends OverlayUICallbacks {
/** User has requested to listen to the current content read aloud */
void onListen();
/** User has requested a translation of the current content */
void onTranslate();
/** User has requested a visual search of the current content */
void onSearch();
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.quickstep.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.quickstep.TaskOverlayFactoryGo.OverlayUICallbacksGo;
/**
* View for showing Go-specific action buttons in Overview
*/
public final class GoOverviewActionsView extends OverviewActionsView<OverlayUICallbacksGo> {
public GoOverviewActionsView(Context context) {
this(context, null);
}
public GoOverviewActionsView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public GoOverviewActionsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getResources().getBoolean(R.bool.enable_niu_actions)) {
findViewById(R.id.action_listen).setOnClickListener(this);
findViewById(R.id.action_translate).setOnClickListener(this);
findViewById(R.id.action_search).setOnClickListener(this);
} else {
findViewById(R.id.action_listen).setVisibility(View.GONE);
findViewById(R.id.action_translate).setVisibility(View.GONE);
findViewById(R.id.action_search).setVisibility(View.GONE);
}
}
@Override
public void onClick(View view) {
super.onClick(view);
if (mCallbacks == null) {
return;
}
int id = view.getId();
if (id == R.id.action_listen) {
mCallbacks.onListen();
} else if (id == R.id.action_translate) {
mCallbacks.onTranslate();
} else if (id == R.id.action_search) {
mCallbacks.onSearch();
}
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="task_overlay_factory_class" translatable="false"/>
</resources>

View File

@ -14,8 +14,6 @@
limitations under the License.
-->
<resources>
<string name="task_overlay_factory_class" translatable="false"/>
<string name="overscroll_plugin_factory_class" translatable="false" />
<!-- Activities which block home gesture -->

View File

@ -64,6 +64,20 @@ public class ImageActionsApi {
*/
@UiThread
public void shareWithExplicitIntent(@Nullable Rect crop, Intent intent) {
addImageAndSendIntent(crop, intent, false);
}
/**
* Share the image this api was constructed with using the provided intent. The implementation
* should set the intent's data field to the URI pointing to the image.
*/
@UiThread
public void shareAsDataWithExplicitIntent(@Nullable Rect crop, Intent intent) {
addImageAndSendIntent(crop, intent, true);
}
@UiThread
private void addImageAndSendIntent(@Nullable Rect crop, Intent intent, boolean setData) {
if (mBitmapSupplier.get() == null) {
Log.e(TAG, "No snapshot available, not starting share.");
return;
@ -71,12 +85,14 @@ public class ImageActionsApi {
UI_HELPER_EXECUTOR.execute(() -> persistBitmapAndStartActivity(mContext,
mBitmapSupplier.get(), crop, intent, (uri, intentForUri) -> {
intentForUri
.addFlags(FLAG_GRANT_READ_URI_PERMISSION)
.putExtra(EXTRA_STREAM, uri);
intentForUri.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
if (setData) {
intentForUri.setData(uri);
} else {
intentForUri.putExtra(EXTRA_STREAM, uri);
}
return new Intent[]{intentForUri};
}, TAG));
}
/**

View File

@ -122,12 +122,11 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
*/
public static class TaskOverlay<T extends OverviewActionsView> {
private final Context mApplicationContext;
protected final Context mApplicationContext;
protected final TaskThumbnailView mThumbnailView;
private T mActionsView;
private ImageActionsApi mImageApi;
private boolean mIsAllowedByPolicy;
protected ImageActionsApi mImageApi;
protected TaskOverlay(TaskThumbnailView taskThumbnailView) {
mApplicationContext = taskThumbnailView.getContext().getApplicationContext();
@ -153,24 +152,8 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
if (thumbnail != null) {
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
final boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
getActionsView().setCallbacks(new OverlayUICallbacks() {
@Override
public void onShare() {
if (isAllowedByPolicy) {
endLiveTileMode(() -> mImageApi.startShareActivity(null));
} else {
showBlockedByPolicyMessage();
}
}
@SuppressLint("NewApi")
@Override
public void onScreenshot() {
endLiveTileMode(() -> saveScreenshot(task));
}
});
boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
getActionsView().setCallbacks(new OverlayUICallbacksImpl(isAllowedByPolicy, task));
}
}
@ -193,7 +176,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
* Called to save screenshot of the task thumbnail.
*/
@SuppressLint("NewApi")
private void saveScreenshot(Task task) {
protected void saveScreenshot(Task task) {
if (mThumbnailView.isRealSnapshot()) {
mImageApi.saveScreenshot(mThumbnailView.getThumbnail(),
getTaskSnapshotBounds(), getTaskSnapshotInsets(), task.key);
@ -251,7 +234,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
return mThumbnailView.getScaledInsets();
}
private void showBlockedByPolicyMessage() {
protected void showBlockedByPolicyMessage() {
Toast.makeText(
mThumbnailView.getContext(),
R.string.blocked_by_policy,
@ -273,6 +256,29 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
dismissTaskMenuView(mActivity);
}
}
protected class OverlayUICallbacksImpl implements OverlayUICallbacks {
protected final boolean mIsAllowedByPolicy;
protected final Task mTask;
public OverlayUICallbacksImpl(boolean isAllowedByPolicy, Task task) {
mIsAllowedByPolicy = isAllowedByPolicy;
mTask = task;
}
public void onShare() {
if (mIsAllowedByPolicy) {
endLiveTileMode(() -> mImageApi.startShareActivity(null));
} else {
showBlockedByPolicyMessage();
}
}
@SuppressLint("NewApi")
public void onScreenshot() {
endLiveTileMode(() -> saveScreenshot(mTask));
}
}
}
/**