From f332106222be60feb46e61c52a03b204fcb4226e Mon Sep 17 00:00:00 2001 From: tomnatan Date: Tue, 6 Jul 2021 14:55:42 +0000 Subject: [PATCH] Add support for always_constrain_display_apis flag Bug: 191184114 Test: atest WmTests:SizeCompatTests Test: atest FrameworksCoreTests:ConstrainDisplayApisConfigTest Change-Id: Ifc0d48c838216603c00f4cc09d0df2fd145a53a6 --- .../java/android/content/pm/ActivityInfo.java | 3 +- .../pm/ConstrainDisplayApisConfig.java | 32 +++++++++++++- .../pm/ConstrainDisplayApisConfigTest.java | 43 +++++++++++++++++-- .../android/server/wm/SizeCompatTests.java | 34 ++++++++++++--- 4 files changed, 100 insertions(+), 12 deletions(-) diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 60ab83aa2264b..95c5612aeee47 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1363,7 +1363,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { public boolean alwaysSandboxDisplayApis() { return CompatChanges.isChangeEnabled(ALWAYS_SANDBOX_DISPLAY_APIS, applicationInfo.packageName, - UserHandle.getUserHandleForUid(applicationInfo.uid)); + UserHandle.getUserHandleForUid(applicationInfo.uid)) + || ConstrainDisplayApisConfig.alwaysConstrainDisplayApis(applicationInfo); } /** @hide */ diff --git a/core/java/android/content/pm/ConstrainDisplayApisConfig.java b/core/java/android/content/pm/ConstrainDisplayApisConfig.java index 1337347cdaf02..11ba3d4ba9a29 100644 --- a/core/java/android/content/pm/ConstrainDisplayApisConfig.java +++ b/core/java/android/content/pm/ConstrainDisplayApisConfig.java @@ -46,6 +46,14 @@ public final class ConstrainDisplayApisConfig { private static final String FLAG_NEVER_CONSTRAIN_DISPLAY_APIS_ALL_PACKAGES = "never_constrain_display_apis_all_packages"; + /** + * A string flag whose value holds a comma separated list of package entries in the format + * ':?:?' for which Display APIs should + * always be constrained. + */ + private static final String FLAG_ALWAYS_CONSTRAIN_DISPLAY_APIS = + "always_constrain_display_apis"; + /** * Returns true if either the flag 'never_constrain_display_apis_all_packages' is true or the * flag 'never_constrain_display_apis' contains a package entry that matches the given {@code @@ -58,8 +66,30 @@ public final class ConstrainDisplayApisConfig { FLAG_NEVER_CONSTRAIN_DISPLAY_APIS_ALL_PACKAGES, /* defaultValue= */ false)) { return true; } + + return flagHasMatchingPackageEntry(FLAG_NEVER_CONSTRAIN_DISPLAY_APIS, applicationInfo); + } + + /** + * Returns true if the flag 'always_constrain_display_apis' contains a package entry that + * matches the given {@code applicationInfo}. + * + * @param applicationInfo Information about the application/package. + */ + public static boolean alwaysConstrainDisplayApis(ApplicationInfo applicationInfo) { + return flagHasMatchingPackageEntry(FLAG_ALWAYS_CONSTRAIN_DISPLAY_APIS, applicationInfo); + } + + /** + * Returns true if the flag with the given {@code flagName} contains a package entry that + * matches the given {@code applicationInfo}. + * + * @param applicationInfo Information about the application/package. + */ + private static boolean flagHasMatchingPackageEntry(String flagName, + ApplicationInfo applicationInfo) { String configStr = DeviceConfig.getString(NAMESPACE_CONSTRAIN_DISPLAY_APIS, - FLAG_NEVER_CONSTRAIN_DISPLAY_APIS, /* defaultValue= */ ""); + flagName, /* defaultValue= */ ""); // String#split returns a non-empty array given an empty string. if (configStr.isEmpty()) { diff --git a/core/tests/coretests/src/android/content/pm/ConstrainDisplayApisConfigTest.java b/core/tests/coretests/src/android/content/pm/ConstrainDisplayApisConfigTest.java index 1dfbfcd85a736..0456029f45a04 100644 --- a/core/tests/coretests/src/android/content/pm/ConstrainDisplayApisConfigTest.java +++ b/core/tests/coretests/src/android/content/pm/ConstrainDisplayApisConfigTest.java @@ -48,7 +48,8 @@ public final class ConstrainDisplayApisConfigTest { public void setUp() throws Exception { mInitialConstrainDisplayApisFlags = DeviceConfig.getProperties( NAMESPACE_CONSTRAIN_DISPLAY_APIS); - clearConstrainDisplayApisFlags(); + DeviceConfig.setProperties( + new Properties.Builder(NAMESPACE_CONSTRAIN_DISPLAY_APIS).build()); } @After @@ -120,6 +121,29 @@ public final class ConstrainDisplayApisConfigTest { testNeverConstrainDisplayApis("com.android.test5", /* version= */ 5, /* expected= */ true); } + @Test + public void alwaysConstrainDisplayApis_flagsNoSet_returnsFalse() { + testAlwaysConstrainDisplayApis("com.android.test", /* version= */ 1, /* expected= */ false); + } + + @Test + public void alwaysConstrainDisplayApis_flagHasEntries_returnsTrueForPackagesWithinRange() { + setAlwaysConstrainDisplayApisFlag("com.android.test1::,com.android.test2:1:2"); + + // Package 'com.android.other' + testAlwaysConstrainDisplayApis("com.android.other", /* version= */ 5, /* expected= */ + false); + // Package 'com.android.test1' + testAlwaysConstrainDisplayApis("com.android.test1", /* version= */ 5, /* expected= */ true); + // Package 'com.android.test2' + testAlwaysConstrainDisplayApis("com.android.test2", /* version= */ 0, /* expected= */ + false); + testAlwaysConstrainDisplayApis("com.android.test2", /* version= */ 1, /* expected= */ true); + testAlwaysConstrainDisplayApis("com.android.test2", /* version= */ 2, /* expected= */ true); + testAlwaysConstrainDisplayApis("com.android.test2", /* version= */ 3, /* expected= */ + false); + } + private static void testNeverConstrainDisplayApis(String packageName, long version, boolean expected) { boolean result = ConstrainDisplayApisConfig.neverConstrainDisplayApis( @@ -131,6 +155,17 @@ public final class ConstrainDisplayApisConfigTest { } } + private static void testAlwaysConstrainDisplayApis(String packageName, long version, + boolean expected) { + boolean result = ConstrainDisplayApisConfig.alwaysConstrainDisplayApis( + buildApplicationInfo(packageName, version)); + if (expected) { + assertTrue(result); + } else { + assertFalse(result); + } + } + private static ApplicationInfo buildApplicationInfo(String packageName, long version) { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.packageName = packageName; @@ -149,8 +184,8 @@ public final class ConstrainDisplayApisConfigTest { value, /* makeDefault= */ false); } - private static void clearConstrainDisplayApisFlags() { - setNeverConstrainDisplayApisFlag(null); - setNeverConstrainDisplayApisAllPackagesFlag(null); + private static void setAlwaysConstrainDisplayApisFlag(@Nullable String value) { + DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS, "always_constrain_display_apis", + value, /* makeDefault= */ false); } } 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 4872ec511ccc0..f270d10e55a8f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -105,7 +105,8 @@ public class SizeCompatTests extends WindowTestsBase { public void setUp() throws Exception { mInitialConstrainDisplayApisFlags = DeviceConfig.getProperties( NAMESPACE_CONSTRAIN_DISPLAY_APIS); - clearConstrainDisplayApisFlags(); + DeviceConfig.setProperties( + new Properties.Builder(NAMESPACE_CONSTRAIN_DISPLAY_APIS).build()); } @After @@ -923,7 +924,7 @@ public class SizeCompatTests extends WindowTestsBase { @Test @DisableCompatChanges({ActivityInfo.ALWAYS_SANDBOX_DISPLAY_APIS}) - public void testAlwaysSandboxDisplayApis_configDisabled_sandboxingNotApplied() { + public void testAlwaysSandboxDisplayApis_configDisabled_sandboxingApplied() { setUpDisplaySizeWithApp(1000, 1200); // Make the task root resizable. @@ -935,7 +936,7 @@ public class SizeCompatTests extends WindowTestsBase { activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); prepareUnresizable(activity, /* maxAspect=*/ 1.5f, SCREEN_ORIENTATION_LANDSCAPE); - // Activity max bounds be sandboxed due to letterbox and the config being disabled. + // Activity max bounds should be sandboxed due to letterbox and the config being disabled. assertActivityMaxBoundsSandboxed(activity); } @@ -964,6 +965,27 @@ public class SizeCompatTests extends WindowTestsBase { assertActivityMaxBoundsSandboxed(activity); } + @Test + public void testAlwaysConstrainDisplayApisDeviceConfig_packageInRange_sandboxingApplied() { + setUpDisplaySizeWithApp(1000, 1200); + + setAlwaysConstrainDisplayApisFlag( + "com.android.frameworks.wmtests:20:,com.android.other::," + + "com.android.frameworks.wmtests:0:10"); + + // Make the task root resizable. + mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE; + + // Create an activity with a max aspect ratio on the same task. + final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */false, + RESIZE_MODE_UNRESIZEABLE, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + prepareUnresizable(activity, /* maxAspect=*/ 1.5f, SCREEN_ORIENTATION_LANDSCAPE); + + // Resizable activity is sandboxed due to match with flag. + assertActivityMaxBoundsSandboxed(activity); + } + @Test @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO, ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM}) @@ -2120,8 +2142,8 @@ public class SizeCompatTests extends WindowTestsBase { value, /* makeDefault= */ false); } - private static void clearConstrainDisplayApisFlags() { - setNeverConstrainDisplayApisFlag(null); - setNeverConstrainDisplayApisAllPackagesFlag(null); + private static void setAlwaysConstrainDisplayApisFlag(@Nullable String value) { + DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS, "always_constrain_display_apis", + value, /* makeDefault= */ false); } }