Add support for switching off sandboxing via device config flags
Bug: 187408243 Test: atest WmTests:SizeCompatTests Test: atest FrameworksCoreTests:ConstrainDisplayApisConfigTest Change-Id: I3ec02f3b2ba5c1825cdc530fd0f6f71abbe5bd10
This commit is contained in:
@@ -1348,7 +1348,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
public boolean neverSandboxDisplayApis() {
|
||||
return CompatChanges.isChangeEnabled(NEVER_SANDBOX_DISPLAY_APIS,
|
||||
applicationInfo.packageName,
|
||||
UserHandle.getUserHandleForUid(applicationInfo.uid));
|
||||
UserHandle.getUserHandleForUid(applicationInfo.uid))
|
||||
|| ConstrainDisplayApisConfig.neverConstrainDisplayApis(applicationInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
118
core/java/android/content/pm/ConstrainDisplayApisConfig.java
Normal file
118
core/java/android/content/pm/ConstrainDisplayApisConfig.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.pm;
|
||||
|
||||
import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS;
|
||||
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class for processing flags in the Device Config namespace 'constrain_display_apis'.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class ConstrainDisplayApisConfig {
|
||||
private static final String TAG = ConstrainDisplayApisConfig.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* A string flag whose value holds a comma separated list of package entries in the format
|
||||
* '<package-name>:<min-version-code>?:<max-version-code>?' for which Display APIs should never
|
||||
* be constrained.
|
||||
*/
|
||||
private static final String FLAG_NEVER_CONSTRAIN_DISPLAY_APIS = "never_constrain_display_apis";
|
||||
|
||||
/**
|
||||
* A boolean flag indicating whether Display APIs should never be constrained for all
|
||||
* packages. If true, {@link #FLAG_NEVER_CONSTRAIN_DISPLAY_APIS} is ignored.
|
||||
*/
|
||||
private static final String FLAG_NEVER_CONSTRAIN_DISPLAY_APIS_ALL_PACKAGES =
|
||||
"never_constrain_display_apis_all_packages";
|
||||
|
||||
/**
|
||||
* 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
|
||||
* applicationInfo}.
|
||||
*
|
||||
* @param applicationInfo Information about the application/package.
|
||||
*/
|
||||
public static boolean neverConstrainDisplayApis(ApplicationInfo applicationInfo) {
|
||||
if (DeviceConfig.getBoolean(NAMESPACE_CONSTRAIN_DISPLAY_APIS,
|
||||
FLAG_NEVER_CONSTRAIN_DISPLAY_APIS_ALL_PACKAGES, /* defaultValue= */ false)) {
|
||||
return true;
|
||||
}
|
||||
String configStr = DeviceConfig.getString(NAMESPACE_CONSTRAIN_DISPLAY_APIS,
|
||||
FLAG_NEVER_CONSTRAIN_DISPLAY_APIS, /* defaultValue= */ "");
|
||||
|
||||
// String#split returns a non-empty array given an empty string.
|
||||
if (configStr.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String packageEntryString : configStr.split(",")) {
|
||||
if (matchesApplicationInfo(packageEntryString, applicationInfo)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given {@code packageEntryString} and returns true if {@code
|
||||
* applicationInfo.packageName} matches the package name in the config and {@code
|
||||
* applicationInfo.longVersionCode} is within the version range in the config.
|
||||
*
|
||||
* <p>Logs a warning and returns false in case the given {@code packageEntryString} is invalid.
|
||||
*
|
||||
* @param packageEntryStr A package entry expected to be in the format
|
||||
* '<package-name>:<min-version-code>?:<max-version-code>?'.
|
||||
* @param applicationInfo Information about the application/package.
|
||||
*/
|
||||
private static boolean matchesApplicationInfo(String packageEntryStr,
|
||||
ApplicationInfo applicationInfo) {
|
||||
List<String> packageAndVersions = Arrays.asList(packageEntryStr.split(":", 3));
|
||||
if (packageAndVersions.size() != 3) {
|
||||
Slog.w(TAG, "Invalid package entry in flag 'never_constrain_display_apis': "
|
||||
+ packageEntryStr);
|
||||
return false;
|
||||
}
|
||||
String packageName = packageAndVersions.get(0);
|
||||
String minVersionCodeStr = packageAndVersions.get(1);
|
||||
String maxVersionCodeStr = packageAndVersions.get(2);
|
||||
|
||||
if (!packageName.equals(applicationInfo.packageName)) {
|
||||
return false;
|
||||
}
|
||||
long version = applicationInfo.longVersionCode;
|
||||
try {
|
||||
if (!minVersionCodeStr.isEmpty() && version < Long.parseLong(minVersionCodeStr)) {
|
||||
return false;
|
||||
}
|
||||
if (!maxVersionCodeStr.isEmpty() && version > Long.parseLong(maxVersionCodeStr)) {
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
Slog.w(TAG, "Invalid APK version code in package entry: " + packageEntryStr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.pm;
|
||||
|
||||
import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfig.Properties;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Test class for {@link ConstrainDisplayApisConfig}.
|
||||
*
|
||||
* Build/Install/Run:
|
||||
* atest FrameworksCoreTests:ConstrainDisplayApisConfigTest
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public final class ConstrainDisplayApisConfigTest {
|
||||
|
||||
private Properties mInitialConstrainDisplayApisFlags;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mInitialConstrainDisplayApisFlags = DeviceConfig.getProperties(
|
||||
NAMESPACE_CONSTRAIN_DISPLAY_APIS);
|
||||
clearConstrainDisplayApisFlags();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
DeviceConfig.setProperties(mInitialConstrainDisplayApisFlags);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void neverConstrainDisplayApis_allPackagesFlagTrue_returnsTrue() {
|
||||
setNeverConstrainDisplayApisAllPackagesFlag("true");
|
||||
// Setting 'never_constrain_display_apis' as well to make sure it is ignored.
|
||||
setNeverConstrainDisplayApisFlag("com.android.other:1:2,com.android.other2::");
|
||||
|
||||
testNeverConstrainDisplayApis("com.android.test", /* version= */ 5, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.other", /* version= */ 0, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.other", /* version= */ 3, /* expected= */ true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void neverConstrainDisplayApis_flagsNoSet_returnsFalse() {
|
||||
testNeverConstrainDisplayApis("com.android.test", /* version= */ 1, /* expected= */ false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void neverConstrainDisplayApis_flagsHasSingleEntry_returnsTrueForPackageWithinRange() {
|
||||
setNeverConstrainDisplayApisFlag("com.android.test:1:1");
|
||||
|
||||
testNeverConstrainDisplayApis("com.android.other", /* version= */ 5, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test", /* version= */ 0, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test", /* version= */ 1, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test", /* version= */ 2, /* expected= */ false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void neverConstrainDisplayApis_flagHasEntries_returnsTrueForPackagesWithinRange() {
|
||||
setNeverConstrainDisplayApisFlag("com.android.test1::,com.android.test2:1:3,"
|
||||
+ "com.android.test3:5:,com.android.test4::8");
|
||||
|
||||
// Package 'com.android.other'
|
||||
testNeverConstrainDisplayApis("com.android.other", /* version= */ 5, /* expected= */ false);
|
||||
// Package 'com.android.test1'
|
||||
testNeverConstrainDisplayApis("com.android.test1", /* version= */ 5, /* expected= */ true);
|
||||
// Package 'com.android.test2'
|
||||
testNeverConstrainDisplayApis("com.android.test2", /* version= */ 0, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test2", /* version= */ 1, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test2", /* version= */ 2, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test2", /* version= */ 3, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test2", /* version= */ 4, /* expected= */ false);
|
||||
// Package 'com.android.test3'
|
||||
testNeverConstrainDisplayApis("com.android.test3", /* version= */ 4, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test3", /* version= */ 5, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test3", /* version= */ 6, /* expected= */ true);
|
||||
// Package 'com.android.test4'
|
||||
testNeverConstrainDisplayApis("com.android.test4", /* version= */ 7, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test4", /* version= */ 8, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test4", /* version= */ 9, /* expected= */ false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void neverConstrainDisplayApis_flagHasInvalidEntries_ignoresInvalidEntries() {
|
||||
// We add a valid entry before and after the invalid ones to make sure they are applied.
|
||||
setNeverConstrainDisplayApisFlag("com.android.test1::,com.android.test2:1,"
|
||||
+ "com.android.test3:5:ten,com.android.test4:5::,com.android.test5::");
|
||||
|
||||
testNeverConstrainDisplayApis("com.android.test1", /* version= */ 5, /* expected= */ true);
|
||||
testNeverConstrainDisplayApis("com.android.test2", /* version= */ 2, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test3", /* version= */ 7, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test4", /* version= */ 7, /* expected= */ false);
|
||||
testNeverConstrainDisplayApis("com.android.test5", /* version= */ 5, /* expected= */ true);
|
||||
}
|
||||
|
||||
private static void testNeverConstrainDisplayApis(String packageName, long version,
|
||||
boolean expected) {
|
||||
boolean result = ConstrainDisplayApisConfig.neverConstrainDisplayApis(
|
||||
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;
|
||||
applicationInfo.longVersionCode = version;
|
||||
return applicationInfo;
|
||||
}
|
||||
|
||||
private static void setNeverConstrainDisplayApisFlag(@Nullable String value) {
|
||||
DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS, "never_constrain_display_apis",
|
||||
value, /* makeDefault= */ false);
|
||||
}
|
||||
|
||||
private static void setNeverConstrainDisplayApisAllPackagesFlag(@Nullable String value) {
|
||||
DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS,
|
||||
"never_constrain_display_apis_all_packages",
|
||||
value, /* makeDefault= */ false);
|
||||
}
|
||||
|
||||
private static void clearConstrainDisplayApisFlags() {
|
||||
setNeverConstrainDisplayApisFlag(null);
|
||||
setNeverConstrainDisplayApisAllPackagesFlag(null);
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@
|
||||
<uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
|
||||
<uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
|
||||
<uses-permission android:name="android.permission.CAPTURE_BLACKOUT_CONTENT"/>
|
||||
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
|
||||
|
||||
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
|
||||
<application android:debuggable="true"
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
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;
|
||||
import static android.view.Surface.ROTATION_180;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
@@ -54,6 +55,7 @@ import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.app.WindowConfiguration;
|
||||
@@ -64,6 +66,8 @@ import android.content.pm.ActivityInfo.ScreenOrientation;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfig.Properties;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
@@ -71,6 +75,8 @@ import androidx.test.filters.MediumTest;
|
||||
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
|
||||
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
@@ -91,6 +97,19 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
|
||||
private Task mTask;
|
||||
private ActivityRecord mActivity;
|
||||
private Properties mInitialConstrainDisplayApisFlags;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mInitialConstrainDisplayApisFlags = DeviceConfig.getProperties(
|
||||
NAMESPACE_CONSTRAIN_DISPLAY_APIS);
|
||||
clearConstrainDisplayApisFlags();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
DeviceConfig.setProperties(mInitialConstrainDisplayApisFlags);
|
||||
}
|
||||
|
||||
private void setUpApp(DisplayContent display) {
|
||||
mTask = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true).build();
|
||||
@@ -790,6 +809,90 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertActivityMaxBoundsSandboxed(activity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeverConstrainDisplayApisDeviceConfig_allPackagesFlagTrue_sandboxNotApplied() {
|
||||
setUpDisplaySizeWithApp(1000, 1200);
|
||||
|
||||
setNeverConstrainDisplayApisAllPackagesFlag("true");
|
||||
// Setting 'never_constrain_display_apis' as well to make sure it is ignored.
|
||||
setNeverConstrainDisplayApisFlag("com.android.other::,com.android.other2::");
|
||||
|
||||
// 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);
|
||||
|
||||
// Activity max bounds should not be sandboxed, even though it is letterboxed.
|
||||
assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertThat(activity.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(activity.getDisplayArea().getBounds());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeverConstrainDisplayApisDeviceConfig_packageInRange_sandboxingNotApplied() {
|
||||
setUpDisplaySizeWithApp(1000, 1200);
|
||||
|
||||
setNeverConstrainDisplayApisFlag(
|
||||
"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);
|
||||
|
||||
// Activity max bounds should not be sandboxed, even though it is letterboxed.
|
||||
assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
|
||||
assertThat(activity.getConfiguration().windowConfiguration.getMaxBounds())
|
||||
.isEqualTo(activity.getDisplayArea().getBounds());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeverConstrainDisplayApisDeviceConfig_packageOutsideRange_sandboxingApplied() {
|
||||
setUpDisplaySizeWithApp(1000, 1200);
|
||||
|
||||
setNeverConstrainDisplayApisFlag("com.android.other::,com.android.frameworks.wmtests:1:5");
|
||||
|
||||
// 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);
|
||||
|
||||
// Activity max bounds should be sandboxed due to letterboxed and the mismatch with flag.
|
||||
assertActivityMaxBoundsSandboxed(activity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeverConstrainDisplayApisDeviceConfig_packageNotInFlag_sandboxingApplied() {
|
||||
setUpDisplaySizeWithApp(1000, 1200);
|
||||
|
||||
setNeverConstrainDisplayApisFlag("com.android.other::,com.android.other2::");
|
||||
|
||||
// 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);
|
||||
|
||||
// Activity max bounds should be sandboxed due to letterboxed and the mismatch with flag.
|
||||
assertActivityMaxBoundsSandboxed(activity);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({ActivityInfo.ALWAYS_SANDBOX_DISPLAY_APIS})
|
||||
public void testAlwaysSandboxDisplayApis_configEnabled_sandboxingApplied_unresizable() {
|
||||
@@ -1927,4 +2030,20 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
displayContent.computeScreenConfiguration(c);
|
||||
displayContent.onRequestedOverrideConfigurationChanged(c);
|
||||
}
|
||||
|
||||
private static void setNeverConstrainDisplayApisFlag(@Nullable String value) {
|
||||
DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS, "never_constrain_display_apis",
|
||||
value, /* makeDefault= */ false);
|
||||
}
|
||||
|
||||
private static void setNeverConstrainDisplayApisAllPackagesFlag(@Nullable String value) {
|
||||
DeviceConfig.setProperty(NAMESPACE_CONSTRAIN_DISPLAY_APIS,
|
||||
"never_constrain_display_apis_all_packages",
|
||||
value, /* makeDefault= */ false);
|
||||
}
|
||||
|
||||
private static void clearConstrainDisplayApisFlags() {
|
||||
setNeverConstrainDisplayApisFlag(null);
|
||||
setNeverConstrainDisplayApisAllPackagesFlag(null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user