diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 2b2100e56f443..3b4429846c1e0 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -223,6 +223,7 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.IdentifierProto.USER_ID; +import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW; import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; @@ -8785,9 +8786,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final float letterboxAspectRatioOverride = mLetterboxUiController.getFixedOrientationLetterboxAspectRatio(newParentConfig); - final float desiredAspectRatio = - letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO - ? letterboxAspectRatioOverride : computeAspectRatio(parentBounds); + + // Aspect ratio as suggested by the system. Apps requested mix/max aspect ratio will + // be respected in #applyAspectRatio. + final float desiredAspectRatio; + if (isDefaultMultiWindowLetterboxAspectRatioDesired(newParentConfig)) { + desiredAspectRatio = DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW; + } else if (letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) { + desiredAspectRatio = letterboxAspectRatioOverride; + } else { + desiredAspectRatio = computeAspectRatio(parentBounds); + } + // Apply aspect ratio to resolved bounds mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingBoundsWithInsets, containingBounds, desiredAspectRatio); @@ -8812,6 +8822,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds); } + /** + * Returns {@code true} if the default aspect ratio for a letterboxed app in multi-window mode + * should be used. + */ + private boolean isDefaultMultiWindowLetterboxAspectRatioDesired( + @NonNull Configuration parentConfig) { + if (mDisplayContent == null) { + return false; + } + final int windowingMode = parentConfig.windowConfiguration.getWindowingMode(); + return WindowConfiguration.inMultiWindowMode(windowingMode) + && !mDisplayContent.getIgnoreOrientationRequest(); + } + /** * Resolves aspect ratio restrictions for an activity. If the bounds are restricted by * aspect ratio, the position will be adjusted later in {@link #updateResolvedBoundsPosition diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index a93cb8ad2d974..067a18c88aaa6 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -52,6 +52,9 @@ final class LetterboxConfiguration { */ static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f; + /** The default aspect ratio for a letterboxed app in multi-window mode. */ + static final float DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW = 1.01f; + /** Letterboxed app window position multiplier indicating center position. */ static final float LETTERBOX_POSITION_MULTIPLIER_CENTER = 0.5f; 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 2dd34eb5ac4d7..28fcb12f2bcad 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -2046,6 +2046,72 @@ public class SizeCompatTests extends WindowTestsBase { activityBounds.width()); } + @Test + public void testDefaultLetterboxAspectRatioForMultiWindowMode_fixedOrientationApp() { + // Set-up display in portrait. + mAtm.mDevEnableNonResizableMultiWindow = true; + final int screenWidth = 1100; + final int screenHeight = 2100; + setUpDisplaySizeWithApp(screenWidth, screenHeight); + + mActivity.mDisplayContent.getWindowConfiguration() + .setAppBounds(/* left */ 0, /* top */ 0, screenWidth, screenHeight); + + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + // Move activity to multi-window which takes half of the screen. + mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test"); + organizer.mPrimary.setBounds(0, 0, screenWidth, getExpectedSplitSize(screenHeight)); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode()); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode()); + + // Unresizable portrait-only activity. + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + // Activity should be letterboxed with an aspect ratio of 1.01. + final Rect afterBounds = mActivity.getBounds(); + final float actualAspectRatio = 1f * afterBounds.height() / afterBounds.width(); + assertEquals(LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW, + actualAspectRatio, 0.001f); + assertTrue(mActivity.areBoundsLetterboxed()); + } + + @Test + public void + testDefaultLetterboxAspectRatioForMultiWindowMode_fixedOrientationAppWithMinRatio() { + // Set-up display in portrait. + mAtm.mDevEnableNonResizableMultiWindow = true; + final int screenWidth = 1100; + final int screenHeight = 2100; + setUpDisplaySizeWithApp(screenWidth, screenHeight); + + mActivity.mDisplayContent.getWindowConfiguration() + .setAppBounds(/* left */ 0, /* top */ 0, screenWidth, screenHeight); + + // Set min aspect ratio to value greater than the default letterbox aspect ratio for + // multi-window mode. + final float minAspectRatio = 1.2f; + mActivity.info.setMinAspectRatio(minAspectRatio); + + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + // Move activity to multi-window which takes half of the screen. + mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test"); + organizer.mPrimary.setBounds(0, 0, screenWidth, getExpectedSplitSize(screenHeight)); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode()); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode()); + + // Unresizable portrait-only activity. + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + // Activity should be letterboxed with the min aspect ratio requested by the app NOT the + // default letterbox aspect ratio for multi-window. + final Rect afterBounds = mActivity.getBounds(); + final float actualAspectRatio = 1f * afterBounds.height() / afterBounds.width(); + assertEquals(minAspectRatio, actualAspectRatio, 0.001f); + assertTrue(mActivity.areBoundsLetterboxed()); + } + @Test public void testDisplayIgnoreOrientationRequest_unresizableWithCorrespondingMinAspectRatio() { // Set up a display in landscape and ignoring orientation request.