Loading core/java/android/content/pm/IPackageManager.aidl +11 −0 Original line number Diff line number Diff line Loading @@ -482,6 +482,7 @@ interface IPackageManager { */ boolean performDexOpt(String packageName, boolean checkProfiles, int compileReason, boolean force); /** * Ask the package manager to perform a dex-opt with the given compiler filter. * Loading @@ -491,6 +492,16 @@ interface IPackageManager { boolean performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force); /** * Ask the package manager to perform a dex-opt with the given compiler filter on the * secondary dex files belonging to the given package. * * Note: exposed only for the shell command to allow moving packages explicitly to a * definite state. */ boolean performDexOptSecondary(String packageName, String targetCompilerFilter, boolean force); /** * Ask the package manager to dump profiles associated with a package. */ Loading services/core/java/com/android/server/pm/Installer.java +8 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,14 @@ public class Installer extends SystemService { public static final int DEXOPT_BOOTCOMPLETE = 1 << 4; /** Hint that the dexopt type is profile-guided. */ public static final int DEXOPT_PROFILE_GUIDED = 1 << 5; /** The compilation is for a secondary dex file. */ public static final int DEXOPT_SECONDARY_DEX = 1 << 6; /** Ignore the result of dexoptNeeded and force compilation. */ public static final int DEXOPT_FORCE = 1 << 7; /** Indicates that the dex file passed to dexopt in on CE storage. */ public static final int DEXOPT_STORAGE_CE = 1 << 8; /** Indicates that the dex file passed to dexopt in on DE storage. */ public static final int DEXOPT_STORAGE_DE = 1 << 9; // NOTE: keep in sync with installd public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; Loading services/core/java/com/android/server/pm/PackageDexOptimizer.java +119 −10 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.pm; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageParser; import android.os.Environment; import android.os.PowerManager; Loading @@ -35,6 +36,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import dalvik.system.DexFile; Loading @@ -43,6 +45,10 @@ import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE; import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED; import static com.android.server.pm.Installer.DEXOPT_PUBLIC; import static com.android.server.pm.Installer.DEXOPT_SAFEMODE; import static com.android.server.pm.Installer.DEXOPT_SECONDARY_DEX; 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.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; Loading @@ -52,13 +58,13 @@ import static dalvik.system.DexFile.isProfileGuidedCompilerFilter; /** * Helper class for running dexopt command on packages. */ class PackageDexOptimizer { public class PackageDexOptimizer { private static final String TAG = "PackageManager.DexOptimizer"; static final String OAT_DIR_NAME = "oat"; // TODO b/19550105 Remove error codes and use exceptions static final int DEX_OPT_SKIPPED = 0; static final int DEX_OPT_PERFORMED = 1; static final int DEX_OPT_FAILED = -1; public static final int DEX_OPT_SKIPPED = 0; public static final int DEX_OPT_PERFORMED = 1; public static final int DEX_OPT_FAILED = -1; private final Installer mInstaller; private final Object mInstallLock; Loading Loading @@ -100,6 +106,9 @@ class PackageDexOptimizer { return DEX_OPT_SKIPPED; } synchronized (mInstallLock) { // During boot the system doesn't need to instantiate and obtain a wake lock. // PowerManager might not be ready, but that doesn't mean that we can't proceed with // dexopt. final boolean useLock = mSystemReady; if (useLock) { mDexoptWakeLock.setWorkSource(new WorkSource(pkg.applicationInfo.uid)); Loading Loading @@ -130,9 +139,11 @@ class PackageDexOptimizer { final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final String compilerFilter = getRealCompilerFilter(pkg, targetCompilerFilter); final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, targetCompilerFilter, isUsedByOtherApps(pkg)); final boolean profileUpdated = checkForProfileUpdates && isProfileUpdated(pkg, sharedGid, compilerFilter); // TODO(calin,jeffhao): shared library paths should be adjusted to include previous code // paths (b/34169257). final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries); Loading Loading @@ -200,6 +211,79 @@ class PackageDexOptimizer { } } /** * Performs dexopt on the secondary dex {@code path} belonging to the app {@code info}. * * @return * DEX_OPT_FAILED if there was any exception during dexopt * DEX_OPT_PERFORMED if dexopt was performed successfully on the given path. * NOTE that DEX_OPT_PERFORMED for secondary dex files includes the case when the dex file * didn't need an update. That's because at the moment we don't get more than success/failure * from installd. * * TODO(calin): Consider adding return codes to installd dexopt invocation (rather than * throwing exceptions). Or maybe make a separate call to installd to get DexOptNeeded, though * that seems wasteful. */ public int dexOptSecondaryDexPath(ApplicationInfo info, String path, Set<String> isas, String compilerFilter, boolean isUsedByOtherApps) { synchronized (mInstallLock) { // During boot the system doesn't need to instantiate and obtain a wake lock. // PowerManager might not be ready, but that doesn't mean that we can't proceed with // dexopt. final boolean useLock = mSystemReady; if (useLock) { mDexoptWakeLock.setWorkSource(new WorkSource(info.uid)); mDexoptWakeLock.acquire(); } try { return dexOptSecondaryDexPathLI(info, path, isas, compilerFilter, isUsedByOtherApps); } finally { if (useLock) { mDexoptWakeLock.release(); } } } } @GuardedBy("mInstallLock") private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas, String compilerFilter, boolean isUsedByOtherApps) { int dexoptFlags = getDexFlags(info, compilerFilter) | DEXOPT_SECONDARY_DEX; // Check the app storage and add the appropriate flags. if (info.dataDir.equals(info.deviceProtectedDataDir)) { dexoptFlags |= DEXOPT_STORAGE_DE; } else if (info.dataDir.equals(info.credentialProtectedDataDir)) { dexoptFlags |= DEXOPT_STORAGE_CE; } else { Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName); return DEX_OPT_FAILED; } compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps); Log.d(TAG, "Running dexopt on: " + path + " pkg=" + info.packageName + " isa=" + isas + " dexoptFlags=" + printDexoptFlags(dexoptFlags) + " target-filter=" + compilerFilter); try { for (String isa : isas) { // Reuse the same dexopt path as for the primary apks. We don't need all the // arguments as some (dexopNeeded and oatDir) will be computed by installd because // system server cannot read untrusted app content. // TODO(calin): maybe add a separate call. mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, /*oatDir*/ null, dexoptFlags, compilerFilter, info.volumeUuid, /*sharedLibrariesPath*/ null); } return DEX_OPT_PERFORMED; } catch (InstallerException e) { Slog.w(TAG, "Failed to dexopt", e); return DEX_OPT_FAILED; } } /** * Adjust the given dexopt-needed value. Can be overridden to influence the decision to * optimize or not (and in what way). Loading Loading @@ -246,8 +330,9 @@ class PackageDexOptimizer { * The target filter will be updated if the package code is used by other apps * or if it has the safe mode flag set. */ private String getRealCompilerFilter(PackageParser.Package pkg, String targetCompilerFilter) { int flags = pkg.applicationInfo.flags; private String getRealCompilerFilter(ApplicationInfo info, String targetCompilerFilter, boolean isUsedByOtherApps) { int flags = info.flags; boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0; if (vmSafeMode) { // For the compilation, it doesn't really matter what we return here because installd Loading @@ -259,7 +344,7 @@ class PackageDexOptimizer { return getNonProfileGuidedCompilerFilter(targetCompilerFilter); } if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps(pkg)) { if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps) { // If the dex files is used by other apps, we cannot use profile-guided compilation. return getNonProfileGuidedCompilerFilter(targetCompilerFilter); } Loading @@ -272,12 +357,16 @@ class PackageDexOptimizer { * filter. */ private int getDexFlags(PackageParser.Package pkg, String compilerFilter) { int flags = pkg.applicationInfo.flags; return getDexFlags(pkg.applicationInfo, compilerFilter); } private int getDexFlags(ApplicationInfo info, String compilerFilter) { int flags = info.flags; boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0; boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; // Profile guide compiled oat files should not be public. boolean isProfileGuidedFilter = isProfileGuidedCompilerFilter(compilerFilter); boolean isPublic = !pkg.isForwardLocked() && !isProfileGuidedFilter; boolean isPublic = !info.isForwardLocked() && !isProfileGuidedFilter; int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0; int dexFlags = (isPublic ? DEXOPT_PUBLIC : 0) Loading Loading @@ -437,6 +526,19 @@ class PackageDexOptimizer { if ((flags & DEXOPT_SAFEMODE) == DEXOPT_SAFEMODE) { flagsList.add("safemode"); } if ((flags & DEXOPT_SECONDARY_DEX) == DEXOPT_SECONDARY_DEX) { flagsList.add("secondary"); } if ((flags & DEXOPT_FORCE) == DEXOPT_FORCE) { flagsList.add("force"); } if ((flags & DEXOPT_STORAGE_CE) == DEXOPT_STORAGE_CE) { flagsList.add("storage_ce"); } if ((flags & DEXOPT_STORAGE_DE) == DEXOPT_STORAGE_DE) { flagsList.add("storage_de"); } return String.join(",", flagsList); } Loading @@ -461,5 +563,12 @@ class PackageDexOptimizer { // TODO: The return value is wrong when patchoat is needed. return DexFile.DEX2OAT_FROM_SCRATCH; } @Override protected int adjustDexoptFlags(int flags) { // Add DEXOPT_FORCE flag to signal installd that it should force compilation // and discard dexoptanalyzer result. return flags | DEXOPT_FORCE; } } } services/core/java/com/android/server/pm/PackageManagerService.java +10 −1 Original line number Diff line number Diff line Loading @@ -2133,7 +2133,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstaller = installer; mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, "*dexopt*"); mDexManager = new DexManager(); mDexManager = new DexManager(this, mPackageDexOptimizer); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( Loading Loading @@ -7540,6 +7540,15 @@ public class PackageManagerService extends IPackageManager.Stub { targetCompilerFilter, getOrCreateCompilerPackageStats(p)); } // Performs dexopt on the used secondary dex files belonging to the given package. // Returns true if all dex files were process successfully (which could mean either dexopt or // skip). Returns false if any of the files caused errors. @Override public boolean performDexOptSecondary(String packageName, String compilerFilter, boolean force) { return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); } Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { if (p.usesLibraries != null || p.usesOptionalLibraries != null) { ArrayList<PackageParser.Package> retValue = new ArrayList<>(); Loading services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java +1 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import dalvik.system.DexFile; /** * Manage (retrieve) mappings from compilation reason to compilation filter. */ class PackageManagerServiceCompilerMapping { public class PackageManagerServiceCompilerMapping { // Names for compilation reasons. static final String REASON_STRINGS[] = { "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk", Loading Loading
core/java/android/content/pm/IPackageManager.aidl +11 −0 Original line number Diff line number Diff line Loading @@ -482,6 +482,7 @@ interface IPackageManager { */ boolean performDexOpt(String packageName, boolean checkProfiles, int compileReason, boolean force); /** * Ask the package manager to perform a dex-opt with the given compiler filter. * Loading @@ -491,6 +492,16 @@ interface IPackageManager { boolean performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force); /** * Ask the package manager to perform a dex-opt with the given compiler filter on the * secondary dex files belonging to the given package. * * Note: exposed only for the shell command to allow moving packages explicitly to a * definite state. */ boolean performDexOptSecondary(String packageName, String targetCompilerFilter, boolean force); /** * Ask the package manager to dump profiles associated with a package. */ Loading
services/core/java/com/android/server/pm/Installer.java +8 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,14 @@ public class Installer extends SystemService { public static final int DEXOPT_BOOTCOMPLETE = 1 << 4; /** Hint that the dexopt type is profile-guided. */ public static final int DEXOPT_PROFILE_GUIDED = 1 << 5; /** The compilation is for a secondary dex file. */ public static final int DEXOPT_SECONDARY_DEX = 1 << 6; /** Ignore the result of dexoptNeeded and force compilation. */ public static final int DEXOPT_FORCE = 1 << 7; /** Indicates that the dex file passed to dexopt in on CE storage. */ public static final int DEXOPT_STORAGE_CE = 1 << 8; /** Indicates that the dex file passed to dexopt in on DE storage. */ public static final int DEXOPT_STORAGE_DE = 1 << 9; // NOTE: keep in sync with installd public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8; Loading
services/core/java/com/android/server/pm/PackageDexOptimizer.java +119 −10 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.pm; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageParser; import android.os.Environment; import android.os.PowerManager; Loading @@ -35,6 +36,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import dalvik.system.DexFile; Loading @@ -43,6 +45,10 @@ import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE; import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED; import static com.android.server.pm.Installer.DEXOPT_PUBLIC; import static com.android.server.pm.Installer.DEXOPT_SAFEMODE; import static com.android.server.pm.Installer.DEXOPT_SECONDARY_DEX; 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.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; Loading @@ -52,13 +58,13 @@ import static dalvik.system.DexFile.isProfileGuidedCompilerFilter; /** * Helper class for running dexopt command on packages. */ class PackageDexOptimizer { public class PackageDexOptimizer { private static final String TAG = "PackageManager.DexOptimizer"; static final String OAT_DIR_NAME = "oat"; // TODO b/19550105 Remove error codes and use exceptions static final int DEX_OPT_SKIPPED = 0; static final int DEX_OPT_PERFORMED = 1; static final int DEX_OPT_FAILED = -1; public static final int DEX_OPT_SKIPPED = 0; public static final int DEX_OPT_PERFORMED = 1; public static final int DEX_OPT_FAILED = -1; private final Installer mInstaller; private final Object mInstallLock; Loading Loading @@ -100,6 +106,9 @@ class PackageDexOptimizer { return DEX_OPT_SKIPPED; } synchronized (mInstallLock) { // During boot the system doesn't need to instantiate and obtain a wake lock. // PowerManager might not be ready, but that doesn't mean that we can't proceed with // dexopt. final boolean useLock = mSystemReady; if (useLock) { mDexoptWakeLock.setWorkSource(new WorkSource(pkg.applicationInfo.uid)); Loading Loading @@ -130,9 +139,11 @@ class PackageDexOptimizer { final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final String compilerFilter = getRealCompilerFilter(pkg, targetCompilerFilter); final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo, targetCompilerFilter, isUsedByOtherApps(pkg)); final boolean profileUpdated = checkForProfileUpdates && isProfileUpdated(pkg, sharedGid, compilerFilter); // TODO(calin,jeffhao): shared library paths should be adjusted to include previous code // paths (b/34169257). final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries); Loading Loading @@ -200,6 +211,79 @@ class PackageDexOptimizer { } } /** * Performs dexopt on the secondary dex {@code path} belonging to the app {@code info}. * * @return * DEX_OPT_FAILED if there was any exception during dexopt * DEX_OPT_PERFORMED if dexopt was performed successfully on the given path. * NOTE that DEX_OPT_PERFORMED for secondary dex files includes the case when the dex file * didn't need an update. That's because at the moment we don't get more than success/failure * from installd. * * TODO(calin): Consider adding return codes to installd dexopt invocation (rather than * throwing exceptions). Or maybe make a separate call to installd to get DexOptNeeded, though * that seems wasteful. */ public int dexOptSecondaryDexPath(ApplicationInfo info, String path, Set<String> isas, String compilerFilter, boolean isUsedByOtherApps) { synchronized (mInstallLock) { // During boot the system doesn't need to instantiate and obtain a wake lock. // PowerManager might not be ready, but that doesn't mean that we can't proceed with // dexopt. final boolean useLock = mSystemReady; if (useLock) { mDexoptWakeLock.setWorkSource(new WorkSource(info.uid)); mDexoptWakeLock.acquire(); } try { return dexOptSecondaryDexPathLI(info, path, isas, compilerFilter, isUsedByOtherApps); } finally { if (useLock) { mDexoptWakeLock.release(); } } } } @GuardedBy("mInstallLock") private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas, String compilerFilter, boolean isUsedByOtherApps) { int dexoptFlags = getDexFlags(info, compilerFilter) | DEXOPT_SECONDARY_DEX; // Check the app storage and add the appropriate flags. if (info.dataDir.equals(info.deviceProtectedDataDir)) { dexoptFlags |= DEXOPT_STORAGE_DE; } else if (info.dataDir.equals(info.credentialProtectedDataDir)) { dexoptFlags |= DEXOPT_STORAGE_CE; } else { Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName); return DEX_OPT_FAILED; } compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps); Log.d(TAG, "Running dexopt on: " + path + " pkg=" + info.packageName + " isa=" + isas + " dexoptFlags=" + printDexoptFlags(dexoptFlags) + " target-filter=" + compilerFilter); try { for (String isa : isas) { // Reuse the same dexopt path as for the primary apks. We don't need all the // arguments as some (dexopNeeded and oatDir) will be computed by installd because // system server cannot read untrusted app content. // TODO(calin): maybe add a separate call. mInstaller.dexopt(path, info.uid, info.packageName, isa, /*dexoptNeeded*/ 0, /*oatDir*/ null, dexoptFlags, compilerFilter, info.volumeUuid, /*sharedLibrariesPath*/ null); } return DEX_OPT_PERFORMED; } catch (InstallerException e) { Slog.w(TAG, "Failed to dexopt", e); return DEX_OPT_FAILED; } } /** * Adjust the given dexopt-needed value. Can be overridden to influence the decision to * optimize or not (and in what way). Loading Loading @@ -246,8 +330,9 @@ class PackageDexOptimizer { * The target filter will be updated if the package code is used by other apps * or if it has the safe mode flag set. */ private String getRealCompilerFilter(PackageParser.Package pkg, String targetCompilerFilter) { int flags = pkg.applicationInfo.flags; private String getRealCompilerFilter(ApplicationInfo info, String targetCompilerFilter, boolean isUsedByOtherApps) { int flags = info.flags; boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0; if (vmSafeMode) { // For the compilation, it doesn't really matter what we return here because installd Loading @@ -259,7 +344,7 @@ class PackageDexOptimizer { return getNonProfileGuidedCompilerFilter(targetCompilerFilter); } if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps(pkg)) { if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps) { // If the dex files is used by other apps, we cannot use profile-guided compilation. return getNonProfileGuidedCompilerFilter(targetCompilerFilter); } Loading @@ -272,12 +357,16 @@ class PackageDexOptimizer { * filter. */ private int getDexFlags(PackageParser.Package pkg, String compilerFilter) { int flags = pkg.applicationInfo.flags; return getDexFlags(pkg.applicationInfo, compilerFilter); } private int getDexFlags(ApplicationInfo info, String compilerFilter) { int flags = info.flags; boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0; boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; // Profile guide compiled oat files should not be public. boolean isProfileGuidedFilter = isProfileGuidedCompilerFilter(compilerFilter); boolean isPublic = !pkg.isForwardLocked() && !isProfileGuidedFilter; boolean isPublic = !info.isForwardLocked() && !isProfileGuidedFilter; int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0; int dexFlags = (isPublic ? DEXOPT_PUBLIC : 0) Loading Loading @@ -437,6 +526,19 @@ class PackageDexOptimizer { if ((flags & DEXOPT_SAFEMODE) == DEXOPT_SAFEMODE) { flagsList.add("safemode"); } if ((flags & DEXOPT_SECONDARY_DEX) == DEXOPT_SECONDARY_DEX) { flagsList.add("secondary"); } if ((flags & DEXOPT_FORCE) == DEXOPT_FORCE) { flagsList.add("force"); } if ((flags & DEXOPT_STORAGE_CE) == DEXOPT_STORAGE_CE) { flagsList.add("storage_ce"); } if ((flags & DEXOPT_STORAGE_DE) == DEXOPT_STORAGE_DE) { flagsList.add("storage_de"); } return String.join(",", flagsList); } Loading @@ -461,5 +563,12 @@ class PackageDexOptimizer { // TODO: The return value is wrong when patchoat is needed. return DexFile.DEX2OAT_FROM_SCRATCH; } @Override protected int adjustDexoptFlags(int flags) { // Add DEXOPT_FORCE flag to signal installd that it should force compilation // and discard dexoptanalyzer result. return flags | DEXOPT_FORCE; } } }
services/core/java/com/android/server/pm/PackageManagerService.java +10 −1 Original line number Diff line number Diff line Loading @@ -2133,7 +2133,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstaller = installer; mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, "*dexopt*"); mDexManager = new DexManager(); mDexManager = new DexManager(this, mPackageDexOptimizer); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mOnPermissionChangeListeners = new OnPermissionChangeListeners( Loading Loading @@ -7540,6 +7540,15 @@ public class PackageManagerService extends IPackageManager.Stub { targetCompilerFilter, getOrCreateCompilerPackageStats(p)); } // Performs dexopt on the used secondary dex files belonging to the given package. // Returns true if all dex files were process successfully (which could mean either dexopt or // skip). Returns false if any of the files caused errors. @Override public boolean performDexOptSecondary(String packageName, String compilerFilter, boolean force) { return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); } Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { if (p.usesLibraries != null || p.usesOptionalLibraries != null) { ArrayList<PackageParser.Package> retValue = new ArrayList<>(); Loading
services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java +1 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import dalvik.system.DexFile; /** * Manage (retrieve) mappings from compilation reason to compilation filter. */ class PackageManagerServiceCompilerMapping { public class PackageManagerServiceCompilerMapping { // Names for compilation reasons. static final String REASON_STRINGS[] = { "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk", Loading