summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Miranda Kephart <mkephart@google.com> 2020-01-21 21:30:48 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-01-21 21:30:48 +0000
commitcec4ff9940df0bba33aa7d68c66b8ad876fededf (patch)
tree75f1a6d5fcdccf7b834fc226eeb8c047c21e9c03
parent1d8df2ad914682a5938c5d78a9fc937272f01aec (diff)
parent43c0296b5b75ad9ff8b06a9324dfa1e35e07f26e (diff)
Merge "Implement visual spec for screenshots corner flow"
-rw-r--r--packages/SystemUI/res/drawable/action_chip_background.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_arrow_downward.xml25
-rw-r--r--packages/SystemUI/res/drawable/screenshot_actions_background_protection.xml22
-rw-r--r--packages/SystemUI/res/drawable/screenshot_rounded_corners.xml20
-rw-r--r--packages/SystemUI/res/layout/global_screenshot.xml88
-rw-r--r--packages/SystemUI/res/layout/global_screenshot_action_chip.xml1
-rw-r--r--packages/SystemUI/res/values/colors.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml13
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java226
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshotLegacy.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java7
15 files changed, 359 insertions, 166 deletions
diff --git a/packages/SystemUI/res/drawable/action_chip_background.xml b/packages/SystemUI/res/drawable/action_chip_background.xml
index fc3dfeb9c1fd..ac227a604e56 100644
--- a/packages/SystemUI/res/drawable/action_chip_background.xml
+++ b/packages/SystemUI/res/drawable/action_chip_background.xml
@@ -19,7 +19,7 @@
android:color="@color/global_screenshot_button_ripple">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <stroke android:width="1dp" android:color="@color/global_screenshot_button_text"/>
+ <stroke android:width="1dp" android:color="@color/global_screenshot_button_border"/>
<solid android:color="@color/global_screenshot_button_background"/>
<corners android:radius="@dimen/screenshot_button_corner_radius"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/ic_arrow_downward.xml b/packages/SystemUI/res/drawable/ic_arrow_downward.xml
new file mode 100644
index 000000000000..ddd075dd17cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_arrow_downward.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2020 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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"
+ android:fillColor="@android:color/white"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/screenshot_actions_background_protection.xml b/packages/SystemUI/res/drawable/screenshot_actions_background_protection.xml
new file mode 100644
index 000000000000..163015b7b0f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/screenshot_actions_background_protection.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+ <gradient
+ android:angle="90"
+ android:startColor="#1f000000"
+ android:endColor="#00000000"/>
+</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/screenshot_rounded_corners.xml b/packages/SystemUI/res/drawable/screenshot_rounded_corners.xml
new file mode 100644
index 000000000000..fb8e9b7373f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/screenshot_rounded_corners.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+</shape>
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 995cb7d48e60..1f7def2bc956 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -1,51 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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.
--->
+<!--
+ ~ Copyright (C) 2011 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.
+ -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageView android:id="@+id/global_screenshot_background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/global_screenshot_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@android:color/black"
- android:visibility="gone" />
- <ImageView android:id="@+id/global_screenshot"
+ android:visibility="gone"/>
+ <ImageView
+ android:id="@+id/global_screenshot_actions_background"
+ android:layout_height="400dp"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom|center"
+ android:src="@drawable/screenshot_actions_background_protection"
+ android:alpha="0"/>
+ <HorizontalScrollView
+ android:id="@+id/global_screenshot_actions_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center"
+ android:elevation="3dp"
+ android:fillViewport="true"
+ android:layout_marginHorizontal="@dimen/screenshot_action_container_margin_horizontal"
+ android:gravity="center"
+ android:paddingLeft="@dimen/screenshot_action_container_padding_left"
+ android:paddingRight="@dimen/screenshot_action_container_padding_right"
+ android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
+ android:visibility="gone"
+ android:scrollbars="none"
+ android:background="@drawable/action_chip_container_background">
+ <LinearLayout
+ android:id="@+id/global_screenshot_actions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ </HorizontalScrollView>
+ <ImageView
+ android:id="@+id/global_screenshot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:background="@drawable/screenshot_panel"
+ android:elevation="8dp"
android:visibility="gone"
- android:adjustViewBounds="true" />
- <ImageView android:id="@+id/global_screenshot_flash"
+ android:background="@drawable/screenshot_rounded_corners"
+ android:adjustViewBounds="true"/>
+ <ImageView
+ android:id="@+id/global_screenshot_flash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@android:color/white"
- android:visibility="gone" />
+ android:visibility="gone"/>
<com.android.systemui.screenshot.ScreenshotSelectorView
android:id="@+id/global_screenshot_selector"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:pointerIcon="crosshair"/>
- <LinearLayout
- android:id="@+id/global_screenshot_actions"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center"
- android:gravity="center"
- android:paddingVertical="@dimen/screenshot_action_container_padding"
- android:visibility="gone"
- android:background="@drawable/action_chip_container_background"/>
+
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
index 366abaa1366d..79867a16b243 100644
--- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
@@ -36,5 +36,6 @@
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screenshot_action_chip_padding_end"
android:textSize="@dimen/screenshot_action_chip_text_size"
+ android:textStyle="bold"
android:textColor="@color/global_screenshot_button_text"/>
</com.android.systemui.screenshot.ScreenshotActionChip>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index c1424657cf4f..8dd2a8b9d07a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -182,8 +182,10 @@
<!-- Global screenshot actions -->
<color name="global_screenshot_button_background">#F5F5F5</color>
+ <color name="global_screenshot_button_text">#000000</color>
+ <color name="global_screenshot_button_border">@color/GM2_grey_300</color>
<color name="global_screenshot_button_ripple">#1f000000</color>
- <color name="global_screenshot_button_text">@color/GM2_blue_500</color>
+ <color name="global_screenshot_button_icon">@color/GM2_blue_500</color>
<!-- GM2 colors -->
<color name="GM2_grey_50">#F8F9FA</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 53df02588f11..5c722706543e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -295,17 +295,24 @@
<!-- The padding on the global screenshot background image -->
<dimen name="global_screenshot_legacy_bg_padding">20dp</dimen>
<dimen name="global_screenshot_bg_padding">20dp</dimen>
+ <dimen name="global_screenshot_x_scale">80dp</dimen>
+ <dimen name="screenshot_offset_y">48dp</dimen>
+ <dimen name="screenshot_offset_x">16dp</dimen>
+ <dimen name="screenshot_action_container_offset_y">32dp</dimen>
<dimen name="screenshot_action_container_corner_radius">10dp</dimen>
- <dimen name="screenshot_action_container_padding">10dp</dimen>
+ <dimen name="screenshot_action_container_padding_vertical">10dp</dimen>
+ <dimen name="screenshot_action_container_margin_horizontal">8dp</dimen>
+ <dimen name="screenshot_action_container_padding_left">100dp</dimen>
+ <dimen name="screenshot_action_container_padding_right">8dp</dimen>
<!-- Radius of the chip background on global screenshot actions -->
<dimen name="screenshot_button_corner_radius">20dp</dimen>
<dimen name="screenshot_action_chip_margin_horizontal">4dp</dimen>
<dimen name="screenshot_action_chip_padding_vertical">10dp</dimen>
<dimen name="screenshot_action_chip_icon_size">20dp</dimen>
- <dimen name="screenshot_action_chip_padding_start">4dp</dimen>
+ <dimen name="screenshot_action_chip_padding_start">8dp</dimen>
<!-- Padding between icon and text -->
<dimen name="screenshot_action_chip_padding_middle">8dp</dimen>
- <dimen name="screenshot_action_chip_padding_end">12dp</dimen>
+ <dimen name="screenshot_action_chip_padding_end">16dp</dimen>
<dimen name="screenshot_action_chip_text_size">14sp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 27c95552c1d1..50e9a51478ed 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -29,19 +29,21 @@ import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Color;
+import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.Region;
+import android.graphics.drawable.Icon;
import android.media.MediaActionSound;
import android.net.Uri;
import android.os.AsyncTask;
@@ -49,6 +51,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.DisplayMetrics;
@@ -60,8 +63,11 @@ import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.Interpolator;
+import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
@@ -87,7 +93,7 @@ import dagger.Lazy;
* Class for handling device screen shots
*/
@Singleton
-public class GlobalScreenshot {
+public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInsetsListener {
/**
* POD used in the AsyncTask which saves an image in the background.
@@ -98,6 +104,7 @@ public class GlobalScreenshot {
public Consumer<Uri> finisher;
public GlobalScreenshot.ActionsReadyListener mActionsReadyListener;
public int errorMsgResId;
+ public boolean createDeleteAction;
void clearImage() {
image = null;
@@ -106,7 +113,8 @@ public class GlobalScreenshot {
}
abstract static class ActionsReadyListener {
- abstract void onActionsReady(Uri imageUri, List<Notification.Action> actions);
+ abstract void onActionsReady(Uri imageUri, List<Notification.Action> smartActions,
+ List<Notification.Action> actions);
}
// These strings are used for communicating the action invoked to
@@ -130,38 +138,36 @@ public class GlobalScreenshot {
private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
private static final int SCREENSHOT_DROP_OUT_DURATION = 430;
private static final int SCREENSHOT_DROP_OUT_SCALE_DURATION = 370;
- private static final int SCREENSHOT_FAST_DROP_OUT_DURATION = 320;
private static final float BACKGROUND_ALPHA = 0.5f;
- private static final float SCREENSHOT_SCALE = 1f;
- private static final float SCREENSHOT_DROP_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.725f;
- private static final float SCREENSHOT_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.45f;
- private static final float SCREENSHOT_CORNER_MIN_SCALE = SCREENSHOT_SCALE * 0.2f;
- private static final float SCREENSHOT_FAST_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.6f;
- private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;
- private static final float SCREENSHOT_CORNER_MIN_SCALE_OFFSET = .1f;
+ private static final float SCREENSHOT_DROP_IN_MIN_SCALE = 0.725f;
+ private static final float ROUNDED_CORNER_RADIUS = .05f;
private static final long SCREENSHOT_CORNER_TIMEOUT_MILLIS = 8000;
private static final int MESSAGE_CORNER_TIMEOUT = 2;
private final ScreenshotNotificationsController mNotificationsController;
- private Context mContext;
- private WindowManager mWindowManager;
- private WindowManager.LayoutParams mWindowLayoutParams;
- private Display mDisplay;
- private DisplayMetrics mDisplayMetrics;
+ private final Context mContext;
+ private final WindowManager mWindowManager;
+ private final WindowManager.LayoutParams mWindowLayoutParams;
+ private final Display mDisplay;
+ private final DisplayMetrics mDisplayMetrics;
+
+ private final View mScreenshotLayout;
+ private final ScreenshotSelectorView mScreenshotSelectorView;
+ private final ImageView mBackgroundView;
+ private final ImageView mScreenshotView;
+ private final ImageView mScreenshotFlash;
+ private final HorizontalScrollView mActionsContainer;
+ private final LinearLayout mActionsView;
+ private final ImageView mBackgroundProtection;
private Bitmap mScreenBitmap;
- private View mScreenshotLayout;
- private ScreenshotSelectorView mScreenshotSelectorView;
- private ImageView mBackgroundView;
- private ImageView mScreenshotView;
- private ImageView mScreenshotFlash;
- private LinearLayout mActionsView;
-
private AnimatorSet mScreenshotAnimation;
- private float mBgPadding;
- private float mBgPaddingScale;
+ private float mScreenshotOffsetXPx;
+ private float mScreenshotOffsetYPx;
+ private float mScreenshotHeightPx;
+ private float mCornerScale;
private AsyncTask<Void, Void, Void> mSaveInBgTask;
@@ -172,7 +178,7 @@ public class GlobalScreenshot {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_CORNER_TIMEOUT:
- GlobalScreenshot.this.clearScreenshot();
+ GlobalScreenshot.this.clearScreenshot("timeout");
break;
default:
break;
@@ -194,7 +200,20 @@ 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);
+ mScreenshotView.setClipToOutline(true);
+ mScreenshotView.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
+ ROUNDED_CORNER_RADIUS * view.getWidth());
+ }
+ });
+
+ mActionsContainer = mScreenshotLayout.findViewById(
+ R.id.global_screenshot_actions_container);
mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
+ mBackgroundProtection = mScreenshotLayout.findViewById(
+ R.id.global_screenshot_actions_background);
mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
@@ -202,6 +221,9 @@ public class GlobalScreenshot {
mScreenshotSelectorView.setFocusable(true);
mScreenshotSelectorView.setFocusableInTouchMode(true);
mScreenshotLayout.setOnTouchListener((v, event) -> {
+ if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+ clearScreenshot("tap_outside");
+ }
// Intercept and ignore all touch events
return true;
});
@@ -212,6 +234,8 @@ public class GlobalScreenshot {
WindowManager.LayoutParams.TYPE_SCREENSHOT,
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT);
mWindowLayoutParams.setTitle("ScreenshotAnimation");
@@ -222,16 +246,33 @@ public class GlobalScreenshot {
mDisplayMetrics = new DisplayMetrics();
mDisplay.getRealMetrics(mDisplayMetrics);
- // Scale has to account for both sides of the bg
- mBgPadding = (float) resources.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
- mBgPaddingScale = mBgPadding / mDisplayMetrics.widthPixels;
-
+ mScreenshotOffsetXPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_x);
+ mScreenshotOffsetYPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_y);
+ mScreenshotHeightPx =
+ resources.getDimensionPixelSize(R.dimen.screenshot_action_container_offset_y);
+ mCornerScale = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale)
+ / (float) mDisplayMetrics.widthPixels;
// Setup the Camera shutter sound
mCameraSound = new MediaActionSound();
mCameraSound.load(MediaActionSound.SHUTTER_CLICK);
}
+ @Override // ViewTreeObserver.OnComputeInternalInsetsListener
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
+ inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ Region touchRegion = new Region();
+
+ Rect screenshotRect = new Rect();
+ mScreenshotView.getBoundsOnScreen(screenshotRect);
+ touchRegion.op(screenshotRect, Region.Op.UNION);
+ Rect actionsRect = new Rect();
+ mActionsContainer.getBoundsOnScreen(actionsRect);
+ touchRegion.op(actionsRect, Region.Op.UNION);
+
+ inoutInfo.touchableRegion.set(touchRegion);
+ }
+
/**
* Creates a new worker thread and saves the screenshot to the media store.
*/
@@ -241,6 +282,7 @@ public class GlobalScreenshot {
data.image = mScreenBitmap;
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
+ data.createDeleteAction = false;
if (mSaveInBgTask != null) {
mSaveInBgTask.cancel(false);
}
@@ -252,6 +294,8 @@ public class GlobalScreenshot {
* Takes a screenshot of the current display and shows an animation.
*/
private void takeScreenshot(Consumer<Uri> finisher, Rect crop) {
+ clearScreenshot("new screenshot requested");
+
int rot = mDisplay.getRotation();
int width = crop.width();
int height = crop.height();
@@ -269,6 +313,9 @@ public class GlobalScreenshot {
mScreenBitmap.setHasAlpha(false);
mScreenBitmap.prepareToDraw();
+ mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
+ mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+
// Start the post-screenshot animation
startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);
}
@@ -314,12 +361,9 @@ public class GlobalScreenshot {
return false;
}
});
- mScreenshotLayout.post(new Runnable() {
- @Override
- public void run() {
- mScreenshotSelectorView.setVisibility(View.VISIBLE);
- mScreenshotSelectorView.requestFocus();
- }
+ mScreenshotLayout.post(() -> {
+ mScreenshotSelectorView.setVisibility(View.VISIBLE);
+ mScreenshotSelectorView.requestFocus();
});
}
@@ -337,16 +381,20 @@ public class GlobalScreenshot {
/**
* Clears current screenshot
*/
- private void clearScreenshot() {
+ private void clearScreenshot(String reason) {
+ Log.e(TAG, "clearing screenshot: " + reason);
if (mScreenshotLayout.isAttachedToWindow()) {
mWindowManager.removeView(mScreenshotLayout);
}
+ mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
+ mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
// Clear any references to the bitmap
mScreenBitmap = null;
mScreenshotView.setImageBitmap(null);
- mActionsView.setVisibility(View.GONE);
+ mActionsContainer.setVisibility(View.GONE);
mBackgroundView.setVisibility(View.GONE);
+ mBackgroundProtection.setAlpha(0f);
mScreenshotView.setVisibility(View.GONE);
mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
}
@@ -374,7 +422,6 @@ public class GlobalScreenshot {
mScreenshotAnimation.removeAllListeners();
}
- mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
ValueAnimator screenshotDropInAnim = createScreenshotDropInAnimation();
ValueAnimator screenshotFadeOutAnim = createScreenshotToCornerAnimation(w, h);
mScreenshotAnimation = new AnimatorSet();
@@ -385,16 +432,19 @@ public class GlobalScreenshot {
// Save the screenshot once we have a bit of time now
saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
@Override
- void onActionsReady(Uri uri, List<Notification.Action> actions) {
+ void onActionsReady(Uri uri, List<Notification.Action> smartActions,
+ List<Notification.Action> actions) {
if (uri == null) {
mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_capture_text);
} else {
mScreenshotHandler.post(() ->
- createScreenshotActionsShadeAnimation(actions).start());
+ createScreenshotActionsShadeAnimation(smartActions,
+ actions).start());
}
}
});
+ mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
mScreenshotHandler.sendMessageDelayed(
mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT),
SCREENSHOT_CORNER_TIMEOUT_MILLIS);
@@ -435,14 +485,6 @@ public class GlobalScreenshot {
}
};
- Resources r = mContext.getResources();
- if ((r.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
- == Configuration.UI_MODE_NIGHT_YES) {
- mScreenshotView.getBackground().setTint(Color.BLACK);
- } else {
- mScreenshotView.getBackground().setTintList(null);
- }
-
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(SCREENSHOT_DROP_IN_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@@ -453,8 +495,8 @@ public class GlobalScreenshot {
mScreenshotView.setAlpha(0f);
mScreenshotView.setTranslationX(0f);
mScreenshotView.setTranslationY(0f);
- mScreenshotView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
- mScreenshotView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
+ mScreenshotView.setScaleX(1);
+ mScreenshotView.setScaleY(1);
mScreenshotView.setVisibility(View.VISIBLE);
mScreenshotFlash.setAlpha(0f);
mScreenshotFlash.setVisibility(View.VISIBLE);
@@ -469,9 +511,8 @@ public class GlobalScreenshot {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float t = (Float) animation.getAnimatedValue();
- float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
- - scaleInterpolator.getInterpolation(t)
- * (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
+ float scaleT = 1 - (scaleInterpolator.getInterpolation(t)
+ * (1 - SCREENSHOT_DROP_IN_MIN_SCALE));
mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
mScreenshotView.setAlpha(t);
mScreenshotView.setScaleX(scaleT);
@@ -500,20 +541,19 @@ public class GlobalScreenshot {
};
// Determine the bounds of how to scale
- float halfScreenWidth = (w - 2f * mBgPadding) / 2f;
- float halfScreenHeight = (h - 2f * mBgPadding) / 2f;
- final float offsetPct = SCREENSHOT_CORNER_MIN_SCALE_OFFSET;
+ float halfScreenWidth = w / 2f;
+ float halfScreenHeight = h / 2f;
final PointF finalPos = new PointF(
- -halfScreenWidth + (SCREENSHOT_CORNER_MIN_SCALE + offsetPct) * halfScreenWidth,
- halfScreenHeight - (SCREENSHOT_CORNER_MIN_SCALE + offsetPct) * halfScreenHeight);
+ -halfScreenWidth + mCornerScale * halfScreenWidth + mScreenshotOffsetXPx,
+ halfScreenHeight - mCornerScale * halfScreenHeight - mScreenshotOffsetYPx);
// Animate the screenshot to the bottom left corner
anim.setDuration(SCREENSHOT_DROP_OUT_DURATION);
anim.addUpdateListener(animation -> {
float t = (Float) animation.getAnimatedValue();
- float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
+ float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE)
- scaleInterpolator.getInterpolation(t)
- * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_CORNER_MIN_SCALE);
+ * (SCREENSHOT_DROP_IN_MIN_SCALE - mCornerScale);
mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
mScreenshotView.setScaleX(scaleT);
mScreenshotView.setScaleY(scaleT);
@@ -523,24 +563,48 @@ public class GlobalScreenshot {
return anim;
}
- private ValueAnimator createScreenshotActionsShadeAnimation(List<Notification.Action> actions) {
+ private ValueAnimator createScreenshotActionsShadeAnimation(
+ List<Notification.Action> smartActions, List<Notification.Action> actions) {
LayoutInflater inflater = LayoutInflater.from(mContext);
mActionsView.removeAllViews();
+ mActionsContainer.setScrollX(0);
+ mScreenshotLayout.invalidate();
+ mScreenshotLayout.requestLayout();
+ mScreenshotLayout.getViewTreeObserver().dispatchOnGlobalLayout();
+
+ // By default the activities won't be able to start immediately; override this to keep
+ // the same behavior as if started from a notification
+ try {
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+
+ for (Notification.Action smartAction : smartActions) {
+ ScreenshotActionChip actionChip = (ScreenshotActionChip) inflater.inflate(
+ R.layout.global_screenshot_action_chip, mActionsView, false);
+ actionChip.setText(smartAction.title);
+ actionChip.setIcon(smartAction.getIcon(), false);
+ actionChip.setPendingIntent(smartAction.actionIntent,
+ () -> clearScreenshot("chip tapped"));
+ mActionsView.addView(actionChip);
+ }
for (Notification.Action action : actions) {
ScreenshotActionChip actionChip = (ScreenshotActionChip) inflater.inflate(
R.layout.global_screenshot_action_chip, mActionsView, false);
actionChip.setText(action.title);
actionChip.setIcon(action.getIcon(), true);
- actionChip.setOnClickListener(v -> {
- try {
- action.actionIntent.send();
- clearScreenshot();
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG,
- String.format("Intent cancelled (title: %s)", action.title), e);
- }
- });
+ actionChip.setPendingIntent(action.actionIntent, () -> clearScreenshot("chip tapped"));
+ if (action.actionIntent.getIntent().getAction().equals(Intent.ACTION_EDIT)) {
+ mScreenshotView.setOnClickListener(v -> {
+ try {
+ action.actionIntent.send();
+ clearScreenshot("screenshot preview tapped");
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Intent cancelled", e);
+ }
+ });
+ }
mActionsView.addView(actionChip);
}
@@ -550,27 +614,29 @@ public class GlobalScreenshot {
Toast scrollNotImplemented = Toast.makeText(
mContext, "Not implemented", Toast.LENGTH_SHORT);
scrollChip.setText("Extend"); // TODO (mkephart): add resource and translate
+ scrollChip.setIcon(
+ Icon.createWithResource(mContext, R.drawable.ic_arrow_downward), true);
scrollChip.setOnClickListener(v -> scrollNotImplemented.show());
mActionsView.addView(scrollChip);
}
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();
+ mActionsContainer.setY(mDisplayMetrics.heightPixels);
+ mActionsContainer.setVisibility(VISIBLE);
+ mActionsContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ float actionsViewHeight = mActionsContainer.getMeasuredHeight() + mScreenshotHeightPx;
animator.addUpdateListener(animation -> {
float t = animation.getAnimatedFraction();
- mScreenshotView.setTranslationY(screenshotStartHeight - actionsViewHeight * t);
- mActionsView.setY(mDisplayMetrics.heightPixels - actionsViewHeight * t);
+ mBackgroundProtection.setAlpha(t);
+ mActionsContainer.setY(mDisplayMetrics.heightPixels - actionsViewHeight * t);
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mScreenshotView.requestFocus();
+ mScreenshotView.setElevation(50);
}
});
return animator;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshotLegacy.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshotLegacy.java
index 11aa80bbea35..16447fbdd4aa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshotLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshotLegacy.java
@@ -184,6 +184,7 @@ public class GlobalScreenshotLegacy {
data.image = mScreenBitmap;
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
+ data.createDeleteAction = true;
if (mSaveInBgTask != null) {
mSaveInBgTask.cancel(false);
}
@@ -264,12 +265,9 @@ public class GlobalScreenshotLegacy {
return false;
}
});
- mScreenshotLayout.post(new Runnable() {
- @Override
- public void run() {
- mScreenshotSelectorView.setVisibility(View.VISIBLE);
- mScreenshotSelectorView.requestFocus();
- }
+ mScreenshotLayout.post(() -> {
+ mScreenshotSelectorView.setVisibility(View.VISIBLE);
+ mScreenshotSelectorView.requestFocus();
});
}
@@ -326,8 +324,8 @@ public class GlobalScreenshotLegacy {
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
ValueAnimator screenshotDropInAnim = createScreenshotDropInAnimation();
- ValueAnimator screenshotFadeOutAnim = createScreenshotDropOutAnimation(w, h,
- statusBarVisible, navBarVisible);
+ ValueAnimator screenshotFadeOutAnim =
+ createScreenshotDropOutAnimation(w, h, statusBarVisible, navBarVisible);
mScreenshotAnimation = new AnimatorSet();
mScreenshotAnimation.playSequentially(screenshotDropInAnim, screenshotFadeOutAnim);
mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
@@ -336,13 +334,14 @@ public class GlobalScreenshotLegacy {
// Save the screenshot once we have a bit of time now
saveScreenshotInWorkerThread(finisher, new GlobalScreenshot.ActionsReadyListener() {
@Override
- void onActionsReady(Uri uri, List<Notification.Action> actions) {
+ void onActionsReady(Uri uri, List<Notification.Action> smartActions,
+ List<Notification.Action> actions) {
if (uri == null) {
mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_capture_text);
} else {
- mNotificationsController.showScreenshotActionsNotification(
- uri, actions);
+ mNotificationsController
+ .showScreenshotActionsNotification(uri, smartActions, actions);
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 6bad15caf9da..e6082dddd6c7 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -65,7 +65,6 @@ import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -90,6 +89,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
private final String mScreenshotId;
private final boolean mSmartActionsEnabled;
+ private final boolean mCreateDeleteAction;
private final Random mRandom = new Random();
SaveImageInBackgroundTask(Context context, GlobalScreenshot.SaveImageInBackgroundData data) {
@@ -102,6 +102,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
mScreenshotId = String.format(SCREENSHOT_ID_TEMPLATE, UUID.randomUUID());
+ mCreateDeleteAction = data.createDeleteAction;
+
// Initialize screenshot notification smart actions provider.
mSmartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, false);
@@ -196,8 +198,20 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
}
List<Notification.Action> actions =
- populateNotificationActions(mContext, r, uri, smartActionsFuture);
- mParams.mActionsReadyListener.onActionsReady(uri, actions);
+ populateNotificationActions(mContext, r, uri);
+ List<Notification.Action> smartActions = new ArrayList<>();
+ if (mSmartActionsEnabled) {
+ int timeoutMs = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
+ 1000);
+ smartActions.addAll(buildSmartActions(
+ ScreenshotSmartActions.getSmartActions(
+ mScreenshotId, smartActionsFuture, timeoutMs,
+ mSmartActionsProvider),
+ mContext));
+ }
+ mParams.mActionsReadyListener.onActionsReady(uri, smartActions, actions);
mParams.imageUri = uri;
mParams.image = null;
mParams.errorMsgResId = 0;
@@ -207,7 +221,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
Slog.e(TAG, "unable to save screenshot", e);
mParams.clearImage();
mParams.errorMsgResId = R.string.screenshot_failed_to_save_text;
- mParams.mActionsReadyListener.onActionsReady(null, null);
+ mParams.mActionsReadyListener.onActionsReady(null, null, null);
}
// Recycle the bitmap data
@@ -228,14 +242,13 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
// If we are cancelled while the task is running in the background, we may get null
// params. The finisher is expected to always be called back, so just use the baked-in
// params from the ctor in any case.
- mParams.mActionsReadyListener.onActionsReady(null, null);
+ mParams.mActionsReadyListener.onActionsReady(null, null, null);
mParams.finisher.accept(null);
mParams.clearImage();
}
@VisibleForTesting
- List<Notification.Action> populateNotificationActions(Context context, Resources r, Uri uri,
- CompletableFuture<List<Notification.Action>> smartActionsFuture) {
+ List<Notification.Action> populateNotificationActions(Context context, Resources r, Uri uri) {
// Note: Both the share and edit actions are proxied through ActionProxyReceiver in
// order to do some common work like dismissing the keyguard and sending
// closeSystemWindows
@@ -260,6 +273,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
// by setting the (otherwise unused) request code to the current user id.
int requestCode = context.getUserId();
+ ArrayList<Notification.Action> actions = new ArrayList<>();
+
PendingIntent chooserAction = PendingIntent.getBroadcast(context, requestCode,
new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
@@ -282,6 +297,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
Icon.createWithResource(r, R.drawable.ic_screenshot_share),
r.getString(com.android.internal.R.string.share), shareAction);
+ actions.add(shareActionBuilder.build());
// Create an edit intent, if a specific package is provided as the editor, then
// launch that directly
@@ -309,31 +325,21 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
Icon.createWithResource(r, R.drawable.ic_screenshot_edit),
r.getString(com.android.internal.R.string.screenshot_edit), editAction);
-
- // Create a delete action for the notification
- PendingIntent deleteAction = PendingIntent.getBroadcast(context, requestCode,
- new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
- .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString())
- .putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
- .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED,
- mSmartActionsEnabled),
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
- Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder(
- Icon.createWithResource(r, R.drawable.ic_screenshot_delete),
- r.getString(com.android.internal.R.string.delete), deleteAction);
-
- ArrayList<Notification.Action> actions = new ArrayList<>(
- Arrays.asList(shareActionBuilder.build(), editActionBuilder.build(),
- deleteActionBuilder.build()));
- if (mSmartActionsEnabled) {
- int timeoutMs = DeviceConfig.getInt(
- DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
- 1000);
- actions.addAll(buildSmartActions(
- ScreenshotSmartActions.getSmartActions(
- mScreenshotId, smartActionsFuture, timeoutMs, mSmartActionsProvider),
- context));
+ actions.add(editActionBuilder.build());
+
+ if (mCreateDeleteAction) {
+ // Create a delete action for the notification
+ PendingIntent deleteAction = PendingIntent.getBroadcast(context, requestCode,
+ new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
+ .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString())
+ .putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
+ .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED,
+ mSmartActionsEnabled),
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
+ Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder(
+ Icon.createWithResource(r, R.drawable.ic_screenshot_delete),
+ r.getString(com.android.internal.R.string.delete), deleteAction);
+ actions.add(deleteActionBuilder.build());
}
return actions;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
index 6edacd12a9d1..44b20e535cce 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
@@ -17,9 +17,11 @@
package com.android.systemui.screenshot;
import android.annotation.ColorInt;
+import android.app.PendingIntent;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
+import android.util.Log;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -31,6 +33,8 @@ import com.android.systemui.R;
*/
public class ScreenshotActionChip extends LinearLayout {
+ private static final String TAG = "ScreenshotActionChip";
+
private ImageView mIcon;
private TextView mText;
private @ColorInt int mIconColor;
@@ -47,11 +51,11 @@ public class ScreenshotActionChip extends LinearLayout {
this(context, attrs, defStyleAttr, 0);
}
- public ScreenshotActionChip(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
+ public ScreenshotActionChip(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mIconColor = context.getColor(R.color.global_screenshot_button_text);
+ mIconColor = context.getColor(R.color.global_screenshot_button_icon);
}
@Override
@@ -70,4 +74,15 @@ public class ScreenshotActionChip extends LinearLayout {
void setText(CharSequence text) {
mText.setText(text);
}
+
+ void setPendingIntent(PendingIntent intent, Runnable finisher) {
+ setOnClickListener(v -> {
+ try {
+ intent.send();
+ finisher.run();
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Intent cancelled", e);
+ }
+ });
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
index 42fca9413afd..811a8d936b77 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java
@@ -190,10 +190,14 @@ public class ScreenshotNotificationsController {
*/
public void showScreenshotActionsNotification(
Uri imageUri,
+ List<Notification.Action> smartActions,
List<Notification.Action> actions) {
for (Notification.Action action : actions) {
mNotificationBuilder.addAction(action);
}
+ for (Notification.Action smartAction : smartActions) {
+ mNotificationBuilder.addAction(smartAction);
+ }
// Create the intent to show the screenshot in gallery
Intent launchIntent = new Intent(Intent.ACTION_VIEW);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 4f045d5c1b71..9570b5a3b57c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -107,6 +107,7 @@ public class TakeScreenshotService extends Service {
@Override
public boolean onUnbind(Intent intent) {
if (mScreenshot != null) mScreenshot.stopScreenshot();
+ // TODO (mkephart) remove once notifications flow is fully deprecated
if (mScreenshotLegacy != null) mScreenshotLegacy.stopScreenshot();
return true;
}
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 2c7cee3e2be1..aeb31e11be23 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -169,11 +169,11 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
data.image = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
data.finisher = null;
data.mActionsReadyListener = null;
+ data.createDeleteAction = true;
SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, data);
List<Notification.Action> actions = task.populateNotificationActions(
mContext, mContext.getResources(),
- Uri.parse("Screenshot_123.png"),
- CompletableFuture.completedFuture(Collections.emptyList()));
+ Uri.parse("Screenshot_123.png"));
Assert.assertEquals(actions.size(), 3);
boolean isShareFound = false;
@@ -184,7 +184,8 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
Assert.assertNotNull(intent);
Bundle bundle = intent.getExtras();
Assert.assertTrue(bundle.containsKey(GlobalScreenshot.EXTRA_ID));
- Assert.assertTrue(bundle.containsKey(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED));
+ Assert.assertTrue(
+ bundle.containsKey(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED));
if (action.title.equals(GlobalScreenshot.ACTION_TYPE_DELETE)) {
isDeleteFound = intent.getAction() == null;