diff options
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; |