Loading services/core/java/com/android/server/pm/BackgroundDexOptService.java +5 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.Nullable; import android.app.job.JobInfo; Loading Loading @@ -434,7 +435,7 @@ public class BackgroundDexOptService extends JobService { | DexoptOptions.DEXOPT_DOWNGRADE; long package_size_before = getPackageSize(pm, pkg); if (isForPrimaryDex) { if (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) { // This applies for system apps or if packages location is not a directory, i.e. // monolithic install. if (!pm.canHaveOatDir(pkg)) { Loading Loading @@ -486,7 +487,9 @@ public class BackgroundDexOptService extends JobService { | DexoptOptions.DEXOPT_BOOT_COMPLETE | DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB; return isForPrimaryDex // System server share the same code path as primary dex files. // PackageManagerService will select the right optimization path for it. return (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) ? performDexOptPrimary(pm, pkg, reason, dexoptFlags) : performDexOptSecondary(pm, pkg, reason, dexoptFlags); } Loading services/core/java/com/android/server/pm/PackageDexOptimizer.java +8 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ 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.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReasonName; Loading Loading @@ -115,7 +116,9 @@ public class PackageDexOptimizer { static boolean canOptimizePackage(AndroidPackage pkg) { // We do not dexopt a package with no code. if (!pkg.isHasCode()) { // Note that the system package is marked as having no code, however we can // still optimize it via dexoptSystemServerPath. if (!PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName()) && !pkg.isHasCode()) { return false; } Loading @@ -132,6 +135,10 @@ public class PackageDexOptimizer { int performDexOpt(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] instructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { if (PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName())) { throw new IllegalArgumentException("System server dexopting should be done via " + " DexManager and PackageDexOptimizer#dexoptSystemServerPath"); } if (pkg.getUid() == -1) { throw new IllegalArgumentException("Dexopt for " + pkg.getPackageName() + " has invalid uid."); Loading services/core/java/com/android/server/pm/dex/DexManager.java +41 −3 Original line number Diff line number Diff line Loading @@ -79,6 +79,10 @@ public class DexManager { private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST = "pm.dexopt.priv-apps-oob-list"; // System server cannot load executable code outside system partitions. // However it can load verification data - thus we pick the "verify" compiler filter. private static final String SYSTEM_SERVER_COMPILER_FILTER = "verify"; private final Context mContext; // Maps package name to code locations. Loading Loading @@ -443,6 +447,14 @@ public class DexManager { * because they don't need to be compiled).. */ public boolean dexoptSecondaryDex(DexoptOptions options) { if (PLATFORM_PACKAGE_NAME.equals(options.getPackageName())) { // We could easily redirect to #dexoptSystemServer in this case. But there should be // no-one calling this method directly for system server. // As such we prefer to abort in this case. Slog.wtf(TAG, "System server jars should be optimized with dexoptSystemServer"); return false; } PackageDexOptimizer pdo = getPackageDexOptimizer(options); String packageName = options.getPackageName(); PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName); Loading Loading @@ -501,8 +513,17 @@ public class DexManager { return PackageDexOptimizer.DEX_OPT_FAILED; } PackageDexOptimizer pdo = getPackageDexOptimizer(options); String packageName = options.getPackageName(); // Override compiler filter for system server to the expected one. // // We could let the caller do this every time the invoke PackageManagerServer#dexopt. // However, there are a few places were this will need to be done which creates // redundancy and the danger of overlooking the config (and thus generating code that will // waste storage and time). DexoptOptions overriddenOptions = options.overrideCompilerFilter( SYSTEM_SERVER_COMPILER_FILTER); PackageDexOptimizer pdo = getPackageDexOptimizer(overriddenOptions); String packageName = overriddenOptions.getPackageName(); PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName); if (useInfo.getDexUseInfoMap().isEmpty()) { if (DEBUG) { Loading @@ -527,7 +548,7 @@ public class DexManager { continue; } int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, options); int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, overriddenOptions); // The end result is: // - FAILED if any path failed, Loading Loading @@ -600,6 +621,23 @@ public class DexManager { packageName, dexUseInfo.getOwnerUserId()) || updated; continue; } // Special handle system server files. // We don't need an installd call because we have permissions to check if the file // exists. if (PLATFORM_PACKAGE_NAME.equals(packageName)) { if (!Files.exists(Paths.get(dexPath))) { if (DEBUG) { Slog.w(TAG, "A dex file previously loaded by System Server does not exist " + " anymore: " + dexPath); } updated = mPackageDexUsage.removeUserPackage( packageName, dexUseInfo.getOwnerUserId()) || updated; } continue; } // This is a regular application. ApplicationInfo info = pkg.applicationInfo; int flags = 0; if (info.deviceProtectedDataDir != null && Loading services/core/java/com/android/server/pm/dex/DexoptOptions.java +13 −0 Original line number Diff line number Diff line Loading @@ -166,4 +166,17 @@ public final class DexoptOptions { public int getCompilationReason() { return mCompilationReason; } /** * Creates a new set of DexoptOptions which are the same with the exception of the compiler * filter (set to the given value). */ public DexoptOptions overrideCompilerFilter(String newCompilerFilter) { return new DexoptOptions( mPackageName, mCompilationReason, newCompilerFilter, mSplitName, mFlags); } } Loading
services/core/java/com/android/server/pm/BackgroundDexOptService.java +5 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.Nullable; import android.app.job.JobInfo; Loading Loading @@ -434,7 +435,7 @@ public class BackgroundDexOptService extends JobService { | DexoptOptions.DEXOPT_DOWNGRADE; long package_size_before = getPackageSize(pm, pkg); if (isForPrimaryDex) { if (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) { // This applies for system apps or if packages location is not a directory, i.e. // monolithic install. if (!pm.canHaveOatDir(pkg)) { Loading Loading @@ -486,7 +487,9 @@ public class BackgroundDexOptService extends JobService { | DexoptOptions.DEXOPT_BOOT_COMPLETE | DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB; return isForPrimaryDex // System server share the same code path as primary dex files. // PackageManagerService will select the right optimization path for it. return (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) ? performDexOptPrimary(pm, pkg, reason, dexoptFlags) : performDexOptSecondary(pm, pkg, reason, dexoptFlags); } Loading
services/core/java/com/android/server/pm/PackageDexOptimizer.java +8 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ 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.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReasonName; Loading Loading @@ -115,7 +116,9 @@ public class PackageDexOptimizer { static boolean canOptimizePackage(AndroidPackage pkg) { // We do not dexopt a package with no code. if (!pkg.isHasCode()) { // Note that the system package is marked as having no code, however we can // still optimize it via dexoptSystemServerPath. if (!PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName()) && !pkg.isHasCode()) { return false; } Loading @@ -132,6 +135,10 @@ public class PackageDexOptimizer { int performDexOpt(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] instructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { if (PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName())) { throw new IllegalArgumentException("System server dexopting should be done via " + " DexManager and PackageDexOptimizer#dexoptSystemServerPath"); } if (pkg.getUid() == -1) { throw new IllegalArgumentException("Dexopt for " + pkg.getPackageName() + " has invalid uid."); Loading
services/core/java/com/android/server/pm/dex/DexManager.java +41 −3 Original line number Diff line number Diff line Loading @@ -79,6 +79,10 @@ public class DexManager { private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST = "pm.dexopt.priv-apps-oob-list"; // System server cannot load executable code outside system partitions. // However it can load verification data - thus we pick the "verify" compiler filter. private static final String SYSTEM_SERVER_COMPILER_FILTER = "verify"; private final Context mContext; // Maps package name to code locations. Loading Loading @@ -443,6 +447,14 @@ public class DexManager { * because they don't need to be compiled).. */ public boolean dexoptSecondaryDex(DexoptOptions options) { if (PLATFORM_PACKAGE_NAME.equals(options.getPackageName())) { // We could easily redirect to #dexoptSystemServer in this case. But there should be // no-one calling this method directly for system server. // As such we prefer to abort in this case. Slog.wtf(TAG, "System server jars should be optimized with dexoptSystemServer"); return false; } PackageDexOptimizer pdo = getPackageDexOptimizer(options); String packageName = options.getPackageName(); PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName); Loading Loading @@ -501,8 +513,17 @@ public class DexManager { return PackageDexOptimizer.DEX_OPT_FAILED; } PackageDexOptimizer pdo = getPackageDexOptimizer(options); String packageName = options.getPackageName(); // Override compiler filter for system server to the expected one. // // We could let the caller do this every time the invoke PackageManagerServer#dexopt. // However, there are a few places were this will need to be done which creates // redundancy and the danger of overlooking the config (and thus generating code that will // waste storage and time). DexoptOptions overriddenOptions = options.overrideCompilerFilter( SYSTEM_SERVER_COMPILER_FILTER); PackageDexOptimizer pdo = getPackageDexOptimizer(overriddenOptions); String packageName = overriddenOptions.getPackageName(); PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName); if (useInfo.getDexUseInfoMap().isEmpty()) { if (DEBUG) { Loading @@ -527,7 +548,7 @@ public class DexManager { continue; } int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, options); int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, overriddenOptions); // The end result is: // - FAILED if any path failed, Loading Loading @@ -600,6 +621,23 @@ public class DexManager { packageName, dexUseInfo.getOwnerUserId()) || updated; continue; } // Special handle system server files. // We don't need an installd call because we have permissions to check if the file // exists. if (PLATFORM_PACKAGE_NAME.equals(packageName)) { if (!Files.exists(Paths.get(dexPath))) { if (DEBUG) { Slog.w(TAG, "A dex file previously loaded by System Server does not exist " + " anymore: " + dexPath); } updated = mPackageDexUsage.removeUserPackage( packageName, dexUseInfo.getOwnerUserId()) || updated; } continue; } // This is a regular application. ApplicationInfo info = pkg.applicationInfo; int flags = 0; if (info.deviceProtectedDataDir != null && Loading
services/core/java/com/android/server/pm/dex/DexoptOptions.java +13 −0 Original line number Diff line number Diff line Loading @@ -166,4 +166,17 @@ public final class DexoptOptions { public int getCompilationReason() { return mCompilationReason; } /** * Creates a new set of DexoptOptions which are the same with the exception of the compiler * filter (set to the given value). */ public DexoptOptions overrideCompilerFilter(String newCompilerFilter) { return new DexoptOptions( mPackageName, mCompilationReason, newCompilerFilter, mSplitName, mFlags); } }