Loading services/core/java/com/android/server/pm/Installer.java +55 −5 Original line number Diff line number Diff line Loading @@ -487,9 +487,42 @@ public class Installer extends SystemService { } } public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, /** * Runs dex optimization. * * @param apkPath Path of target APK * @param uid UID of the package * @param pkgName Name of the package * @param instructionSet Target instruction set to run dex optimization. * @param dexoptNeeded Necessary dex optimization for this request. Check * {@link dalvik.system.DexFile#NO_DEXOPT_NEEDED}, * {@link dalvik.system.DexFile#DEX2OAT_FROM_SCRATCH}, * {@link dalvik.system.DexFile#DEX2OAT_FOR_BOOT_IMAGE}, and * {@link dalvik.system.DexFile#DEX2OAT_FOR_FILTER}. * @param outputPath Output path of generated dex optimization. * @param dexFlags Check {@code DEXOPT_*} for allowed flags. * @param compilerFilter Compiler filter like "verify", "speed-profile". Check * {@code art/libartbase/base/compiler_filter.cc} for full list. * @param volumeUuid UUID of the volume where the package data is stored. {@code null} * represents internal storage. * @param classLoaderContext This encodes the class loader chain (class loader type + class * path) in a format compatible to dex2oat. Check * {@code DexoptUtils.processContextForDexLoad} for further details. * @param seInfo Selinux context to set for generated outputs. * @param downgrade If set, allows downgrading {@code compilerFilter}. If downgrading is not * allowed and requested {@code compilerFilter} is considered as downgrade, * the request will be ignored. * @param targetSdkVersion Target SDK version of the package. * @param profileName Name of reference profile file. * @param dexMetadataPath Specifies the location of dex metadata file. * @param compilationReason Specifies the reason for the compilation like "install". * @return {@code true} if {@code dexopt} is completed. {@code false} if it was cancelled. * * @throws InstallerException if {@code dexopt} fails. */ public boolean dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries, String compilerFilter, @Nullable String volumeUuid, @Nullable String classLoaderContext, @Nullable String seInfo, boolean downgrade, int targetSdkVersion, @Nullable String profileName, @Nullable String dexMetadataPath, @Nullable String compilationReason) throws InstallerException { Loading @@ -497,16 +530,33 @@ public class Installer extends SystemService { BlockGuard.getVmPolicy().onPathAccess(apkPath); BlockGuard.getVmPolicy().onPathAccess(outputPath); BlockGuard.getVmPolicy().onPathAccess(dexMetadataPath); if (!checkBeforeRemote()) return; if (!checkBeforeRemote()) return false; try { mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade, return mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, classLoaderContext, seInfo, downgrade, targetSdkVersion, profileName, dexMetadataPath, compilationReason); } catch (Exception e) { throw InstallerException.from(e); } } /** * Enables or disables dex optimization blocking. * * <p> Enabling blocking will also involve cancelling pending dexopt call and killing child * processes forked from installd to run dexopt. The pending dexopt call will return false * when it is cancelled. * * @param block set to true to enable blocking / false to disable blocking. */ public void controlDexOptBlocking(boolean block) { try { mInstalld.controlDexOptBlocking(block); } catch (Exception e) { Slog.w(TAG, "blockDexOpt failed", e); } } /** * Analyzes the ART profiles of the given package, possibly merging the information * into the reference profile. Returns whether or not we should optimize the package Loading services/core/java/com/android/server/pm/OtaDexoptService.java +4 −1 Original line number Diff line number Diff line Loading @@ -288,7 +288,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { * frameworks/native/cmds/installd/otapreopt.cpp. */ @Override public void dexopt(String apkPath, int uid, @Nullable String pkgName, public boolean dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries, @Nullable String seInfo, boolean downgrade, Loading Loading @@ -320,6 +320,9 @@ public class OtaDexoptService extends IOtaDexopt.Stub { encodeParameter(builder, dexoptCompilationReason); commands.add(builder.toString()); // Cancellation cannot happen for OtaDexOpt. Returns true always. return true; } /** Loading services/core/java/com/android/server/pm/PackageDexOptimizer.java +109 −30 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReas import static dalvik.system.DexFile.getSafeModeCompilerFilter; import static dalvik.system.DexFile.isProfileGuidedCompilerFilter; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -79,6 +80,8 @@ import dalvik.system.DexFile; import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Loading @@ -92,16 +95,40 @@ public class PackageDexOptimizer { private static final String TAG = "PackageDexOptimizer"; static final String OAT_DIR_NAME = "oat"; // TODO b/19550105 Remove error codes and use exceptions /** No need to run dexopt and it was skipped */ public static final int DEX_OPT_SKIPPED = 0; /** Dexopt was completed */ public static final int DEX_OPT_PERFORMED = 1; /** * Cancelled while running it. This is not an error case as cancel was requested * from the client. */ public static final int DEX_OPT_CANCELLED = 2; /** Failed to run dexopt */ public static final int DEX_OPT_FAILED = -1; @IntDef(prefix = {"DEX_OPT_"}, value = { DEX_OPT_SKIPPED, DEX_OPT_PERFORMED, DEX_OPT_CANCELLED, DEX_OPT_FAILED, }) @Retention(RetentionPolicy.SOURCE) public @interface DexOptResult { } // One minute over PM WATCHDOG_TIMEOUT private static final long WAKELOCK_TIMEOUT_MS = WATCHDOG_TIMEOUT + 1000 * 60; @GuardedBy("mInstallLock") private final Installer mInstaller; private final Object mInstallLock; /** * This should be accessed only through {@link #getInstallerLI()} with {@link #mInstallLock} * or {@link #getInstallerWithoutLock()} without the lock. Check both methods for further * details on when to use each of them. */ private final Installer mInstaller; @GuardedBy("mInstallLock") private final PowerManager.WakeLock mDexoptWakeLock; private volatile boolean mSystemReady; Loading Loading @@ -144,6 +171,7 @@ public class PackageDexOptimizer { * <p>Calls to {@link com.android.server.pm.Installer#dexopt} on {@link #mInstaller} are * synchronized on {@link #mInstallLock}. */ @DexOptResult int performDexOpt(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] instructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { Loading @@ -169,11 +197,21 @@ public class PackageDexOptimizer { } } /** * Cancels currently running dex optimization. */ void controlDexOptBlocking(boolean block) { // This method should not hold mInstallLock as cancelling should be possible while // the lock is held by other thread running performDexOpt. getInstallerWithoutLock().controlDexOptBlocking(block); } /** * Performs dexopt on all code paths of the given package. * It assumes the install lock is held. */ @GuardedBy("mInstallLock") @DexOptResult private int performDexOptLI(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] targetInstructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { Loading Loading @@ -269,7 +307,6 @@ public class PackageDexOptimizer { profileAnalysisResult, classLoaderContexts[i], dexoptFlags, sharedGid, packageStats, options.isDowngrade(), profileName, dexMetadataPath, options.getCompilationReason()); // OTAPreopt doesn't have stats so don't report in that case. if (packageStats != null) { Trace.traceBegin(Trace.TRACE_TAG_PACKAGE_MANAGER, "dex2oat-metrics"); Loading @@ -293,6 +330,14 @@ public class PackageDexOptimizer { } } // Should stop the operation immediately. if (newResult == DEX_OPT_CANCELLED) { // Even for the cancellation, return failed if has failed. if (result == DEX_OPT_FAILED) { return result; } return newResult; } // The end result is: // - FAILED if any path failed, // - PERFORMED if at least one path needed compilation, Loading @@ -314,6 +359,7 @@ public class PackageDexOptimizer { * DEX_OPT_SKIPPED if the path does not need to be deopt-ed. */ @GuardedBy("mInstallLock") @DexOptResult private int dexOptPath(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String path, String isa, String compilerFilter, int profileAnalysisResult, String classLoaderContext, int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade, Loading @@ -340,12 +386,14 @@ public class PackageDexOptimizer { // installd only uses downgrade flag for secondary dex files and ignores it for // primary dex files. String seInfo = AndroidPackageUtils.getSeInfo(pkg, pkgSetting); mInstaller.dexopt(path, uid, pkg.getPackageName(), isa, dexoptNeeded, oatDir, dexoptFlags, compilerFilter, pkg.getVolumeUuid(), classLoaderContext, seInfo, false /* downgrade*/, pkg.getTargetSdkVersion(), profileName, dexMetadataPath, boolean completed = getInstallerLI().dexopt(path, uid, pkg.getPackageName(), isa, dexoptNeeded, oatDir, dexoptFlags, compilerFilter, pkg.getVolumeUuid(), classLoaderContext, seInfo, /* downgrade= */ false , pkg.getTargetSdkVersion(), profileName, dexMetadataPath, getAugmentedReasonName(compilationReason, dexMetadataPath != null)); if (!completed) { return DEX_OPT_CANCELLED; } if (packageStats != null) { long endTime = System.currentTimeMillis(); packageStats.setCompileTime(path, (int)(endTime - startTime)); Loading @@ -360,6 +408,7 @@ public class PackageDexOptimizer { /** * Perform dexopt (if needed) on a system server code path). */ @DexOptResult public int dexoptSystemServerPath( String dexPath, PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) { int dexoptFlags = DEXOPT_PUBLIC Loading @@ -380,23 +429,28 @@ public class PackageDexOptimizer { continue; } try { mInstaller.dexopt( synchronized (mInstallLock) { boolean completed = getInstallerLI().dexopt( dexPath, android.os.Process.SYSTEM_UID, /* packageName= */ "android", /* pkgName= */ "android", isa, dexoptNeeded, /* oatDir= */ null, /* outputPath= */ null, dexoptFlags, options.getCompilerFilter(), StorageManager.UUID_PRIVATE_INTERNAL, dexUseInfo.getClassLoaderContext(), /* seInfo= */ null, /* downgrade= */ false, /* targetSdk= */ 0, /* profileName */ null, /* dexMetadataPath */ null, /* targetSdkVersion= */ 0, /* profileName= */ null, /* dexMetadataPath= */ null, getReasonName(options.getCompilationReason())); if (!completed) { return DEX_OPT_CANCELLED; } } } catch (InstallerException e) { Slog.w(TAG, "Failed to dexopt", e); return DEX_OPT_FAILED; Loading Loading @@ -426,6 +480,7 @@ public class PackageDexOptimizer { * throwing exceptions). Or maybe make a separate call to installd to get DexOptNeeded, though * that seems wasteful. */ @DexOptResult public int dexOptSecondaryDexPath(ApplicationInfo info, String path, PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) { if (info.uid == -1) { Loading Loading @@ -475,6 +530,7 @@ public class PackageDexOptimizer { } @GuardedBy("mInstallLock") @DexOptResult private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) { if (options.isDexoptOnlySharedDex() && !dexUseInfo.isUsedByOtherApps()) { Loading Loading @@ -523,11 +579,15 @@ public class PackageDexOptimizer { // 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, boolean completed = getInstallerLI().dexopt(path, info.uid, info.packageName, isa, /* dexoptNeeded= */ 0, /* outputPath= */ null, dexoptFlags, compilerFilter, info.volumeUuid, classLoaderContext, info.seInfo, options.isDowngrade(), info.targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null, getReasonName(reason)); options.isDowngrade(), info.targetSdkVersion, /* profileName= */ null, /* dexMetadataPath= */ null, getReasonName(reason)); if (!completed) { return DEX_OPT_CANCELLED; } } return DEX_OPT_PERFORMED; Loading Loading @@ -810,7 +870,9 @@ public class PackageDexOptimizer { } // Merge profiles. It returns whether or not there was an updated in the profile info. try { return mInstaller.mergeProfiles(uid, pkg.getPackageName(), profileName); synchronized (mInstallLock) { return getInstallerLI().mergeProfiles(uid, pkg.getPackageName(), profileName); } } catch (InstallerException e) { Slog.w(TAG, "Failed to merge profiles", e); // We don't need to optimize if we failed to merge. Loading Loading @@ -921,4 +983,21 @@ public class PackageDexOptimizer { return flags | DEXOPT_FORCE; } } /** * Returns {@link #mInstaller} with {@link #mInstallLock}. This should be used for all * {@link #mInstaller} access unless {@link #getInstallerWithoutLock()} is allowed. */ @GuardedBy("mInstallLock") private Installer getInstallerLI() { return mInstaller; } /** * Returns {@link #mInstaller} without lock. This should be used only inside * {@link #controlDexOptBlocking(boolean)}. */ private Installer getInstallerWithoutLock() { return mInstaller; } } services/core/java/com/android/server/pm/PackageManagerService.java +9 −2 Original line number Diff line number Diff line Loading @@ -11032,6 +11032,9 @@ public class PackageManagerService extends IPackageManager.Stub case PackageDexOptimizer.DEX_OPT_SKIPPED: numberOfPackagesSkipped++; break; case PackageDexOptimizer.DEX_OPT_CANCELLED: // ignore this case break; case PackageDexOptimizer.DEX_OPT_FAILED: numberOfPackagesFailed++; break; Loading Loading @@ -11177,12 +11180,18 @@ public class PackageManagerService extends IPackageManager.Stub } } /*package*/ void controlDexOptBlocking(boolean block) { mPackageDexOptimizer.controlDexOptBlocking(block); } /** * Perform dexopt on the given package and return one of following result: * {@link PackageDexOptimizer#DEX_OPT_SKIPPED} * {@link PackageDexOptimizer#DEX_OPT_PERFORMED} * {@link PackageDexOptimizer#DEX_OPT_CANCELLED} * {@link PackageDexOptimizer#DEX_OPT_FAILED} */ @PackageDexOptimizer.DexOptResult /* package */ int performDexOptWithStatus(DexoptOptions options) { return performDexOptTraced(options); } Loading Loading @@ -11307,8 +11316,6 @@ public class PackageManagerService extends IPackageManager.Stub mDexManager.reconcileSecondaryDexFiles(packageName); } // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject // a reference there. /*package*/ DexManager getDexManager() { return mDexManager; } Loading
services/core/java/com/android/server/pm/Installer.java +55 −5 Original line number Diff line number Diff line Loading @@ -487,9 +487,42 @@ public class Installer extends SystemService { } } public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, /** * Runs dex optimization. * * @param apkPath Path of target APK * @param uid UID of the package * @param pkgName Name of the package * @param instructionSet Target instruction set to run dex optimization. * @param dexoptNeeded Necessary dex optimization for this request. Check * {@link dalvik.system.DexFile#NO_DEXOPT_NEEDED}, * {@link dalvik.system.DexFile#DEX2OAT_FROM_SCRATCH}, * {@link dalvik.system.DexFile#DEX2OAT_FOR_BOOT_IMAGE}, and * {@link dalvik.system.DexFile#DEX2OAT_FOR_FILTER}. * @param outputPath Output path of generated dex optimization. * @param dexFlags Check {@code DEXOPT_*} for allowed flags. * @param compilerFilter Compiler filter like "verify", "speed-profile". Check * {@code art/libartbase/base/compiler_filter.cc} for full list. * @param volumeUuid UUID of the volume where the package data is stored. {@code null} * represents internal storage. * @param classLoaderContext This encodes the class loader chain (class loader type + class * path) in a format compatible to dex2oat. Check * {@code DexoptUtils.processContextForDexLoad} for further details. * @param seInfo Selinux context to set for generated outputs. * @param downgrade If set, allows downgrading {@code compilerFilter}. If downgrading is not * allowed and requested {@code compilerFilter} is considered as downgrade, * the request will be ignored. * @param targetSdkVersion Target SDK version of the package. * @param profileName Name of reference profile file. * @param dexMetadataPath Specifies the location of dex metadata file. * @param compilationReason Specifies the reason for the compilation like "install". * @return {@code true} if {@code dexopt} is completed. {@code false} if it was cancelled. * * @throws InstallerException if {@code dexopt} fails. */ public boolean dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries, String compilerFilter, @Nullable String volumeUuid, @Nullable String classLoaderContext, @Nullable String seInfo, boolean downgrade, int targetSdkVersion, @Nullable String profileName, @Nullable String dexMetadataPath, @Nullable String compilationReason) throws InstallerException { Loading @@ -497,16 +530,33 @@ public class Installer extends SystemService { BlockGuard.getVmPolicy().onPathAccess(apkPath); BlockGuard.getVmPolicy().onPathAccess(outputPath); BlockGuard.getVmPolicy().onPathAccess(dexMetadataPath); if (!checkBeforeRemote()) return; if (!checkBeforeRemote()) return false; try { mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade, return mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, classLoaderContext, seInfo, downgrade, targetSdkVersion, profileName, dexMetadataPath, compilationReason); } catch (Exception e) { throw InstallerException.from(e); } } /** * Enables or disables dex optimization blocking. * * <p> Enabling blocking will also involve cancelling pending dexopt call and killing child * processes forked from installd to run dexopt. The pending dexopt call will return false * when it is cancelled. * * @param block set to true to enable blocking / false to disable blocking. */ public void controlDexOptBlocking(boolean block) { try { mInstalld.controlDexOptBlocking(block); } catch (Exception e) { Slog.w(TAG, "blockDexOpt failed", e); } } /** * Analyzes the ART profiles of the given package, possibly merging the information * into the reference profile. Returns whether or not we should optimize the package Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +4 −1 Original line number Diff line number Diff line Loading @@ -288,7 +288,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { * frameworks/native/cmds/installd/otapreopt.cpp. */ @Override public void dexopt(String apkPath, int uid, @Nullable String pkgName, public boolean dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet, int dexoptNeeded, @Nullable String outputPath, int dexFlags, String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries, @Nullable String seInfo, boolean downgrade, Loading Loading @@ -320,6 +320,9 @@ public class OtaDexoptService extends IOtaDexopt.Stub { encodeParameter(builder, dexoptCompilationReason); commands.add(builder.toString()); // Cancellation cannot happen for OtaDexOpt. Returns true always. return true; } /** Loading
services/core/java/com/android/server/pm/PackageDexOptimizer.java +109 −30 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReas import static dalvik.system.DexFile.getSafeModeCompilerFilter; import static dalvik.system.DexFile.isProfileGuidedCompilerFilter; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading Loading @@ -79,6 +80,8 @@ import dalvik.system.DexFile; import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Loading @@ -92,16 +95,40 @@ public class PackageDexOptimizer { private static final String TAG = "PackageDexOptimizer"; static final String OAT_DIR_NAME = "oat"; // TODO b/19550105 Remove error codes and use exceptions /** No need to run dexopt and it was skipped */ public static final int DEX_OPT_SKIPPED = 0; /** Dexopt was completed */ public static final int DEX_OPT_PERFORMED = 1; /** * Cancelled while running it. This is not an error case as cancel was requested * from the client. */ public static final int DEX_OPT_CANCELLED = 2; /** Failed to run dexopt */ public static final int DEX_OPT_FAILED = -1; @IntDef(prefix = {"DEX_OPT_"}, value = { DEX_OPT_SKIPPED, DEX_OPT_PERFORMED, DEX_OPT_CANCELLED, DEX_OPT_FAILED, }) @Retention(RetentionPolicy.SOURCE) public @interface DexOptResult { } // One minute over PM WATCHDOG_TIMEOUT private static final long WAKELOCK_TIMEOUT_MS = WATCHDOG_TIMEOUT + 1000 * 60; @GuardedBy("mInstallLock") private final Installer mInstaller; private final Object mInstallLock; /** * This should be accessed only through {@link #getInstallerLI()} with {@link #mInstallLock} * or {@link #getInstallerWithoutLock()} without the lock. Check both methods for further * details on when to use each of them. */ private final Installer mInstaller; @GuardedBy("mInstallLock") private final PowerManager.WakeLock mDexoptWakeLock; private volatile boolean mSystemReady; Loading Loading @@ -144,6 +171,7 @@ public class PackageDexOptimizer { * <p>Calls to {@link com.android.server.pm.Installer#dexopt} on {@link #mInstaller} are * synchronized on {@link #mInstallLock}. */ @DexOptResult int performDexOpt(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] instructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { Loading @@ -169,11 +197,21 @@ public class PackageDexOptimizer { } } /** * Cancels currently running dex optimization. */ void controlDexOptBlocking(boolean block) { // This method should not hold mInstallLock as cancelling should be possible while // the lock is held by other thread running performDexOpt. getInstallerWithoutLock().controlDexOptBlocking(block); } /** * Performs dexopt on all code paths of the given package. * It assumes the install lock is held. */ @GuardedBy("mInstallLock") @DexOptResult private int performDexOptLI(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] targetInstructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { Loading Loading @@ -269,7 +307,6 @@ public class PackageDexOptimizer { profileAnalysisResult, classLoaderContexts[i], dexoptFlags, sharedGid, packageStats, options.isDowngrade(), profileName, dexMetadataPath, options.getCompilationReason()); // OTAPreopt doesn't have stats so don't report in that case. if (packageStats != null) { Trace.traceBegin(Trace.TRACE_TAG_PACKAGE_MANAGER, "dex2oat-metrics"); Loading @@ -293,6 +330,14 @@ public class PackageDexOptimizer { } } // Should stop the operation immediately. if (newResult == DEX_OPT_CANCELLED) { // Even for the cancellation, return failed if has failed. if (result == DEX_OPT_FAILED) { return result; } return newResult; } // The end result is: // - FAILED if any path failed, // - PERFORMED if at least one path needed compilation, Loading @@ -314,6 +359,7 @@ public class PackageDexOptimizer { * DEX_OPT_SKIPPED if the path does not need to be deopt-ed. */ @GuardedBy("mInstallLock") @DexOptResult private int dexOptPath(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String path, String isa, String compilerFilter, int profileAnalysisResult, String classLoaderContext, int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade, Loading @@ -340,12 +386,14 @@ public class PackageDexOptimizer { // installd only uses downgrade flag for secondary dex files and ignores it for // primary dex files. String seInfo = AndroidPackageUtils.getSeInfo(pkg, pkgSetting); mInstaller.dexopt(path, uid, pkg.getPackageName(), isa, dexoptNeeded, oatDir, dexoptFlags, compilerFilter, pkg.getVolumeUuid(), classLoaderContext, seInfo, false /* downgrade*/, pkg.getTargetSdkVersion(), profileName, dexMetadataPath, boolean completed = getInstallerLI().dexopt(path, uid, pkg.getPackageName(), isa, dexoptNeeded, oatDir, dexoptFlags, compilerFilter, pkg.getVolumeUuid(), classLoaderContext, seInfo, /* downgrade= */ false , pkg.getTargetSdkVersion(), profileName, dexMetadataPath, getAugmentedReasonName(compilationReason, dexMetadataPath != null)); if (!completed) { return DEX_OPT_CANCELLED; } if (packageStats != null) { long endTime = System.currentTimeMillis(); packageStats.setCompileTime(path, (int)(endTime - startTime)); Loading @@ -360,6 +408,7 @@ public class PackageDexOptimizer { /** * Perform dexopt (if needed) on a system server code path). */ @DexOptResult public int dexoptSystemServerPath( String dexPath, PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) { int dexoptFlags = DEXOPT_PUBLIC Loading @@ -380,23 +429,28 @@ public class PackageDexOptimizer { continue; } try { mInstaller.dexopt( synchronized (mInstallLock) { boolean completed = getInstallerLI().dexopt( dexPath, android.os.Process.SYSTEM_UID, /* packageName= */ "android", /* pkgName= */ "android", isa, dexoptNeeded, /* oatDir= */ null, /* outputPath= */ null, dexoptFlags, options.getCompilerFilter(), StorageManager.UUID_PRIVATE_INTERNAL, dexUseInfo.getClassLoaderContext(), /* seInfo= */ null, /* downgrade= */ false, /* targetSdk= */ 0, /* profileName */ null, /* dexMetadataPath */ null, /* targetSdkVersion= */ 0, /* profileName= */ null, /* dexMetadataPath= */ null, getReasonName(options.getCompilationReason())); if (!completed) { return DEX_OPT_CANCELLED; } } } catch (InstallerException e) { Slog.w(TAG, "Failed to dexopt", e); return DEX_OPT_FAILED; Loading Loading @@ -426,6 +480,7 @@ public class PackageDexOptimizer { * throwing exceptions). Or maybe make a separate call to installd to get DexOptNeeded, though * that seems wasteful. */ @DexOptResult public int dexOptSecondaryDexPath(ApplicationInfo info, String path, PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) { if (info.uid == -1) { Loading Loading @@ -475,6 +530,7 @@ public class PackageDexOptimizer { } @GuardedBy("mInstallLock") @DexOptResult private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, PackageDexUsage.DexUseInfo dexUseInfo, DexoptOptions options) { if (options.isDexoptOnlySharedDex() && !dexUseInfo.isUsedByOtherApps()) { Loading Loading @@ -523,11 +579,15 @@ public class PackageDexOptimizer { // 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, boolean completed = getInstallerLI().dexopt(path, info.uid, info.packageName, isa, /* dexoptNeeded= */ 0, /* outputPath= */ null, dexoptFlags, compilerFilter, info.volumeUuid, classLoaderContext, info.seInfo, options.isDowngrade(), info.targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null, getReasonName(reason)); options.isDowngrade(), info.targetSdkVersion, /* profileName= */ null, /* dexMetadataPath= */ null, getReasonName(reason)); if (!completed) { return DEX_OPT_CANCELLED; } } return DEX_OPT_PERFORMED; Loading Loading @@ -810,7 +870,9 @@ public class PackageDexOptimizer { } // Merge profiles. It returns whether or not there was an updated in the profile info. try { return mInstaller.mergeProfiles(uid, pkg.getPackageName(), profileName); synchronized (mInstallLock) { return getInstallerLI().mergeProfiles(uid, pkg.getPackageName(), profileName); } } catch (InstallerException e) { Slog.w(TAG, "Failed to merge profiles", e); // We don't need to optimize if we failed to merge. Loading Loading @@ -921,4 +983,21 @@ public class PackageDexOptimizer { return flags | DEXOPT_FORCE; } } /** * Returns {@link #mInstaller} with {@link #mInstallLock}. This should be used for all * {@link #mInstaller} access unless {@link #getInstallerWithoutLock()} is allowed. */ @GuardedBy("mInstallLock") private Installer getInstallerLI() { return mInstaller; } /** * Returns {@link #mInstaller} without lock. This should be used only inside * {@link #controlDexOptBlocking(boolean)}. */ private Installer getInstallerWithoutLock() { return mInstaller; } }
services/core/java/com/android/server/pm/PackageManagerService.java +9 −2 Original line number Diff line number Diff line Loading @@ -11032,6 +11032,9 @@ public class PackageManagerService extends IPackageManager.Stub case PackageDexOptimizer.DEX_OPT_SKIPPED: numberOfPackagesSkipped++; break; case PackageDexOptimizer.DEX_OPT_CANCELLED: // ignore this case break; case PackageDexOptimizer.DEX_OPT_FAILED: numberOfPackagesFailed++; break; Loading Loading @@ -11177,12 +11180,18 @@ public class PackageManagerService extends IPackageManager.Stub } } /*package*/ void controlDexOptBlocking(boolean block) { mPackageDexOptimizer.controlDexOptBlocking(block); } /** * Perform dexopt on the given package and return one of following result: * {@link PackageDexOptimizer#DEX_OPT_SKIPPED} * {@link PackageDexOptimizer#DEX_OPT_PERFORMED} * {@link PackageDexOptimizer#DEX_OPT_CANCELLED} * {@link PackageDexOptimizer#DEX_OPT_FAILED} */ @PackageDexOptimizer.DexOptResult /* package */ int performDexOptWithStatus(DexoptOptions options) { return performDexOptTraced(options); } Loading Loading @@ -11307,8 +11316,6 @@ public class PackageManagerService extends IPackageManager.Stub mDexManager.reconcileSecondaryDexFiles(packageName); } // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject // a reference there. /*package*/ DexManager getDexManager() { return mDexManager; }