diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/content/pm/ActivityInfo.java | 3 | ||||
| -rw-r--r-- | core/java/android/content/pm/ConstrainDisplayApisConfig.java | 118 |
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; + } +} |
