Merge changes I4cbf9376,Ief2111ec into sc-dev am: dec5d61e3a am: 89e4a33931
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15096008
Change-Id: I7e58fa8a3f20db68b2840265ed0b3baa8a088b8d
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 93bd581..c92b10c 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -19,12 +19,15 @@
android:id="@+id/global_screenshot_frame"
android:theme="@style/Screenshot"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:importantForAccessibility="no">
<ImageView
android:id="@+id/screenshot_scrolling_scrim"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="gone"/>
+ android:visibility="gone"
+ android:clickable="true"
+ android:importantForAccessibility="no"/>
<ImageView
android:id="@+id/global_screenshot_actions_background"
android:layout_height="@dimen/screenshot_bg_protection_height"
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 2e13836..24cca91 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -486,9 +486,24 @@
private void takeScreenshotInternal(Consumer<Uri> finisher, Rect crop) {
// copy the input Rect, since SurfaceControl.screenshot can mutate it
Rect screenRect = new Rect(crop);
+ Bitmap screenshot = captureScreenshot(crop);
+
+ if (screenshot == null) {
+ Log.e(TAG, "takeScreenshotInternal: Screenshot bitmap was null");
+ mNotificationsController.notifyScreenshotError(
+ R.string.screenshot_failed_to_capture_text);
+ if (mCurrentRequestCallback != null) {
+ mCurrentRequestCallback.reportError();
+ }
+ return;
+ }
+
+ saveScreenshot(screenshot, finisher, screenRect, Insets.NONE, true);
+ }
+
+ private Bitmap captureScreenshot(Rect crop) {
int width = crop.width();
int height = crop.height();
-
Bitmap screenshot = null;
final Display display = getDefaultDisplay();
final DisplayAddress address = display.getAddress();
@@ -509,18 +524,7 @@
SurfaceControl.captureDisplay(captureArgs);
screenshot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
}
-
- if (screenshot == null) {
- Log.e(TAG, "takeScreenshotInternal: Screenshot bitmap was null");
- mNotificationsController.notifyScreenshotError(
- R.string.screenshot_failed_to_capture_text);
- if (mCurrentRequestCallback != null) {
- mCurrentRequestCallback.reportError();
- }
- return;
- }
-
- saveScreenshot(screenshot, finisher, screenRect, Insets.NONE, true);
+ return screenshot;
}
private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect,
@@ -644,45 +648,56 @@
final ScrollCaptureResponse response = mLastScrollCaptureResponse;
mScreenshotView.showScrollChip(/* onClick */ () -> {
- mScreenshotView.prepareScrollingTransition(response, mScreenBitmap);
- // Clear the reference to prevent close() in dismissScreenshot
- mLastScrollCaptureResponse = null;
- final ListenableFuture<ScrollCaptureController.LongScreenshot> future =
- mScrollCaptureController.run(response);
- future.addListener(() -> {
- ScrollCaptureController.LongScreenshot longScreenshot;
- try {
- longScreenshot = future.get();
- } catch (CancellationException | InterruptedException | ExecutionException e) {
- Log.e(TAG, "Exception", e);
- return;
- }
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ getDefaultDisplay().getRealMetrics(displayMetrics);
+ Bitmap newScreenshot = captureScreenshot(
+ new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels));
- mLongScreenshotHolder.setLongScreenshot(longScreenshot);
- mLongScreenshotHolder.setTransitionDestinationCallback(
- (transitionDestination, onTransitionEnd) ->
- mScreenshotView.startLongScreenshotTransition(
- transitionDestination, onTransitionEnd,
- longScreenshot));
+ mScreenshotView.prepareScrollingTransition(response, mScreenBitmap, newScreenshot);
+ // delay starting scroll capture to make sure the scrim is up before the app moves
+ mScreenshotView.post(() -> {
+ // Clear the reference to prevent close() in dismissScreenshot
+ mLastScrollCaptureResponse = null;
+ final ListenableFuture<ScrollCaptureController.LongScreenshot> future =
+ mScrollCaptureController.run(response);
+ future.addListener(() -> {
+ ScrollCaptureController.LongScreenshot longScreenshot;
+ try {
+ longScreenshot = future.get();
+ } catch (CancellationException
+ | InterruptedException
+ | ExecutionException e) {
+ Log.e(TAG, "Exception", e);
+ return;
+ }
- final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mLongScreenshotHolder.setLongScreenshot(longScreenshot);
+ mLongScreenshotHolder.setTransitionDestinationCallback(
+ (transitionDestination, onTransitionEnd) ->
+ mScreenshotView.startLongScreenshotTransition(
+ transitionDestination, onTransitionEnd,
+ longScreenshot));
- Pair<ActivityOptions, ExitTransitionCoordinator> transition =
- ActivityOptions.startSharedElementAnimation(mWindow,
- new ScreenshotExitTransitionCallbacksSupplier(false).get(),
- null);
- transition.second.startExit();
- mContext.startActivity(intent, transition.first.toBundle());
- RemoteAnimationAdapter runner = new RemoteAnimationAdapter(
- SCREENSHOT_REMOTE_RUNNER, 0, 0);
- try {
- WindowManagerGlobal.getWindowManagerService()
- .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY);
- } catch (Exception e) {
- Log.e(TAG, "Error overriding screenshot app transition", e);
- }
- }, mMainExecutor);
+ final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+ Pair<ActivityOptions, ExitTransitionCoordinator> transition =
+ ActivityOptions.startSharedElementAnimation(mWindow,
+ new ScreenshotExitTransitionCallbacksSupplier(false).get(),
+ null);
+ transition.second.startExit();
+ mContext.startActivity(intent, transition.first.toBundle());
+ RemoteAnimationAdapter runner = new RemoteAnimationAdapter(
+ SCREENSHOT_REMOTE_RUNNER, 0, 0);
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY);
+ } catch (Exception e) {
+ Log.e(TAG, "Error overriding screenshot app transition", e);
+ }
+ }, mMainExecutor);
+ });
});
} catch (CancellationException e) {
// Ignore
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 3c830cc..9fe8c84 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -36,8 +36,10 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.BlendMode;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Matrix;
@@ -257,10 +259,10 @@
@Override // ViewTreeObserver.OnComputeInternalInsetsListener
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- inoutInfo.touchableRegion.set(getTouchRegion());
+ inoutInfo.touchableRegion.set(getTouchRegion(true));
}
- private Region getTouchRegion() {
+ private Region getTouchRegion(boolean includeScrim) {
Region touchRegion = new Region();
final Rect tmpRect = new Rect();
@@ -273,6 +275,11 @@
mDismissButton.getBoundsOnScreen(tmpRect);
touchRegion.op(tmpRect, Region.Op.UNION);
+ if (includeScrim && mScrollingScrim.getVisibility() == View.VISIBLE) {
+ mScrollingScrim.getBoundsOnScreen(tmpRect);
+ touchRegion.op(tmpRect, Region.Op.UNION);
+ }
+
if (QuickStepContract.isGesturalMode(mNavMode)) {
final WindowManager wm = mContext.getSystemService(WindowManager.class);
final WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
@@ -296,7 +303,7 @@
if (ev instanceof MotionEvent) {
MotionEvent event = (MotionEvent) ev;
if (event.getActionMasked() == MotionEvent.ACTION_DOWN
- && !getTouchRegion().contains(
+ && !getTouchRegion(false).contains(
(int) event.getRawX(), (int) event.getRawY())) {
mCallbacks.onTouchOutside();
}
@@ -313,6 +320,10 @@
@Override // ViewGroup
public boolean onInterceptTouchEvent(MotionEvent ev) {
+ // scrolling scrim should not be swipeable; return early if we're on the scrim
+ if (!getTouchRegion(false).contains((int) ev.getRawX(), (int) ev.getRawY())) {
+ return false;
+ }
// always pass through the down event so the swipe handler knows the initial state
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
mSwipeDismissHandler.onTouch(this, ev);
@@ -374,10 +385,6 @@
return mScreenshotPreview;
}
- View getScrollablePreview() {
- return mScrollablePreview;
- }
-
/**
* Set up the logger and callback on dismissal.
*
@@ -807,8 +814,9 @@
anim.start();
}
- void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap) {
- mScrollingScrim.setImageBitmap(screenBitmap);
+ void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap,
+ Bitmap newBitmap) {
+ mScrollingScrim.setImageBitmap(newBitmap);
mScrollingScrim.setVisibility(View.VISIBLE);
Rect scrollableArea = scrollableAreaOnScreen(response);
float scale = mCornerSizeX
@@ -828,7 +836,19 @@
mScrollablePreview.setImageBitmap(screenBitmap);
mScrollablePreview.setVisibility(View.VISIBLE);
- createScreenshotFadeDismissAnimation(true).start();
+ mDismissButton.setVisibility(View.GONE);
+ mActionsContainer.setVisibility(View.GONE);
+ mBackgroundProtection.setVisibility(View.GONE);
+ // set these invisible, but not gone, so that the views are laid out correctly
+ mActionsContainerBackground.setVisibility(View.INVISIBLE);
+ mScreenshotPreviewBorder.setVisibility(View.INVISIBLE);
+ mScreenshotPreview.setVisibility(View.INVISIBLE);
+ mScrollingScrim.setImageTintBlendMode(BlendMode.SRC_ATOP);
+ ValueAnimator anim = ValueAnimator.ofFloat(0, .3f);
+ anim.addUpdateListener(animation -> mScrollingScrim.setImageTintList(
+ ColorStateList.valueOf(Color.argb((float) animation.getAnimatedValue(), 0, 0, 0))));
+ anim.setDuration(200);
+ anim.start();
}
boolean isDismissing() {
@@ -844,10 +864,6 @@
}
private void animateDismissal(Animator dismissAnimation) {
- if (DEBUG_WINDOW) {
- Log.d(TAG, "removing OnComputeInternalInsetsListener");
- }
- getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
mDismissAnimation = dismissAnimation;
mDismissAnimation.addListener(new AnimatorListenerAdapter() {
private boolean mCancelled = false;
@@ -909,6 +925,7 @@
mContext.getResources().getString(R.string.screenshot_preview_description));
mScreenshotPreview.setOnClickListener(null);
mShareChip.setOnClickListener(null);
+ mScrollingScrim.setVisibility(View.GONE);
mEditChip.setOnClickListener(null);
mShareChip.setIsPending(false);
mEditChip.setIsPending(false);
@@ -931,7 +948,7 @@
transition.action.actionIntent.send();
// fade out non-preview UI
- createScreenshotFadeDismissAnimation(false).start();
+ createScreenshotFadeDismissAnimation().start();
} catch (PendingIntent.CanceledException e) {
mPendingSharedTransition = false;
if (transition.onCancelRunnable != null) {
@@ -969,7 +986,7 @@
return animSet;
}
- ValueAnimator createScreenshotFadeDismissAnimation(boolean fadePreview) {
+ ValueAnimator createScreenshotFadeDismissAnimation() {
ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1);
alphaAnim.addUpdateListener(animation -> {
float alpha = 1 - animation.getAnimatedFraction();
@@ -978,9 +995,6 @@
mActionsContainer.setAlpha(alpha);
mBackgroundProtection.setAlpha(alpha);
mScreenshotPreviewBorder.setAlpha(alpha);
- if (fadePreview) {
- mScreenshotPreview.setAlpha(alpha);
- }
});
alphaAnim.setDuration(600);
return alphaAnim;