Loading core/java/android/content/pm/IPackageManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -513,7 +513,7 @@ interface IPackageManager { * configuration. */ boolean performDexOpt(String packageName, boolean checkProfiles, int compileReason, boolean force, boolean bootComplete); int compileReason, boolean force, boolean bootComplete, boolean downgrade); /** * Ask the package manager to perform a dex-opt with the given compiler filter. Loading core/java/com/android/internal/os/ZygoteInit.java +1 −1 Original line number Diff line number Diff line Loading @@ -577,7 +577,7 @@ public class ZygoteInit { try { installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, uuid, sharedLibraries, seInfo); uuid, sharedLibraries, seInfo, false /* downgrade */); } catch (RemoteException | ServiceSpecificException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " Loading services/core/java/com/android/server/pm/BackgroundDexOptService.java +74 −12 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.pm; import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT; import android.app.AlarmManager; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; Loading @@ -40,6 +39,7 @@ import com.android.server.LocalServices; import com.android.server.PinnerService; import java.io.File; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.TimeUnit; Loading Loading @@ -73,6 +73,9 @@ public class BackgroundDexOptService extends JobService { // Optimizations should be aborted. No space left on device. private static final int OPTIMIZE_ABORT_NO_SPACE_LEFT = 3; // Used for calculating space threshold for downgrading unused apps. private static final int LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE = 2; /** * Set of failed packages remembered across job runs. */ Loading @@ -92,6 +95,9 @@ public class BackgroundDexOptService extends JobService { private final File mDataDir = Environment.getDataDirectory(); private static final long mDowngradeUnusedAppsThresholdInMillis = getDowngradeUnusedAppsThresholdInMillis(); public static void schedule(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); Loading Loading @@ -215,7 +221,8 @@ public class BackgroundDexOptService extends JobService { /* checkProfiles */ false, PackageManagerService.REASON_BOOT, /* force */ false, /* bootComplete */ true); /* bootComplete */ true, /* downgrade */ false); if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) { updatedPackages.add(pkg); } Loading Loading @@ -243,7 +250,8 @@ public class BackgroundDexOptService extends JobService { } // Optimize the given packages and return the optimization result (one of the OPTIMIZE_* codes). private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs, Context context) { private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs, Context context) { Log.i(TAG, "Performing idle optimizations"); // If post-boot update is still running, request that it exits early. mExitPostBootUpdate.set(true); Loading Loading @@ -274,9 +282,16 @@ public class BackgroundDexOptService extends JobService { long lowStorageThreshold, boolean is_for_primary_dex, ArraySet<String> failedPackageNames) { ArraySet<String> updatedPackages = new ArraySet<>(); Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis); // Only downgrade apps when space is low on device. // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean // up disk before user hits the actual lowStorageThreshold. final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE * lowStorageThreshold; boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade); for (String pkg : pkgs) { int abort_code = abortIdleOptimizations(lowStorageThreshold); if (abort_code != OPTIMIZE_CONTINUE) { if (abort_code == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) { return abort_code; } Loading @@ -284,11 +299,36 @@ public class BackgroundDexOptService extends JobService { if (failedPackageNames.contains(pkg)) { // Skip previously failing package continue; } } int reason; boolean downgrade; // Downgrade unused packages. if (unusedPackages.contains(pkg) && shouldDowngrade) { // This applies for system apps or if packages location is not a directory, i.e. // monolithic install. if (is_for_primary_dex && !pm.canHaveOatDir(pkg)) { // For apps that don't have the oat directory, instead of downgrading, // remove their compiler artifacts from dalvik cache. pm.deleteOatArtifactsOfPackage(pkg); continue; } else { // Conservatively add package to the list of failing ones in case performDexOpt // never returns. failedPackageNames.add(pkg); reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE; downgrade = true; } } else if (abort_code != OPTIMIZE_ABORT_NO_SPACE_LEFT) { reason = PackageManagerService.REASON_BACKGROUND_DEXOPT; downgrade = false; } else { // can't dexopt because of low space. continue; } synchronized (failedPackageNames) { // Conservatively add package to the list of failing ones in case // performDexOpt never returns. failedPackageNames.add(pkg); } // Optimize package if needed. Note that there can be no race between Loading @@ -297,17 +337,19 @@ public class BackgroundDexOptService extends JobService { if (is_for_primary_dex) { int result = pm.performDexOptWithStatus(pkg, /* checkProfiles */ true, PackageManagerService.REASON_BACKGROUND_DEXOPT, /* force */ false, /* bootComplete */ true); reason, false /* forceCompile*/, true /* bootComplete */, downgrade); success = result != PackageDexOptimizer.DEX_OPT_FAILED; if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) { updatedPackages.add(pkg); } } else { success = pm.performDexOptSecondary(pkg, PackageManagerService.REASON_BACKGROUND_DEXOPT, /* force */ false); reason, false /* force */, downgrade); } if (success) { // Dexopt succeeded, remove package from the list of failing ones. Loading Loading @@ -347,6 +389,16 @@ public class BackgroundDexOptService extends JobService { return OPTIMIZE_CONTINUE; } // Evaluate whether apps should be downgraded. private boolean shouldDowngrade(long lowStorageThresholdForDowngrade) { long usableSpace = mDataDir.getUsableSpace(); if (usableSpace < lowStorageThresholdForDowngrade) { return true; } return false; } /** * Execute the idle optimizations immediately. */ Loading Loading @@ -415,4 +467,14 @@ public class BackgroundDexOptService extends JobService { pinnerService.update(updatedPackages); } } private static long getDowngradeUnusedAppsThresholdInMillis() { final String sysPropKey = "pm.dexopt.downgrade_after_inactive_days"; String sysPropValue = SystemProperties.get(sysPropKey); if (sysPropValue == null || sysPropValue.isEmpty()) { Log.w(TAG, "SysProp " + sysPropKey + " not set"); return Long.MAX_VALUE; } return TimeUnit.DAYS.toMillis(Long.parseLong(sysPropValue)); } } services/core/java/com/android/server/pm/Installer.java +2 −2 Original line number Diff line number Diff line Loading @@ -279,13 +279,13 @@ public class Installer extends SystemService { public void 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) @Nullable String seInfo, boolean downgrade) throws InstallerException { assertValidInstructionSet(instructionSet); if (!checkBeforeRemote()) return; try { mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo); dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade); } catch (Exception e) { throw InstallerException.from(e); } Loading services/core/java/com/android/server/pm/OtaDexoptService.java +9 −7 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.ShellCallback; import android.os.storage.StorageManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; Loading @@ -40,7 +39,6 @@ import com.android.server.pm.Installer.InstallerException; import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; Loading Loading @@ -261,11 +259,12 @@ public class OtaDexoptService extends IOtaDexopt.Stub { public void 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) throws InstallerException { @Nullable String sharedLibraries, @Nullable String seInfo, boolean downgrade) throws InstallerException { final StringBuilder builder = new StringBuilder(); // The version. Right now it's 2. builder.append("2 "); // The version. Right now it's 3. builder.append("3 "); builder.append("dexopt"); Loading @@ -280,6 +279,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { encodeParameter(builder, volumeUuid); encodeParameter(builder, sharedLibraries); encodeParameter(builder, seInfo); encodeParameter(builder, downgrade); commands.add(builder.toString()); } Loading Loading @@ -319,12 +319,14 @@ public class OtaDexoptService extends IOtaDexopt.Stub { getCompilerFilterForReason(compilationReason), null /* CompilerStats.PackageStats */, mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), true /* bootComplete */); true /* bootComplete */, false /* downgrade */); mPackageManagerService.getDexManager().dexoptSecondaryDex(pkg.packageName, getCompilerFilterForReason(compilationReason), false /* force */, false /* compileOnlySharedDex */); false /* compileOnlySharedDex */, false /* downgrade */); return commands; } Loading Loading
core/java/android/content/pm/IPackageManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -513,7 +513,7 @@ interface IPackageManager { * configuration. */ boolean performDexOpt(String packageName, boolean checkProfiles, int compileReason, boolean force, boolean bootComplete); int compileReason, boolean force, boolean bootComplete, boolean downgrade); /** * Ask the package manager to perform a dex-opt with the given compiler filter. Loading
core/java/com/android/internal/os/ZygoteInit.java +1 −1 Original line number Diff line number Diff line Loading @@ -577,7 +577,7 @@ public class ZygoteInit { try { installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, uuid, sharedLibraries, seInfo); uuid, sharedLibraries, seInfo, false /* downgrade */); } catch (RemoteException | ServiceSpecificException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " Loading
services/core/java/com/android/server/pm/BackgroundDexOptService.java +74 −12 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.pm; import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT; import android.app.AlarmManager; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; Loading @@ -40,6 +39,7 @@ import com.android.server.LocalServices; import com.android.server.PinnerService; import java.io.File; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.TimeUnit; Loading Loading @@ -73,6 +73,9 @@ public class BackgroundDexOptService extends JobService { // Optimizations should be aborted. No space left on device. private static final int OPTIMIZE_ABORT_NO_SPACE_LEFT = 3; // Used for calculating space threshold for downgrading unused apps. private static final int LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE = 2; /** * Set of failed packages remembered across job runs. */ Loading @@ -92,6 +95,9 @@ public class BackgroundDexOptService extends JobService { private final File mDataDir = Environment.getDataDirectory(); private static final long mDowngradeUnusedAppsThresholdInMillis = getDowngradeUnusedAppsThresholdInMillis(); public static void schedule(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); Loading Loading @@ -215,7 +221,8 @@ public class BackgroundDexOptService extends JobService { /* checkProfiles */ false, PackageManagerService.REASON_BOOT, /* force */ false, /* bootComplete */ true); /* bootComplete */ true, /* downgrade */ false); if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) { updatedPackages.add(pkg); } Loading Loading @@ -243,7 +250,8 @@ public class BackgroundDexOptService extends JobService { } // Optimize the given packages and return the optimization result (one of the OPTIMIZE_* codes). private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs, Context context) { private int idleOptimization(PackageManagerService pm, ArraySet<String> pkgs, Context context) { Log.i(TAG, "Performing idle optimizations"); // If post-boot update is still running, request that it exits early. mExitPostBootUpdate.set(true); Loading Loading @@ -274,9 +282,16 @@ public class BackgroundDexOptService extends JobService { long lowStorageThreshold, boolean is_for_primary_dex, ArraySet<String> failedPackageNames) { ArraySet<String> updatedPackages = new ArraySet<>(); Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis); // Only downgrade apps when space is low on device. // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean // up disk before user hits the actual lowStorageThreshold. final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE * lowStorageThreshold; boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade); for (String pkg : pkgs) { int abort_code = abortIdleOptimizations(lowStorageThreshold); if (abort_code != OPTIMIZE_CONTINUE) { if (abort_code == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) { return abort_code; } Loading @@ -284,11 +299,36 @@ public class BackgroundDexOptService extends JobService { if (failedPackageNames.contains(pkg)) { // Skip previously failing package continue; } } int reason; boolean downgrade; // Downgrade unused packages. if (unusedPackages.contains(pkg) && shouldDowngrade) { // This applies for system apps or if packages location is not a directory, i.e. // monolithic install. if (is_for_primary_dex && !pm.canHaveOatDir(pkg)) { // For apps that don't have the oat directory, instead of downgrading, // remove their compiler artifacts from dalvik cache. pm.deleteOatArtifactsOfPackage(pkg); continue; } else { // Conservatively add package to the list of failing ones in case performDexOpt // never returns. failedPackageNames.add(pkg); reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE; downgrade = true; } } else if (abort_code != OPTIMIZE_ABORT_NO_SPACE_LEFT) { reason = PackageManagerService.REASON_BACKGROUND_DEXOPT; downgrade = false; } else { // can't dexopt because of low space. continue; } synchronized (failedPackageNames) { // Conservatively add package to the list of failing ones in case // performDexOpt never returns. failedPackageNames.add(pkg); } // Optimize package if needed. Note that there can be no race between Loading @@ -297,17 +337,19 @@ public class BackgroundDexOptService extends JobService { if (is_for_primary_dex) { int result = pm.performDexOptWithStatus(pkg, /* checkProfiles */ true, PackageManagerService.REASON_BACKGROUND_DEXOPT, /* force */ false, /* bootComplete */ true); reason, false /* forceCompile*/, true /* bootComplete */, downgrade); success = result != PackageDexOptimizer.DEX_OPT_FAILED; if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) { updatedPackages.add(pkg); } } else { success = pm.performDexOptSecondary(pkg, PackageManagerService.REASON_BACKGROUND_DEXOPT, /* force */ false); reason, false /* force */, downgrade); } if (success) { // Dexopt succeeded, remove package from the list of failing ones. Loading Loading @@ -347,6 +389,16 @@ public class BackgroundDexOptService extends JobService { return OPTIMIZE_CONTINUE; } // Evaluate whether apps should be downgraded. private boolean shouldDowngrade(long lowStorageThresholdForDowngrade) { long usableSpace = mDataDir.getUsableSpace(); if (usableSpace < lowStorageThresholdForDowngrade) { return true; } return false; } /** * Execute the idle optimizations immediately. */ Loading Loading @@ -415,4 +467,14 @@ public class BackgroundDexOptService extends JobService { pinnerService.update(updatedPackages); } } private static long getDowngradeUnusedAppsThresholdInMillis() { final String sysPropKey = "pm.dexopt.downgrade_after_inactive_days"; String sysPropValue = SystemProperties.get(sysPropKey); if (sysPropValue == null || sysPropValue.isEmpty()) { Log.w(TAG, "SysProp " + sysPropKey + " not set"); return Long.MAX_VALUE; } return TimeUnit.DAYS.toMillis(Long.parseLong(sysPropValue)); } }
services/core/java/com/android/server/pm/Installer.java +2 −2 Original line number Diff line number Diff line Loading @@ -279,13 +279,13 @@ public class Installer extends SystemService { public void 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) @Nullable String seInfo, boolean downgrade) throws InstallerException { assertValidInstructionSet(instructionSet); if (!checkBeforeRemote()) return; try { mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo); dexFlags, compilerFilter, volumeUuid, sharedLibraries, seInfo, downgrade); } catch (Exception e) { throw InstallerException.from(e); } Loading
services/core/java/com/android/server/pm/OtaDexoptService.java +9 −7 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.ShellCallback; import android.os.storage.StorageManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; Loading @@ -40,7 +39,6 @@ import com.android.server.pm.Installer.InstallerException; import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; Loading Loading @@ -261,11 +259,12 @@ public class OtaDexoptService extends IOtaDexopt.Stub { public void 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) throws InstallerException { @Nullable String sharedLibraries, @Nullable String seInfo, boolean downgrade) throws InstallerException { final StringBuilder builder = new StringBuilder(); // The version. Right now it's 2. builder.append("2 "); // The version. Right now it's 3. builder.append("3 "); builder.append("dexopt"); Loading @@ -280,6 +279,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { encodeParameter(builder, volumeUuid); encodeParameter(builder, sharedLibraries); encodeParameter(builder, seInfo); encodeParameter(builder, downgrade); commands.add(builder.toString()); } Loading Loading @@ -319,12 +319,14 @@ public class OtaDexoptService extends IOtaDexopt.Stub { getCompilerFilterForReason(compilationReason), null /* CompilerStats.PackageStats */, mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), true /* bootComplete */); true /* bootComplete */, false /* downgrade */); mPackageManagerService.getDexManager().dexoptSecondaryDex(pkg.packageName, getCompilerFilterForReason(compilationReason), false /* force */, false /* compileOnlySharedDex */); false /* compileOnlySharedDex */, false /* downgrade */); return commands; } Loading