Merge "Apply user aspect ratio override settings" into udc-qpr-dev am: 9b4891843f am: 9f2a5d6263
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/24014849
Change-Id: I8b08a0e4473162f86871574e08c1e05c87491fac
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 904d480..ea06b42 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -9413,6 +9413,9 @@
if (info.applicationInfo == null) {
return info.getMinAspectRatio();
}
+ if (mLetterboxUiController.shouldApplyUserMinAspectRatioOverride()) {
+ return mLetterboxUiController.getUserMinAspectRatio();
+ }
if (!mLetterboxUiController.shouldOverrideMinAspectRatio()) {
return info.getMinAspectRatio();
}
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 39f7570..394105a 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -40,6 +40,12 @@
import static android.content.pm.ActivityInfo.isFixedOrientation;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.screenOrientationToString;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
@@ -103,6 +109,7 @@
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.RemoteException;
import android.util.Slog;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -237,6 +244,10 @@
// Counter for ActivityRecord#setRequestedOrientation
private int mSetOrientationRequestCounter = 0;
+ // The min aspect ratio override set by user
+ @PackageManager.UserMinAspectRatio
+ private int mUserAspectRatio = USER_MIN_ASPECT_RATIO_UNSET;
+
// The CompatDisplayInsets of the opaque activity beneath the translucent one.
private ActivityRecord.CompatDisplayInsets mInheritedCompatDisplayInsets;
@@ -1059,7 +1070,7 @@
private float getDefaultMinAspectRatioForUnresizableApps() {
if (!mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()
- || mActivityRecord.getDisplayContent() == null) {
+ || mActivityRecord.getDisplayArea() == null) {
return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
> MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
@@ -1071,8 +1082,8 @@
float getSplitScreenAspectRatio() {
// Getting the same aspect ratio that apps get in split screen.
- final DisplayContent displayContent = mActivityRecord.getDisplayContent();
- if (displayContent == null) {
+ final DisplayArea displayArea = mActivityRecord.getDisplayArea();
+ if (displayArea == null) {
return getDefaultMinAspectRatioForUnresizableApps();
}
int dividerWindowWidth =
@@ -1080,7 +1091,7 @@
int dividerInsets =
getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_insets);
int dividerSize = dividerWindowWidth - dividerInsets * 2;
- final Rect bounds = new Rect(displayContent.getWindowConfiguration().getAppBounds());
+ final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
if (bounds.width() >= bounds.height()) {
bounds.inset(/* dx */ dividerSize / 2, /* dy */ 0);
bounds.right = bounds.centerX();
@@ -1091,14 +1102,57 @@
return computeAspectRatio(bounds);
}
+ boolean shouldApplyUserMinAspectRatioOverride() {
+ if (!mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()) {
+ return false;
+ }
+
+ try {
+ final int userAspectRatio = mActivityRecord.mAtmService.getPackageManager()
+ .getUserMinAspectRatio(mActivityRecord.packageName, mActivityRecord.mUserId);
+ mUserAspectRatio = userAspectRatio;
+ return userAspectRatio != USER_MIN_ASPECT_RATIO_UNSET;
+ } catch (RemoteException e) {
+ // Don't apply user aspect ratio override
+ Slog.w(TAG, "Exception thrown retrieving aspect ratio user override " + this, e);
+ return false;
+ }
+ }
+
+ float getUserMinAspectRatio() {
+ switch (mUserAspectRatio) {
+ case USER_MIN_ASPECT_RATIO_DISPLAY_SIZE:
+ return getDisplaySizeMinAspectRatio();
+ case USER_MIN_ASPECT_RATIO_SPLIT_SCREEN:
+ return getSplitScreenAspectRatio();
+ case USER_MIN_ASPECT_RATIO_16_9:
+ return 16 / 9f;
+ case USER_MIN_ASPECT_RATIO_4_3:
+ return 4 / 3f;
+ case USER_MIN_ASPECT_RATIO_3_2:
+ return 3 / 2f;
+ default:
+ throw new AssertionError("Unexpected user min aspect ratio override: "
+ + mUserAspectRatio);
+ }
+ }
+
+ private float getDisplaySizeMinAspectRatio() {
+ final DisplayArea displayArea = mActivityRecord.getDisplayArea();
+ if (displayArea == null) {
+ return mActivityRecord.info.getMinAspectRatio();
+ }
+ final Rect bounds = new Rect(displayArea.getWindowConfiguration().getAppBounds());
+ return computeAspectRatio(bounds);
+ }
+
private float getDefaultMinAspectRatio() {
- final DisplayContent displayContent = mActivityRecord.getDisplayContent();
- if (displayContent == null
+ if (mActivityRecord.getDisplayArea() == null
|| !mLetterboxConfiguration
.getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) {
return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
}
- return computeAspectRatio(new Rect(displayContent.getBounds()));
+ return getDisplaySizeMinAspectRatio();
}
Resources getResources() {
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 3908947..d5afe3b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -27,6 +27,11 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_DISPLAY_SIZE;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS;
@@ -91,9 +96,12 @@
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
@@ -2255,6 +2263,169 @@
}
@Test
+ public void testUserOverrideSplitScreenAspectRatioForLandscapeDisplay() {
+ final int displayWidth = 1600;
+ final int displayHeight = 1400;
+ setUpDisplaySizeWithApp(displayWidth, displayHeight);
+
+ float expectedAspectRatio = 1f * displayHeight / getExpectedSplitSize(displayWidth);
+
+ testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_SPLIT_SCREEN);
+ }
+
+ @Test
+ public void testUserOverrideSplitScreenAspectRatioForPortraitDisplay() {
+ final int displayWidth = 1400;
+ final int displayHeight = 1600;
+ setUpDisplaySizeWithApp(displayWidth, displayHeight);
+
+ float expectedAspectRatio = 1f * displayWidth / getExpectedSplitSize(displayHeight);
+
+ testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_SPLIT_SCREEN);
+ }
+
+ @Test
+ public void testUserOverrideDisplaySizeAspectRatioForLandscapeDisplay() {
+ final int displayWidth = 1600;
+ final int displayHeight = 1400;
+ setUpDisplaySizeWithApp(displayWidth, displayHeight);
+
+ float expectedAspectRatio = 1f * displayWidth / displayHeight;
+
+ testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_DISPLAY_SIZE);
+ }
+
+ @Test
+ public void testUserOverrideDisplaySizeAspectRatioForPortraitDisplay() {
+ final int displayWidth = 1400;
+ final int displayHeight = 1600;
+ setUpDisplaySizeWithApp(displayWidth, displayHeight);
+
+ float expectedAspectRatio = 1f * displayHeight / displayWidth;
+
+ testUserOverrideAspectRatio(expectedAspectRatio, USER_MIN_ASPECT_RATIO_DISPLAY_SIZE);
+ }
+
+ @Test
+ public void testUserOverride32AspectRatioForPortraitDisplay() {
+ setUpDisplaySizeWithApp(/* dw */ 1400, /* dh */ 1600);
+ testUserOverrideAspectRatio(3 / 2f, USER_MIN_ASPECT_RATIO_3_2);
+ }
+
+ @Test
+ public void testUserOverride32AspectRatioForLandscapeDisplay() {
+ setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
+ testUserOverrideAspectRatio(3 / 2f, USER_MIN_ASPECT_RATIO_3_2);
+ }
+
+ @Test
+ public void testUserOverride43AspectRatioForPortraitDisplay() {
+ setUpDisplaySizeWithApp(/* dw */ 1400, /* dh */ 1600);
+ testUserOverrideAspectRatio(4 / 3f, USER_MIN_ASPECT_RATIO_4_3);
+ }
+
+ @Test
+ public void testUserOverride43AspectRatioForLandscapeDisplay() {
+ setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
+ testUserOverrideAspectRatio(4 / 3f, USER_MIN_ASPECT_RATIO_4_3);
+ }
+
+ @Test
+ public void testUserOverride169AspectRatioForPortraitDisplay() {
+ setUpDisplaySizeWithApp(/* dw */ 1800, /* dh */ 1500);
+ testUserOverrideAspectRatio(16 / 9f, USER_MIN_ASPECT_RATIO_16_9);
+ }
+
+ @Test
+ public void testUserOverride169AspectRatioForLandscapeDisplay() {
+ setUpDisplaySizeWithApp(/* dw */ 1500, /* dh */ 1800);
+ testUserOverrideAspectRatio(16 / 9f, USER_MIN_ASPECT_RATIO_16_9);
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+ ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE})
+ public void testUserOverrideAspectRatioOverSystemOverride() {
+ setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
+
+ testUserOverrideAspectRatio(false,
+ SCREEN_ORIENTATION_PORTRAIT,
+ 3 / 2f,
+ USER_MIN_ASPECT_RATIO_3_2,
+ true);
+ }
+
+ @Test
+ public void testUserOverrideAspectRatioNotEnabled() {
+ setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
+
+ // App aspect ratio doesn't change
+ testUserOverrideAspectRatio(false,
+ SCREEN_ORIENTATION_PORTRAIT,
+ 1f * 1600 / 1400,
+ USER_MIN_ASPECT_RATIO_3_2,
+ false);
+ }
+
+ private void testUserOverrideAspectRatio(float expectedAspectRatio,
+ @PackageManager.UserMinAspectRatio int aspectRatio) {
+ testUserOverrideAspectRatio(true,
+ SCREEN_ORIENTATION_PORTRAIT,
+ expectedAspectRatio,
+ aspectRatio,
+ true);
+
+ testUserOverrideAspectRatio(false,
+ SCREEN_ORIENTATION_PORTRAIT,
+ expectedAspectRatio,
+ aspectRatio,
+ true);
+
+ testUserOverrideAspectRatio(true,
+ SCREEN_ORIENTATION_LANDSCAPE,
+ expectedAspectRatio,
+ aspectRatio,
+ true);
+
+ testUserOverrideAspectRatio(false,
+ SCREEN_ORIENTATION_LANDSCAPE,
+ expectedAspectRatio,
+ aspectRatio,
+ true);
+ }
+
+ private void testUserOverrideAspectRatio(boolean isUnresizable, int screenOrientation,
+ float expectedAspectRatio, @PackageManager.UserMinAspectRatio int aspectRatio,
+ boolean enabled) {
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ activity.mWmService.mLetterboxConfiguration
+ .setUserAppAspectRatioSettingsOverrideEnabled(enabled);
+ // Set user aspect ratio override
+ final IPackageManager pm = mAtm.getPackageManager();
+ try {
+ doReturn(aspectRatio).when(pm)
+ .getUserMinAspectRatio(activity.packageName, activity.mUserId);
+ } catch (RemoteException ignored) {
+ }
+
+ prepareLimitedBounds(activity, screenOrientation, isUnresizable);
+
+ final Rect afterBounds = activity.getBounds();
+ final int width = afterBounds.width();
+ final int height = afterBounds.height();
+ final float afterAspectRatio =
+ (float) Math.max(width, height) / (float) Math.min(width, height);
+
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ }
+
+ @Test
@EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN})
public void testOverrideSplitScreenAspectRatioForUnresizablePortraitApps() {