From e9169bd526bd51f8c280355368f0dc4cc07be9a6 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Tue, 1 Jun 2021 21:09:52 +0000 Subject: [PATCH] Fix handling of display cutout Add margins around the static screenshot layout. We want the preview/buttons/etc to respect display cutouts (so they aren't covered), but the flash and the background scrim to display across the entire screen. This change adds bounding margins and updates their location when the orientation changes (since we want to move "up/down" in portrait and "left/right" in landscape). This also allows us to handle waterfall cutouts correctly. Bug: 189853509 Fix: 189853509 Test: manual -- used developer settings to test possible cutouts in portrait and landscape Change-Id: Id12012bb3d4dacb948cecd819999e0c7d46bb37b --- .../screenshot/ScreenshotController.java | 26 ++++------------ .../systemui/screenshot/ScreenshotView.java | 31 +++++++++++++++++-- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index eaa6659790fa6..2011c0d3458c6 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -16,7 +16,6 @@ package com.android.systemui.screenshot; -import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; @@ -289,6 +288,7 @@ public class ScreenshotController { mWindowLayoutParams.setTitle("ScreenshotAnimation"); mWindowLayoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + mWindowLayoutParams.setFitInsetsTypes(0); // This is needed to let touches pass through outside the touchable areas mWindowLayoutParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; @@ -402,11 +402,6 @@ public class ScreenshotController { Log.d(TAG, "reloadAssets()"); } - // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait - int orientation = mContext.getResources().getConfiguration().orientation; - mWindowLayoutParams.setFitInsetsTypes( - orientation == ORIENTATION_PORTRAIT ? 0 : WindowInsets.Type.displayCutout()); - // Inflate the screenshot layout mScreenshotView = (ScreenshotView) LayoutInflater.from(mContext).inflate(R.layout.global_screenshot, null); @@ -494,17 +489,6 @@ public class ScreenshotController { saveScreenshot(screenshot, finisher, screenRect, Insets.NONE, true); } - private void updateDisplayCutout() { - // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait - int orientation = mContext.getResources().getConfiguration().orientation; - mWindowLayoutParams.setFitInsetsTypes( - orientation == ORIENTATION_PORTRAIT ? 0 : WindowInsets.Type.displayCutout()); - final View decorView = mWindow.peekDecorView(); - if (decorView != null && decorView.isAttachedToWindow()) { - mWindowManager.updateViewLayout(decorView, mWindowLayoutParams); - } - } - private void saveScreenshot(Bitmap screenshot, Consumer finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { if (mAccessibilityManager.isEnabled()) { @@ -528,8 +512,8 @@ public class ScreenshotController { mScreenshotView.reset(); } - int orientation = mContext.getResources().getConfiguration().orientation; - mScreenshotView.updateOrientation(orientation == ORIENTATION_PORTRAIT); + mScreenshotView.updateOrientation(mWindowManager.getCurrentWindowMetrics() + .getWindowInsets().getDisplayCutout()); mScreenBitmap = screenshot; @@ -563,7 +547,9 @@ public class ScreenshotController { // Delay scroll capture eval a bit to allow the underlying activity // to set up in the new orientation. mScreenshotHandler.postDelayed(this::requestScrollCapture, 150); - updateDisplayCutout(); + mScreenshotView.updateDisplayCutoutMargins( + mWindowManager.getCurrentWindowMetrics().getWindowInsets() + .getDisplayCutout()); } }); }); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 77e1d154f3ac6..a98c79275e0e3 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -54,6 +54,7 @@ import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.util.MathUtils; +import android.view.DisplayCutout; import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -348,12 +349,35 @@ public class ScreenshotView extends FrameLayout implements mScreenshotPreview.setImageDrawable(createScreenDrawable(mResources, bitmap, screenInsets)); } - void updateOrientation(boolean portrait) { - mOrientationPortrait = portrait; + void updateDisplayCutoutMargins(DisplayCutout cutout) { + int orientation = mContext.getResources().getConfiguration().orientation; + mOrientationPortrait = (orientation == ORIENTATION_PORTRAIT); + FrameLayout.LayoutParams p = + (FrameLayout.LayoutParams) mScreenshotStatic.getLayoutParams(); + if (cutout == null) { + p.setMargins(0, 0, 0, 0); + } else { + Insets waterfall = cutout.getWaterfallInsets(); + if (mOrientationPortrait) { + p.setMargins(waterfall.left, Math.max(cutout.getSafeInsetTop(), waterfall.top), + waterfall.right, Math.max(cutout.getSafeInsetBottom(), waterfall.bottom)); + } else { + p.setMargins(Math.max(cutout.getSafeInsetLeft(), waterfall.left), waterfall.top, + Math.max(cutout.getSafeInsetRight(), waterfall.right), waterfall.bottom); + } + } + mScreenshotStatic.setLayoutParams(p); + mScreenshotStatic.requestLayout(); + } + + void updateOrientation(DisplayCutout cutout) { + int orientation = mContext.getResources().getConfiguration().orientation; + mOrientationPortrait = (orientation == ORIENTATION_PORTRAIT); + updateDisplayCutoutMargins(cutout); int screenshotFixedSize = mContext.getResources().getDimensionPixelSize(R.dimen.global_screenshot_x_scale); ViewGroup.LayoutParams params = mScreenshotPreview.getLayoutParams(); - if (portrait) { + if (mOrientationPortrait) { params.width = screenshotFixedSize; params.height = LayoutParams.WRAP_CONTENT; mScreenshotPreview.setScaleType(ImageView.ScaleType.FIT_START); @@ -362,6 +386,7 @@ public class ScreenshotView extends FrameLayout implements params.height = screenshotFixedSize; mScreenshotPreview.setScaleType(ImageView.ScaleType.FIT_END); } + mScreenshotPreview.setLayoutParams(params); }