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
This commit is contained in:
Miranda Kephart
2021-06-01 21:09:52 +00:00
parent 894c5d3d73
commit e9169bd526
2 changed files with 34 additions and 23 deletions

View File

@@ -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<Uri> 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());
}
});
});

View File

@@ -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);
}