From f9fb7e7b2f994315de3cd976e45e319b4bbf7ade Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 20 May 2020 18:23:49 +0800 Subject: [PATCH] Fix size compat bounds in close-to-square display DisplayContent#ignoreRotationForApps does not mean the display cannot rotate. It means that the display can rotate without considering the orientation requested by application. Currently the case is that the aspect ratio of display is close to square. Originally if the close-to-square display is rotated, an activity with fixed aspect ratio will still use non-rotated bounds that causes unexpected scaling. This change makes the case calculate the bounds by current rotation. Fixes: 156543028 Test: SizeCompatTests#testFixedAspectRatioBoundsWithDecorInSquareDisplay Change-Id: Id22522f9a142806a922f643f4802971df302dadb --- .../java/com/android/server/wm/ActivityRecord.java | 10 ++++------ .../src/com/android/server/wm/SizeCompatTests.java | 13 +++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index b5b82d39b9215..5a6e0a1ff9c30 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -6535,14 +6535,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Configuration resolvedConfig = getResolvedOverrideConfiguration(); final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); final int requestedOrientation = getRequestedConfigurationOrientation(); - final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED; + final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED + && !mDisplayContent.ignoreRotationForApps(); final int orientation = orientationRequested ? requestedOrientation : newParentConfiguration.orientation; int rotation = newParentConfiguration.windowConfiguration.getRotation(); final boolean canChangeOrientation = handlesOrientationChangeFromDescendant(); - if (canChangeOrientation && mCompatDisplayInsets.mIsRotatable - && !mCompatDisplayInsets.mIsFloating) { + if (canChangeOrientation && !mCompatDisplayInsets.mIsFloating) { // Use parent rotation because the original display can rotate by requested orientation. resolvedConfig.windowConfiguration.setRotation(rotation); } else { @@ -7628,7 +7628,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private final int mWidth; private final int mHeight; final boolean mIsFloating; - final boolean mIsRotatable; /** * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It @@ -7645,7 +7644,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Constructs the environment to simulate the bounds behavior of the given container. */ CompatDisplayInsets(DisplayContent display, WindowContainer container) { mIsFloating = container.getWindowConfiguration().tasksAreFloating(); - mIsRotatable = !mIsFloating && !display.ignoreRotationForApps(); if (mIsFloating) { final Rect containerBounds = container.getWindowConfiguration().getBounds(); mWidth = containerBounds.width(); @@ -7702,7 +7700,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } - if (mIsRotatable && canChangeOrientation) { + if (canChangeOrientation) { getBoundsByRotation(outBounds, rotation); if (orientationRequested) { getFrameByOrientation(outAppBounds, orientation); diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index e47792f4920ce..68bc58493f13f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -138,7 +138,7 @@ public class SizeCompatTests extends ActivityTestsBase { // Rotation is ignored so because the display size is close to square (700/600<1.333). assertTrue(mActivity.mDisplayContent.ignoreRotationForApps()); - final Rect displayBounds = mActivity.mDisplayContent.getBounds(); + final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds(); final float aspectRatio = 1.2f; mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = aspectRatio; prepareUnresizable(-1f, SCREEN_ORIENTATION_UNSPECIFIED); @@ -160,13 +160,22 @@ public class SizeCompatTests extends ActivityTestsBase { assertFitted(); // After the orientation of activity is changed, even display is not rotated, the aspect - // ratio should be the same (bounds=[0, 0 - 600, 600], appBounds=[0, 100 - 600, 600]). + // ratio should be the same (appBounds=[9, 100 - 592, 800], x-offset=round((600-583)/2)=9). assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */); // The notch is still on top. assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight); mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); assertFitted(); + + // Close-to-square display can rotate without being restricted by the requested orientation. + // The notch becomes on the left side. The activity is horizontal centered in 100 ~ 800. + // So the bounds and appBounds will be [200, 0 - 700, 600] (500x600) that is still fitted. + // Left = 100 + (800 - 100 - 500) / 2 = 200. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + assertFitted(); + assertEquals(appBounds.left, + notchHeight + (displayBounds.width() - notchHeight - appBounds.width()) / 2); } @Test