From 23b2b2fe420d048241396b36de16c6c09e40d4a3 Mon Sep 17 00:00:00 2001 From: Vali Calinescu Date: Wed, 11 Jan 2023 14:44:14 +0000 Subject: [PATCH] Introduce config to use display aspect ratio for letterbox Bug: 264654821 Test: atest WmTests:SizeCompatTests#testDisplayAspectRatioForResizablePortraitApps Change-Id: If5ef64ac478a705fc334d5f4f81b901ccb0d5ba4 --- core/res/res/values/config.xml | 3 + core/res/res/values/symbols.xml | 1 + .../server/wm/LetterboxConfiguration.java | 34 +++++ .../server/wm/LetterboxUiController.java | 17 ++- .../server/wm/WindowManagerShellCommand.java | 13 +- .../android/server/wm/SizeCompatTests.java | 126 ++++++++++++++++++ .../android/server/wm/WindowTestsBase.java | 8 ++ 7 files changed, 199 insertions(+), 3 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 5f0753bb1e0c8..00b551494f703 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5356,6 +5356,9 @@ false + + false + false diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 4d4be22564713..a8748f12c235a 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4463,6 +4463,7 @@ + diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index f916ee40d5380..800fe090b457c 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -197,6 +197,12 @@ final class LetterboxConfiguration { // Whether using split screen aspect ratio as a default aspect ratio for unresizable apps. private boolean mIsSplitScreenAspectRatioForUnresizableAppsEnabled; + // Whether using display aspect ratio as a default aspect ratio for all letterboxed apps. + // mIsSplitScreenAspectRatioForUnresizableAppsEnabled and + // config_letterboxDefaultMinAspectRatioForUnresizableApps take priority over this for + // unresizable apps + private boolean mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox; + // Whether letterboxing strategy is enabled for translucent activities. If {@value false} // all the feature is disabled private boolean mTranslucentLetterboxingEnabled; @@ -288,6 +294,9 @@ final class LetterboxConfiguration { R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps)); mIsSplitScreenAspectRatioForUnresizableAppsEnabled = mContext.getResources().getBoolean( R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled); + mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox = mContext.getResources() + .getBoolean(R.bool + .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled); mTranslucentLetterboxingEnabled = mContext.getResources().getBoolean( R.bool.config_letterboxIsEnabledForTranslucentActivities); mIsCameraCompatTreatmentEnabled = mContext.getResources().getBoolean( @@ -942,6 +951,13 @@ final class LetterboxConfiguration { return mIsSplitScreenAspectRatioForUnresizableAppsEnabled; } + /** + * Whether using display aspect ratio as a default aspect ratio for all letterboxed apps. + */ + boolean getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox() { + return mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox; + } + /** * Overrides whether using split screen aspect ratio as a default aspect ratio for unresizable * apps. @@ -950,6 +966,14 @@ final class LetterboxConfiguration { mIsSplitScreenAspectRatioForUnresizableAppsEnabled = enabled; } + /** + * Overrides whether using display aspect ratio as a default aspect ratio for all letterboxed + * apps. + */ + void setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(boolean enabled) { + mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox = enabled; + } + /** * Resets whether using split screen aspect ratio as a default aspect ratio for unresizable * apps {@link R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled}. @@ -959,6 +983,16 @@ final class LetterboxConfiguration { R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled); } + /** + * Resets whether using display aspect ratio as a default aspect ratio for all letterboxed + * apps {@link R.bool.config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled}. + */ + void resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox() { + mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox = mContext.getResources() + .getBoolean(R.bool + .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled); + } + boolean isTranslucentLetterboxingEnabled() { return mTranslucentLetterboxingOverrideEnabled || (mTranslucentLetterboxingEnabled && isTranslucentLetterboxingAllowed()); diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 9c43c1d62ab8f..67e188fa90454 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -584,7 +584,7 @@ final class LetterboxUiController { ? getSplitScreenAspectRatio() : mActivityRecord.shouldCreateCompatDisplayInsets() ? getDefaultMinAspectRatioForUnresizableApps() - : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(); + : getDefaultMinAspectRatio(); } private float getDefaultMinAspectRatioForUnresizableApps() { @@ -593,7 +593,7 @@ final class LetterboxUiController { return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps() > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO ? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps() - : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(); + : getDefaultMinAspectRatio(); } return getSplitScreenAspectRatio(); @@ -621,6 +621,16 @@ final class LetterboxUiController { return computeAspectRatio(bounds); } + private float getDefaultMinAspectRatio() { + final DisplayContent displayContent = mActivityRecord.getDisplayContent(); + if (displayContent == null + || !mLetterboxConfiguration + .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) { + return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(); + } + return computeAspectRatio(new Rect(displayContent.getBounds())); + } + Resources getResources() { return mActivityRecord.mWmService.mContext.getResources(); } @@ -1014,6 +1024,9 @@ final class LetterboxUiController { + mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()); pw.println(prefix + " isSplitScreenAspectRatioForUnresizableAppsEnabled=" + mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()); + pw.println(prefix + " isDisplayAspectRatioEnabledForFixedOrientationLetterbox=" + + mLetterboxConfiguration + .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()); } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index aef6d1d155102..a06d84c44f17e 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -955,6 +955,10 @@ public class WindowManagerShellCommand extends ShellCommand { runSetBooleanFlag(pw, mLetterboxConfiguration ::setIsSplitScreenAspectRatioForUnresizableAppsEnabled); break; + case "--isDisplayAspectRatioEnabledForFixedOrientationLetterbox": + runSetBooleanFlag(pw, mLetterboxConfiguration + ::setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox); + break; case "--isTranslucentLetterboxingEnabled": runSetBooleanFlag(pw, mLetterboxConfiguration ::setTranslucentLetterboxingOverrideEnabled); @@ -1030,6 +1034,10 @@ public class WindowManagerShellCommand extends ShellCommand { mLetterboxConfiguration .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled(); break; + case "IsDisplayAspectRatioEnabledForFixedOrientationLetterbox": + mLetterboxConfiguration + .resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(); + break; case "isTranslucentLetterboxingEnabled": mLetterboxConfiguration.resetTranslucentLetterboxingEnabled(); break; @@ -1140,6 +1148,7 @@ public class WindowManagerShellCommand extends ShellCommand { mLetterboxConfiguration.resetDefaultPositionForVerticalReachability(); mLetterboxConfiguration.resetIsEducationEnabled(); mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled(); + mLetterboxConfiguration.resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(); mLetterboxConfiguration.resetTranslucentLetterboxingEnabled(); mLetterboxConfiguration.resetCameraCompatRefreshEnabled(); mLetterboxConfiguration.resetCameraCompatRefreshCycleThroughStopEnabled(); @@ -1187,7 +1196,9 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: " + mLetterboxConfiguration .getIsSplitScreenAspectRatioForUnresizableAppsEnabled()); - + pw.println("Is using display aspect ratio as aspect ratio for all letterboxed apps: " + + mLetterboxConfiguration + .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()); pw.println(" Is activity \"refresh\" in camera compatibility treatment enabled: " + mLetterboxConfiguration.isCameraCompatRefreshEnabled()); pw.println(" Refresh using \"stopped -> resumed\" cycle: " 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 995932c46201c..e5ff91f1ba373 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -1911,6 +1911,132 @@ public class SizeCompatTests extends WindowTestsBase { assertFitted(); } + @Test + public void testDisplayAspectRatioForResizablePortraitApps() { + // Set up a display in portrait and ignoring orientation request. + int displayWidth = 1400; + int displayHeight = 1600; + setUpDisplaySizeWithApp(displayWidth, displayHeight); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + mWm.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(2f); + + // Enable display aspect ratio to take precedence before + // fixedOrientationLetterboxAspectRatio + mWm.mLetterboxConfiguration + .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true); + + // Set up resizable app in portrait + prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */); + + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + // Move activity to split screen which takes half of the screen. + mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test"); + organizer.mPrimary.setBounds(0, 0, displayWidth, getExpectedSplitSize(displayHeight)); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode()); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode()); + + // App should launch in fixed orientation letterbox. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + // Checking that there is no size compat mode. + assertFitted(); + // Check that the display aspect ratio is used by the app. + final float targetMinAspectRatio = 1f * displayHeight / displayWidth; + final float delta = 0.01f; + assertEquals(targetMinAspectRatio, ActivityRecord + .computeAspectRatio(mActivity.getBounds()), delta); + } + + @Test + public void testDisplayAspectRatioForResizableLandscapeApps() { + // Set up a display in landscape and ignoring orientation request. + int displayWidth = 1600; + int displayHeight = 1400; + setUpDisplaySizeWithApp(displayWidth, displayHeight); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + mWm.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(2f); + + // Enable display aspect ratio to take precedence before + // fixedOrientationLetterboxAspectRatio + mWm.mLetterboxConfiguration + .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true); + + // Set up resizable app in landscape + prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_LANDSCAPE, false /* isUnresizable */); + + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + // Move activity to split screen which takes half of the screen. + mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test"); + organizer.mPrimary.setBounds(0, 0, getExpectedSplitSize(displayWidth), displayHeight); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode()); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode()); + + // App should launch in fixed orientation letterbox. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + // Checking that there is no size compat mode. + assertFitted(); + // Check that the display aspect ratio is used by the app. + final float targetMinAspectRatio = 1f * displayWidth / displayHeight; + final float delta = 0.01f; + assertEquals(targetMinAspectRatio, ActivityRecord + .computeAspectRatio(mActivity.getBounds()), delta); + } + + @Test + public void testDisplayAspectRatioForUnresizableLandscapeApps() { + // Set up a display in portrait and ignoring orientation request. + int displayWidth = 1400; + int displayHeight = 1600; + setUpDisplaySizeWithApp(displayWidth, displayHeight); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f); + // Enable display aspect ratio to take precedence before + // fixedOrientationLetterboxAspectRatio + mWm.mLetterboxConfiguration + .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true); + + prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); + + // App should launch in fixed orientation letterbox. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + // Checking that there is no size compat mode. + assertFitted(); + // Check that the display aspect ratio is used by the app. + final float targetMinAspectRatio = 1f * displayHeight / displayWidth; + final float delta = 0.01f; + assertEquals(targetMinAspectRatio, ActivityRecord + .computeAspectRatio(mActivity.getBounds()), delta); + } + + @Test + public void testDisplayAspectRatioForUnresizablePortraitApps() { + // Set up a display in landscape and ignoring orientation request. + int displayWidth = 1600; + int displayHeight = 1400; + setUpDisplaySizeWithApp(displayWidth, displayHeight); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f); + // Enable display aspect ratio to take precedence before + // fixedOrientationLetterboxAspectRatio + mWm.mLetterboxConfiguration + .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(true); + + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + // App should launch in fixed orientation letterbox. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + // Checking that there is no size compat mode. + assertFitted(); + // Check that the display aspect ratio is used by the app. + final float targetMinAspectRatio = 1f * displayWidth / displayHeight; + final float delta = 0.01f; + assertEquals(targetMinAspectRatio, ActivityRecord + .computeAspectRatio(mActivity.getBounds()), delta); + } + @Test public void testDisplayIgnoreOrientationRequest_orientationLetterboxBecameSizeCompatAfterRotate() { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 268aa3e5f5b46..f8b809463b2eb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -253,6 +253,12 @@ class WindowTestsBase extends SystemServiceTestsBase { // device form factors. mAtm.mWindowManager.mLetterboxConfiguration .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(false); + // Ensure aspect ratio for al apps isn't overridden on any device target. + // {@link com.android.internal.R.bool + // .config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled}, may be set on + // some device form factors. + mAtm.mWindowManager.mLetterboxConfiguration + .setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(false); checkDeviceSpecificOverridesNotApplied(); } @@ -267,6 +273,8 @@ class WindowTestsBase extends SystemServiceTestsBase { mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled(); mAtm.mWindowManager.mLetterboxConfiguration .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled(); + mAtm.mWindowManager.mLetterboxConfiguration + .resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(); } /**