diff options
3 files changed, 104 insertions, 68 deletions
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml index 93bd58113bc2..c92b10c447b1 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 2e138362aedb..24cca91ea3f3 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 @@ public class ScreenshotController { 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 @@ public class ScreenshotController { 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 @@ public class ScreenshotController { 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)); + + 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; + } - mLongScreenshotHolder.setLongScreenshot(longScreenshot); - mLongScreenshotHolder.setTransitionDestinationCallback( - (transitionDestination, onTransitionEnd) -> - mScreenshotView.startLongScreenshotTransition( - transitionDestination, onTransitionEnd, - longScreenshot)); - - 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); + mLongScreenshotHolder.setLongScreenshot(longScreenshot); + mLongScreenshotHolder.setTransitionDestinationCallback( + (transitionDestination, onTransitionEnd) -> + mScreenshotView.startLongScreenshotTransition( + transitionDestination, onTransitionEnd, + longScreenshot)); + + 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 669046591170..1426709350d4 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.ActivityManager; 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 @@ public class ScreenshotView extends FrameLayout implements @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 @@ public class ScreenshotView extends FrameLayout implements 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 @@ public class ScreenshotView extends FrameLayout implements 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 @@ public class ScreenshotView extends FrameLayout implements @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 @@ public class ScreenshotView extends FrameLayout implements return mScreenshotPreview; } - View getScrollablePreview() { - return mScrollablePreview; - } - /** * Set up the logger and callback on dismissal. * @@ -808,8 +815,9 @@ public class ScreenshotView extends FrameLayout implements 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 @@ -829,7 +837,19 @@ public class ScreenshotView extends FrameLayout implements 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() { @@ -910,6 +930,7 @@ public class ScreenshotView extends FrameLayout implements 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); @@ -932,7 +953,7 @@ public class ScreenshotView extends FrameLayout implements transition.action.actionIntent.send(); // fade out non-preview UI - createScreenshotFadeDismissAnimation(false).start(); + createScreenshotFadeDismissAnimation().start(); } catch (PendingIntent.CanceledException e) { mPendingSharedTransition = false; if (transition.onCancelRunnable != null) { @@ -970,7 +991,7 @@ public class ScreenshotView extends FrameLayout implements return animSet; } - ValueAnimator createScreenshotFadeDismissAnimation(boolean fadePreview) { + ValueAnimator createScreenshotFadeDismissAnimation() { ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); alphaAnim.addUpdateListener(animation -> { float alpha = 1 - animation.getAnimatedFraction(); @@ -979,9 +1000,6 @@ public class ScreenshotView extends FrameLayout implements mActionsContainer.setAlpha(alpha); mBackgroundProtection.setAlpha(alpha); mScreenshotPreviewBorder.setAlpha(alpha); - if (fadePreview) { - mScreenshotPreview.setAlpha(alpha); - } }); alphaAnim.setDuration(600); return alphaAnim; |