diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 2dad9102110ce..2ebf8d9ee3881 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -8242,8 +8242,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (screenResolvedBounds.width() <= parentAppBounds.width()) { float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier( newParentConfiguration); - offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width()) - * positionMultiplier); + offsetX = Math.max(0, (int) Math.ceil((parentAppBounds.width() + - screenResolvedBounds.width()) * positionMultiplier) + // This is added to make sure that insets added inside + // CompatDisplayInsets#getContainerBounds() do not break the alignment + // provided by the positionMultiplier + - screenResolvedBounds.left + parentAppBounds.left); } } @@ -8253,8 +8257,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (screenResolvedBounds.height() <= parentAppBounds.height()) { float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier( newParentConfiguration); - offsetY = (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height()) - * positionMultiplier); + offsetY = Math.max(0, (int) Math.ceil((parentAppBounds.height() + - screenResolvedBounds.height()) * positionMultiplier) + // This is added to make sure that insets added inside + // CompatDisplayInsets#getContainerBounds() do not break the alignment + // provided by the positionMultiplier + - screenResolvedBounds.top + parentAppBounds.top); } } @@ -10037,6 +10045,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A isLandscape ? shortSide : longSide); } + // TODO(b/267151420): Explore removing getContainerBounds() from CompatDisplayInsets. /** Gets the horizontal centered container bounds for size compatibility mode. */ void getContainerBounds(Rect outAppBounds, Rect outBounds, int rotation, int orientation, boolean orientationRequested, boolean isFixedToUserRotation) { 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 c9ff15093fea0..0bcee92faad28 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -2909,6 +2909,39 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.getLetterboxInsets()); } + @Test + public void testUpdateResolvedBoundsHorizontalPosition_leftInsets_appCentered() { + // Set up folded display + final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1100, 2100) + .setCanRotate(true) + .build(); + display.setIgnoreOrientationRequest(true); + final DisplayPolicy policy = display.getDisplayPolicy(); + DisplayPolicy.DecorInsets.Info decorInfo = policy.getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + decorInfo.mNonDecorInsets.set(130, 0, 60, 0); + spyOn(policy); + doReturn(decorInfo).when(policy).getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f); + + setUpApp(display); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + // Resize the display to simulate unfolding in portrait + resizeDisplay(mTask.mDisplayContent, 2200, 1800); + assertTrue(mActivity.inSizeCompatMode()); + + // Simulate real display not taking non-decor insets into consideration + display.getWindowConfiguration().setAppBounds(0, 0, 2200, 1800); + + // Rotate display to landscape + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // App is centered + assertEquals(mActivity.getBounds(), new Rect(350, 50, 1450, 2150)); + } + @Test public void testUpdateResolvedBoundsHorizontalPosition_left() { // Display configured as (2800, 1400). @@ -3079,6 +3112,39 @@ public class SizeCompatTests extends WindowTestsBase { /* letterboxHorizontalPositionMultiplier */ 1.0f); } + @Test + public void testUpdateResolvedBoundsVerticalPosition_topInsets_appCentered() { + // Set up folded display + final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2100, 1100) + .setCanRotate(true) + .build(); + display.setIgnoreOrientationRequest(true); + final DisplayPolicy policy = display.getDisplayPolicy(); + DisplayPolicy.DecorInsets.Info decorInfo = policy.getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + decorInfo.mNonDecorInsets.set(0, 130, 0, 60); + spyOn(policy); + doReturn(decorInfo).when(policy).getDecorInsetsInfo(ROTATION_90, + display.mBaseDisplayHeight, display.mBaseDisplayWidth); + mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f); + + setUpApp(display); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); + + // Resize the display to simulate unfolding in portrait + resizeDisplay(mTask.mDisplayContent, 1800, 2200); + assertTrue(mActivity.inSizeCompatMode()); + + // Simulate real display not taking non-decor insets into consideration + display.getWindowConfiguration().setAppBounds(0, 0, 1800, 2200); + + // Rotate display to landscape + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // App is centered + assertEquals(mActivity.getBounds(), new Rect(50, 350, 2150, 1450)); + } + @Test public void testUpdateResolvedBoundsVerticalPosition_top() { // Display configured as (1400, 2800).