diff options
5 files changed, 132 insertions, 21 deletions
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 95c5612aeee4..e28e4ad9ae9f 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -994,9 +994,10 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * OVERRIDE_MIN_ASPECT_RATIO_MEDIUM * OVERRIDE_MIN_ASPECT_RATIO_LARGE * - * If OVERRIDE_MIN_ASPECT_RATIO is applied, the min aspect ratio given in the app's - * manifest will be overridden to the largest enabled aspect ratio treatment unless the app's - * manifest value is higher. + * If OVERRIDE_MIN_ASPECT_RATIO is applied, and the activity's orientation is fixed to + * portrait, the min aspect ratio given in the app's manifest will be overridden to the + * largest enabled aspect ratio treatment unless the app's manifest value is higher. + * TODO(b/203647190): add OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY instead of portrait by default * @hide */ @ChangeId @@ -1232,8 +1233,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * Returns true if the activity has maximum or minimum aspect ratio. * @hide */ - public boolean hasFixedAspectRatio() { - return getMaxAspectRatio() != 0 || getMinAspectRatio() != 0; + public boolean hasFixedAspectRatio(@ScreenOrientation int orientation) { + return getMaxAspectRatio() != 0 || getMinAspectRatio(orientation) != 0; } /** @@ -1392,10 +1393,14 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * {@code getManifestMinAspectRatio}. * @hide */ - public float getMinAspectRatio() { + public float getMinAspectRatio(@ScreenOrientation int orientation) { + // TODO(b/203647190): check orientation only if OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY + // In case the activity's orientation isn't fixed to portrait, OVERRIDE_MIN_ASPECT_RATIO + // shouldn't be applied. if (applicationInfo == null || !CompatChanges.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO, applicationInfo.packageName, - UserHandle.getUserHandleForUid(applicationInfo.uid))) { + UserHandle.getUserHandleForUid(applicationInfo.uid)) + || !isFixedOrientationPortrait(orientation)) { return mMinAspectRatio; } @@ -1521,9 +1526,10 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { if (getMaxAspectRatio() != 0) { pw.println(prefix + "maxAspectRatio=" + getMaxAspectRatio()); } - if (getMinAspectRatio() != 0) { - pw.println(prefix + "minAspectRatio=" + getMinAspectRatio()); - if (getManifestMinAspectRatio() != getMinAspectRatio()) { + final float minAspectRatio = getMinAspectRatio(screenOrientation); + if (minAspectRatio != 0) { + pw.println(prefix + "minAspectRatio=" + minAspectRatio); + if (getManifestMinAspectRatio() != minAspectRatio) { pw.println(prefix + "getManifestMinAspectRatio=" + getManifestMinAspectRatio()); } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5672ef32c00a..e5340db2f0e2 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1146,10 +1146,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (info.getMaxAspectRatio() != 0) { pw.println(prefix + "maxAspectRatio=" + info.getMaxAspectRatio()); } - if (info.getMinAspectRatio() != 0) { - pw.println(prefix + "minAspectRatio=" + info.getMinAspectRatio()); + final float minAspectRatio = getMinAspectRatio(); + if (minAspectRatio != 0) { + pw.println(prefix + "minAspectRatio=" + minAspectRatio); } - if (info.getMinAspectRatio() != info.getManifestMinAspectRatio()) { + if (minAspectRatio != info.getManifestMinAspectRatio()) { // Log the fact that we've overridden the min aspect ratio from the manifest pw.println(prefix + "manifestMinAspectRatio=" + info.getManifestMinAspectRatio()); @@ -7277,7 +7278,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } } - return !isResizeable() && (info.isFixedOrientation() || info.hasFixedAspectRatio()) + return !isResizeable() && (info.isFixedOrientation() || hasFixedAspectRatio()) // The configuration of non-standard type should be enforced by system. // {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} is set when this activity is // added to a task, but this function is called when resolving the launch params, at @@ -7948,13 +7949,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } } - if (info.getMinAspectRatio() > 0) { + final float minAspectRatio = getMinAspectRatio(); + if (minAspectRatio > 0) { // The activity should have at least the min aspect ratio, so this checks if the // container still has available space to provide larger aspect ratio. final float containerAspectRatio = (0.5f + Math.max(containerAppWidth, containerAppHeight)) / Math.min(containerAppWidth, containerAppHeight); - if (containerAspectRatio <= info.getMinAspectRatio()) { + if (containerAspectRatio <= minAspectRatio) { // The long side has reached the parent. return false; } @@ -8165,8 +8167,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A Rect containingBounds, float desiredAspectRatio, boolean fixedOrientationLetterboxed) { final float maxAspectRatio = info.getMaxAspectRatio(); final Task rootTask = getRootTask(); - final float minAspectRatio = info.getMinAspectRatio(); - + final float minAspectRatio = getMinAspectRatio(); if (task == null || rootTask == null || (inMultiWindowMode() && !shouldCreateCompatDisplayInsets() && !fixedOrientationLetterboxed) @@ -8270,6 +8271,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** + * Returns the min aspect ratio of this activity. + */ + private float getMinAspectRatio() { + return info.getMinAspectRatio(getRequestedOrientation()); + } + + /** + * Returns true if the activity has maximum or minimum aspect ratio. + */ + private boolean hasFixedAspectRatio() { + return info.hasFixedAspectRatio(getRequestedOrientation()); + } + + /** * Returns the aspect ratio of the given {@code rect}. */ static float computeAspectRatio(Rect rect) { diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index d543c1f756c9..b8ceb4a4f421 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -818,7 +818,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight; // Aspect ratio requirements. - final float minAspectRatio = info.getMinAspectRatio(); + final float minAspectRatio = info.getMinAspectRatio(orientation); final float maxAspectRatio = info.getMaxAspectRatio(); final int width = Math.min(defaultWidth, Math.max(phoneWidth, layoutMinWidth)); diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt index 581ff5472e92..9099bb515361 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt @@ -341,10 +341,8 @@ open class AndroidPackageParsingTestBase { launchToken=${this.launchToken} lockTaskLaunchMode=${this.lockTaskLaunchMode} logo=${this.logo} - maxAspectRatio=${this.maxAspectRatio} maxRecents=${this.maxRecents} metaData=${this.metaData.dumpToString()} - minAspectRatio=${this.minAspectRatio} name=${this.name} nonLocalizedLabel=${ // Per b/184574333, v1 mistakenly trimmed the label. v2 fixed this, but for test 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 f9e7898d5969..bed0a94f3b8f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -1123,6 +1123,98 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO, + ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM}) + public void testOverrideMinAspectRatioScreenOrientationNotSetThenChangedToPortrait() { + // In this test, the activity's orientation isn't fixed to portrait, therefore the override + // isn't applied. + + setUpDisplaySizeWithApp(1000, 1200); + + // Create a size compat activity on the same task. + final ActivityRecord activity = new ActivityBuilder(mAtm) + .setTask(mTask) + .setComponent(ComponentName.createRelative(mContext, + SizeCompatTests.class.getName())) + .setUid(android.os.Process.myUid()) + .build(); + + // The per-package override should have no effect + assertEquals(1200, activity.getBounds().height()); + assertEquals(1000, activity.getBounds().width()); + + // After changing the orientation to portrait the override should be applied. + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + activity.clearSizeCompatMode(); + + // The per-package override forces the activity into a 3:2 aspect ratio + assertEquals(1200, activity.getBounds().height()); + assertEquals(1200 / ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE, + activity.getBounds().width(), 0.5); + } + + @Test + @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO, + ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM}) + public void testOverrideMinAspectRatioScreenOrientationLandscapeThenChangedToPortrait() { + // In this test, the activity's orientation isn't fixed to portrait, therefore the override + // isn't applied. + + setUpDisplaySizeWithApp(1000, 1200); + + // Create a size compat activity on the same task. + final ActivityRecord activity = new ActivityBuilder(mAtm) + .setTask(mTask) + .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) + .setComponent(ComponentName.createRelative(mContext, + SizeCompatTests.class.getName())) + .setUid(android.os.Process.myUid()) + .build(); + + // The per-package override should have no effect + assertEquals(1200, activity.getBounds().height()); + assertEquals(1000, activity.getBounds().width()); + + // After changing the orientation to portrait the override should be applied. + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + activity.clearSizeCompatMode(); + + // The per-package override forces the activity into a 3:2 aspect ratio + assertEquals(1200, activity.getBounds().height()); + assertEquals(1200 / ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE, + activity.getBounds().width(), 0.5); + } + + @Test + @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO, + ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM}) + public void testOverrideMinAspectRatioScreenOrientationPortraitThenChangedToUnspecified() { + setUpDisplaySizeWithApp(1000, 1200); + + // Create a size compat activity on the same task. + final ActivityRecord activity = new ActivityBuilder(mAtm) + .setTask(mTask) + .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) + .setComponent(ComponentName.createRelative(mContext, + SizeCompatTests.class.getName())) + .setUid(android.os.Process.myUid()) + .build(); + + // The per-package override forces the activity into a 3:2 aspect ratio + assertEquals(1200, activity.getBounds().height()); + assertEquals(1200 / ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE, + activity.getBounds().width(), 0.5); + + // After changing the orientation to landscape the override shouldn't be applied. + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + activity.clearSizeCompatMode(); + + // The per-package override should have no effect + assertEquals(1200, activity.getBounds().height()); + assertEquals(1000, activity.getBounds().width()); + } + + @Test @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM}) public void testOverrideMinAspectRatioWithoutGlobalOverride() { // In this test, only OVERRIDE_MIN_ASPECT_RATIO_1_5 is set, which has no effect without |