From 7c48e0e074c62eccf0fb6fdad8fd03b4b6107c23 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Thu, 18 Jan 2018 15:25:18 +0000 Subject: [PATCH] Set DEXOPT_DISABLE_HIDDEN_API_CHECKS for system apps For now, system apps will be exempt from hidden API access checks. Pass the appropriate flag to dexopt. Test: manual Bug: 64382372 Bug: 72305689 Merged-In: I5676ffa3a5ba680bf5f6bab0b62f0acf4a933097 Change-Id: Idc3067d2c6040f15fe0f051090ba45efe591ebae --- core/java/android/content/pm/ApplicationInfo.java | 7 +++++++ core/java/com/android/internal/os/ZygoteInit.java | 9 ++++++++- .../core/java/com/android/server/pm/Installer.java | 3 +++ .../com/android/server/pm/PackageDexOptimizer.java | 12 +++++++++++- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 664bcbca6aba6..80fc8e3c2f169 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -1455,6 +1455,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } } + /** + * @hide + */ + public boolean isAllowedToUseHiddenApi() { + return isSystemApp(); + } + /** * @hide */ diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 21f1fb6527945..89a70fc0c9a28 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -98,6 +98,10 @@ public class ZygoteInit { private static final String SOCKET_NAME_ARG = "--socket-name="; + /* Dexopt flag to disable hidden API access checks when dexopting SystemServer. + * Must be kept in sync with com.android.server.pm.Installer. */ + private static final int DEXOPT_DISABLE_HIDDEN_API_CHECKS = 1 << 10; + /** * Used to pre-load resources. */ @@ -565,7 +569,10 @@ public class ZygoteInit { if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { final String packageName = "*"; final String outputPath = null; - final int dexFlags = 0; + // Dexopt with a flag which lifts restrictions on hidden API usage. + // Offending methods would otherwise be re-verified at runtime and + // we want to avoid the performance overhead of that. + final int dexFlags = DEXOPT_DISABLE_HIDDEN_API_CHECKS; final String compilerFilter = systemServerFilter; final String uuid = StorageManager.UUID_PRIVATE_INTERNAL; final String seInfo = null; diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 41cfcbe1af881..2cd128d0171e3 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -58,6 +58,9 @@ public class Installer extends SystemService { public static final int DEXOPT_STORAGE_DE = 1 << 8; /** Indicates that dexopt is invoked from the background service. */ public static final int DEXOPT_IDLE_BACKGROUND_JOB = 1 << 9; + /* Indicates that dexopt should not restrict access to private APIs. + * Must be kept in sync with com.android.internal.os.ZygoteInit. */ + public static final int DEXOPT_DISABLE_HIDDEN_API_CHECKS = 1 << 10; // NOTE: keep in sync with installd public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 2cc51599ad169..1f219c14dbecd 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -55,6 +55,7 @@ import static com.android.server.pm.Installer.DEXOPT_FORCE; import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE; import static com.android.server.pm.Installer.DEXOPT_STORAGE_DE; import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB; +import static com.android.server.pm.Installer.DEXOPT_DISABLE_HIDDEN_API_CHECKS; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; @@ -509,12 +510,18 @@ public class PackageDexOptimizer { boolean isProfileGuidedFilter = isProfileGuidedCompilerFilter(compilerFilter); boolean isPublic = !info.isForwardLocked() && !isProfileGuidedFilter; int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0; + // System apps are invoked with a runtime flag which exempts them from + // restrictions on hidden API usage. We dexopt with the same runtime flag + // otherwise offending methods would have to be re-verified at runtime + // and we want to avoid the performance overhead of that. + int hiddenApiFlag = info.isAllowedToUseHiddenApi() ? DEXOPT_DISABLE_HIDDEN_API_CHECKS : 0; int dexFlags = (isPublic ? DEXOPT_PUBLIC : 0) | (debuggable ? DEXOPT_DEBUGGABLE : 0) | profileFlag | (options.isBootComplete() ? DEXOPT_BOOTCOMPLETE : 0) - | (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0); + | (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0) + | hiddenApiFlag; return adjustDexoptFlags(dexFlags); } @@ -629,6 +636,9 @@ public class PackageDexOptimizer { if ((flags & DEXOPT_IDLE_BACKGROUND_JOB) == DEXOPT_IDLE_BACKGROUND_JOB) { flagsList.add("idle_background_job"); } + if ((flags & DEXOPT_DISABLE_HIDDEN_API_CHECKS) == DEXOPT_DISABLE_HIDDEN_API_CHECKS) { + flagsList.add("disable_hidden_api_checks"); + } return String.join(",", flagsList); }