diff --git a/packages/SystemUI/res/drawable/action_chip_background.xml b/packages/SystemUI/res/drawable/action_chip_background.xml
new file mode 100644
index 0000000000000..fc3dfeb9c1fd5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/action_chip_background.xml
@@ -0,0 +1,27 @@
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/action_chip_container_background.xml b/packages/SystemUI/res/drawable/action_chip_container_background.xml
new file mode 100644
index 0000000000000..095213e38e92d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/action_chip_container_background.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 59952e09555fd..6ac9da4291c6b 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -39,4 +39,13 @@
android:layout_height="match_parent"
android:visibility="gone"
android:pointerIcon="crosshair"/>
+
diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
new file mode 100644
index 0000000000000..6b424002d7fff
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
@@ -0,0 +1,25 @@
+
+
+
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 0febc8ed42621..9a66e8bc87917 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -78,6 +78,11 @@
@color/GM2_red_300
+
+ @color/GM2_grey_900
+ #42FFFFFF
+ @color/GM2_blue_300
+
#ff888888
#ff80cbc4
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bda1c52f27c0d..92c74770a3c4b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -180,6 +180,11 @@
#ffffffff
+
+ #F5F5F5
+ #1f000000
+ @color/GM2_blue_500
+
#F8F9FA
#F1F3F4
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 64b2892efc9a7..f7b92b564dac1 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -285,8 +285,18 @@
3dp
+
+
20dp
+ 10dp
+ 20dp
+
+ 20dp
+ 10dp
+ 10dp
+ 15dp
+
70dp
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 66cd91996cea4..fedd855a858e1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -19,6 +19,7 @@ package com.android.systemui.screenshot;
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
+import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_CORNER_FLOW;
@@ -69,6 +70,8 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
@@ -89,7 +92,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
-import java.util.function.Function;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -110,7 +112,7 @@ public class GlobalScreenshot {
public Bitmap image;
public Uri imageUri;
public Consumer finisher;
- public Function onEditReady;
+ public GlobalScreenshot.ActionsReadyListener mActionsReadyListener;
public int iconSize;
public int previewWidth;
public int previewheight;
@@ -127,6 +129,10 @@ public class GlobalScreenshot {
}
}
+ abstract static class ActionsReadyListener {
+ abstract void onActionsReady(PendingIntent shareAction, PendingIntent editAction);
+ }
+
// These strings are used for communicating the action invoked to
// ScreenshotNotificationSmartActionsProvider.
static final String EXTRA_ACTION_TYPE = "android:screenshot_action_type";
@@ -175,6 +181,10 @@ public class GlobalScreenshot {
private ImageView mBackgroundView;
private ImageView mScreenshotView;
private ImageView mScreenshotFlash;
+ private LinearLayout mActionsView;
+ private TextView mShareAction;
+ private TextView mEditAction;
+ private TextView mScrollAction;
private AnimatorSet mScreenshotAnimation;
@@ -211,17 +221,31 @@ public class GlobalScreenshot {
mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
mBackgroundView = mScreenshotLayout.findViewById(R.id.global_screenshot_background);
mScreenshotView = mScreenshotLayout.findViewById(R.id.global_screenshot);
+ mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
+
+ mShareAction = (TextView) layoutInflater.inflate(
+ R.layout.global_screenshot_action_chip, mActionsView, false);
+ mEditAction = (TextView) layoutInflater.inflate(
+ R.layout.global_screenshot_action_chip, mActionsView, false);
+ mScrollAction = (TextView) layoutInflater.inflate(
+ R.layout.global_screenshot_action_chip, mActionsView, false);
+
+ mShareAction.setText(com.android.internal.R.string.share);
+ mEditAction.setText(com.android.internal.R.string.screenshot_edit);
+ mScrollAction.setText("Scroll"); // TODO (mkephart): Add to resources and translate
+
+ mActionsView.addView(mShareAction);
+ mActionsView.addView(mEditAction);
+ mActionsView.addView(mScrollAction);
+
mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
mScreenshotLayout.setFocusable(true);
mScreenshotSelectorView.setFocusable(true);
mScreenshotSelectorView.setFocusableInTouchMode(true);
- mScreenshotLayout.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // Intercept and ignore all touch events
- return true;
- }
+ mScreenshotLayout.setOnTouchListener((v, event) -> {
+ // Intercept and ignore all touch events
+ return true;
});
// Setup the window that we are going to use
@@ -271,13 +295,13 @@ public class GlobalScreenshot {
* Creates a new worker thread and saves the screenshot to the media store.
*/
private void saveScreenshotInWorkerThread(
- Consumer finisher, @Nullable Function onEditReady) {
+ Consumer finisher, @Nullable ActionsReadyListener actionsReadyListener) {
SaveImageInBackgroundData data = new SaveImageInBackgroundData();
data.context = mContext;
data.image = mScreenBitmap;
data.iconSize = mNotificationIconSize;
data.finisher = finisher;
- data.onEditReady = onEditReady;
+ data.mActionsReadyListener = actionsReadyListener;
data.previewWidth = mPreviewWidth;
data.previewheight = mPreviewHeight;
if (mSaveInBgTask != null) {
@@ -395,6 +419,7 @@ public class GlobalScreenshot {
// Clear any references to the bitmap
mScreenBitmap = null;
mScreenshotView.setImageBitmap(null);
+ mActionsView.setVisibility(View.GONE);
mBackgroundView.setVisibility(View.GONE);
mScreenshotView.setVisibility(View.GONE);
mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
@@ -441,24 +466,13 @@ public class GlobalScreenshot {
saveScreenshotInWorkerThread(finisher);
clearScreenshot();
} else {
- mScreenshotView.requestFocus();
- mScreenshotView.setOnClickListener((v) -> {
- // TODO: remove once we have a better UI to show that we aren't ready yet
- Toast notReadyToast = Toast.makeText(
- mContext, "Screenshot is not ready yet", Toast.LENGTH_SHORT);
- notReadyToast.show();
- });
- saveScreenshotInWorkerThread(finisher, intent -> {
- mScreenshotHandler.post(() -> mScreenshotView.setOnClickListener(v -> {
- try {
- intent.send();
- clearScreenshot();
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Edit intent cancelled", e);
- }
- mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
- }));
- return null;
+ saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
+ @Override
+ void onActionsReady(PendingIntent shareAction, PendingIntent editAction) {
+ mScreenshotHandler.post(() ->
+ createScreenshotActionsShadeAnimation(shareAction, editAction)
+ .start());
+ }
});
mScreenshotHandler.sendMessageDelayed(
mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT),
@@ -664,6 +678,49 @@ public class GlobalScreenshot {
return anim;
}
+ private ValueAnimator createScreenshotActionsShadeAnimation(
+ PendingIntent shareAction, PendingIntent editAction) {
+ ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+ mActionsView.setY(mDisplayMetrics.heightPixels);
+ mActionsView.setVisibility(VISIBLE);
+ mActionsView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ float actionsViewHeight = mActionsView.getMeasuredHeight();
+ float screenshotStartHeight = mScreenshotView.getTranslationY();
+
+ animator.addUpdateListener(animation -> {
+ float t = animation.getAnimatedFraction();
+ mScreenshotView.setTranslationY(screenshotStartHeight - actionsViewHeight * t);
+ mActionsView.setY(mDisplayMetrics.heightPixels - actionsViewHeight * t);
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mScreenshotView.requestFocus();
+ mShareAction.setOnClickListener(v -> {
+ try {
+ shareAction.send();
+ clearScreenshot();
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Share intent cancelled", e);
+ }
+ });
+ mEditAction.setOnClickListener(v -> {
+ try {
+ editAction.send();
+ clearScreenshot();
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Edit intent cancelled", e);
+ }
+ });
+ Toast scrollNotImplemented = Toast.makeText(
+ mContext, "Not implemented", Toast.LENGTH_SHORT);
+ mScrollAction.setOnClickListener(v -> scrollNotImplemented.show());
+ }
+ });
+ return animator;
+ }
+
static void notifyScreenshotError(Context context, NotificationManager nManager, int msgResId) {
Resources r = context.getResources();
String errorMsg = r.getString(msgResId);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 5e5cf743b4685..d2268e12c6620 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -434,8 +434,8 @@ class SaveImageInBackgroundTask extends AsyncTask {
R.drawable.ic_screenshot_edit,
r.getString(com.android.internal.R.string.screenshot_edit), editAction);
notificationBuilder.addAction(editActionBuilder.build());
- if (editAction != null && mParams.onEditReady != null) {
- mParams.onEditReady.apply(editAction);
+ if (mParams.mActionsReadyListener != null) {
+ mParams.mActionsReadyListener.onActionsReady(shareAction, editAction);
}
// Create a delete action for the notification
@@ -472,7 +472,7 @@ class SaveImageInBackgroundTask extends AsyncTask {
GlobalScreenshot.notifyScreenshotError(mParams.context, mNotificationManager,
mParams.errorMsgResId);
} else {
- if (mParams.onEditReady != null) {
+ if (mParams.mActionsReadyListener != null) {
// Cancel the "saving screenshot" notification
mNotificationManager.cancel(
SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
index 3f32c66b2d037..6d85d37537ea4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -175,7 +175,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
data.image = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
data.iconSize = 10;
data.finisher = null;
- data.onEditReady = null;
+ data.mActionsReadyListener = null;
data.previewWidth = 10;
data.previewheight = 10;
SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, data,