From a77d7425a41f4fe28a27a2b25ceef80d71df8048 Mon Sep 17 00:00:00 2001 From: Naomi Musgrave Date: Tue, 5 Oct 2021 13:38:18 +0100 Subject: [PATCH] PossibleMaximumWindowMetrics reports physical display insets for each DisplayInfo (current and non-current display) Changes behaviour from dumbly applying the insets of the current DisplayInfo to all other DisplayInfo, to reading the insets of each DisplayInfo into WindowMetrics. Additionally, applies the appropriate rotation to the insets of each DisplayInfo, so the WindowMetrics contain the correctly-rotated insets. Bug: 201546646 Test: Manual Change-Id: I5756a768b7544939d55d5759f838b27278ca1da6 --- core/java/android/view/WindowManagerImpl.java | 35 +++++++++---------- .../com/android/server/wm/DisplayContent.java | 22 +++++++----- .../server/wm/PossibleDisplayInfoMapper.java | 9 ++++- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 7631269d9c1c9..1c915cb016d4e 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -352,25 +352,11 @@ public final class WindowManagerImpl implements WindowManager { throw e.rethrowFromSystemServer(); } - int size = possibleDisplayInfos.size(); - DisplayInfo currentDisplayInfo; - WindowInsets windowInsets = null; - if (size > 0) { - currentDisplayInfo = possibleDisplayInfos.get(0); - - final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); - final boolean isScreenRound = (currentDisplayInfo.flags & Display.FLAG_ROUND) != 0; - // TODO(181127261) not computing insets correctly - need to have underlying - // frame reflect the faked orientation. - windowInsets = getWindowInsetsFromServerForDisplay( - currentDisplayInfo.displayId, params, - new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), - currentDisplayInfo.getNaturalHeight()), isScreenRound, - WINDOWING_MODE_FULLSCREEN); - } - Set maxMetrics = new HashSet<>(); - for (int i = 0; i < size; i++) { + WindowInsets windowInsets; + DisplayInfo currentDisplayInfo; + final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); + for (int i = 0; i < possibleDisplayInfos.size(); i++) { currentDisplayInfo = possibleDisplayInfos.get(i); // Calculate max bounds for this rotation and state. @@ -378,7 +364,18 @@ public final class WindowManagerImpl implements WindowManager { currentDisplayInfo.logicalHeight); // Calculate insets for the rotated max bounds. - // TODO(181127261) calculate insets for each display rotation and state. + final boolean isScreenRound = (currentDisplayInfo.flags & Display.FLAG_ROUND) != 0; + // Initialize insets based upon display rotation. Note any window-provided insets + // will not be set. + windowInsets = getWindowInsetsFromServerForDisplay( + currentDisplayInfo.displayId, params, + new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), + currentDisplayInfo.getNaturalHeight()), isScreenRound, + WINDOWING_MODE_FULLSCREEN); + // Set the hardware-provided insets. + windowInsets = new WindowInsets.Builder(windowInsets).setRoundedCorners( + currentDisplayInfo.roundedCorners) + .setDisplayCutout(currentDisplayInfo.displayCutout).build(); maxMetrics.add(new WindowMetrics(maxBounds, windowInsets)); } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e14d30bf84477..aaca58ef4ac00 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -588,7 +588,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** Caches the value whether told display manager that we have content. */ private boolean mLastHasContent; - private DisplayRotationUtil mRotationUtil = new DisplayRotationUtil(); + private static DisplayRotationUtil sRotationUtil = new DisplayRotationUtil(); /** * The input method window for this display. @@ -2053,29 +2053,35 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mDisplayCutoutCache.getOrCompute(mInitialDisplayCutout, rotation); } - private WmDisplayCutout calculateDisplayCutoutForRotationUncached( - DisplayCutout cutout, int rotation) { + static WmDisplayCutout calculateDisplayCutoutForRotationAndDisplaySizeUncached( + DisplayCutout cutout, int rotation, int displayWidth, int displayHeight) { if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) { return WmDisplayCutout.NO_CUTOUT; } if (rotation == ROTATION_0) { return WmDisplayCutout.computeSafeInsets( - cutout, mInitialDisplayWidth, mInitialDisplayHeight); + cutout, displayWidth, displayHeight); } final Insets waterfallInsets = RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation); final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); - final Rect[] newBounds = mRotationUtil.getRotatedBounds( + final Rect[] newBounds = sRotationUtil.getRotatedBounds( cutout.getBoundingRectsAll(), - rotation, mInitialDisplayWidth, mInitialDisplayHeight); + rotation, displayWidth, displayHeight); final CutoutPathParserInfo info = cutout.getCutoutPathParserInfo(); final CutoutPathParserInfo newInfo = new CutoutPathParserInfo( info.getDisplayWidth(), info.getDisplayHeight(), info.getDensity(), info.getCutoutSpec(), rotation, info.getScale()); return WmDisplayCutout.computeSafeInsets( DisplayCutout.constructDisplayCutout(newBounds, waterfallInsets, newInfo), - rotated ? mInitialDisplayHeight : mInitialDisplayWidth, - rotated ? mInitialDisplayWidth : mInitialDisplayHeight); + rotated ? displayHeight : displayWidth, + rotated ? displayWidth : displayHeight); + } + + private WmDisplayCutout calculateDisplayCutoutForRotationUncached( + DisplayCutout cutout, int rotation) { + return calculateDisplayCutoutForRotationAndDisplaySizeUncached(cutout, rotation, + mInitialDisplayWidth, mInitialDisplayHeight); } RoundedCorners calculateRoundedCornersForRotation(int rotation) { diff --git a/services/core/java/com/android/server/wm/PossibleDisplayInfoMapper.java b/services/core/java/com/android/server/wm/PossibleDisplayInfoMapper.java index ef8dee401b050..11a27c593d9ee 100644 --- a/services/core/java/com/android/server/wm/PossibleDisplayInfoMapper.java +++ b/services/core/java/com/android/server/wm/PossibleDisplayInfoMapper.java @@ -120,8 +120,15 @@ public class PossibleDisplayInfoMapper { @Surface.Rotation int rotation) { DisplayInfo updatedDisplayInfo = new DisplayInfo(); updatedDisplayInfo.copyFrom(displayInfo); - updatedDisplayInfo.rotation = rotation; + // Apply rotations before updating width and height + updatedDisplayInfo.roundedCorners = updatedDisplayInfo.roundedCorners.rotate(rotation, + updatedDisplayInfo.logicalWidth, updatedDisplayInfo.logicalHeight); + updatedDisplayInfo.displayCutout = + DisplayContent.calculateDisplayCutoutForRotationAndDisplaySizeUncached( + updatedDisplayInfo.displayCutout, rotation, updatedDisplayInfo.logicalWidth, + updatedDisplayInfo.logicalHeight).getDisplayCutout(); + updatedDisplayInfo.rotation = rotation; final int naturalWidth = updatedDisplayInfo.getNaturalWidth(); final int naturalHeight = updatedDisplayInfo.getNaturalHeight(); updatedDisplayInfo.logicalWidth = naturalWidth;