summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/pm/ActivityInfo.java3
-rw-r--r--core/java/android/content/pm/ConstrainDisplayApisConfig.java118
2 files changed, 120 insertions, 1 deletions
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 03f6380e279f..af5f9ceb14d8 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -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);
}
/**
diff --git a/core/java/android/content/pm/ConstrainDisplayApisConfig.java b/core/java/android/content/pm/ConstrainDisplayApisConfig.java
new file mode 100644
index 000000000000..1337347cdaf0
--- /dev/null
+++ b/core/java/android/content/pm/ConstrainDisplayApisConfig.java
@@ -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;
+ }
+}