diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/BackgroundDexOptService.java | 186 |
1 files changed, 99 insertions, 87 deletions
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index cec105816b36..2bf5ef10ec89 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -69,7 +69,7 @@ public class BackgroundDexOptService extends JobService { */ final AtomicBoolean mExitPostBootUpdate = new AtomicBoolean(false); - private final File dataDir = Environment.getDataDirectory(); + private final File mDataDir = Environment.getDataDirectory(); public static void schedule(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); @@ -120,7 +120,7 @@ public class BackgroundDexOptService extends JobService { private long getLowStorageThreshold() { @SuppressWarnings("deprecation") - final long lowThreshold = StorageManager.from(this).getStorageLowBytes(dataDir); + final long lowThreshold = StorageManager.from(this).getStorageLowBytes(mDataDir); if (lowThreshold == 0) { Log.e(TAG, "Invalid low storage threshold"); } @@ -134,114 +134,126 @@ public class BackgroundDexOptService extends JobService { // This job has already been superseded. Do not start it. return false; } + new Thread("BackgroundDexOptService_PostBootUpdate") { + @Override + public void run() { + postBootUpdate(jobParams, pm, pkgs); + } + }.start(); + return true; + } + + private void postBootUpdate(JobParameters jobParams, PackageManagerService pm, + ArraySet<String> pkgs) { // Load low battery threshold from the system config. This is a 0-100 integer. final int lowBatteryThreshold = getResources().getInteger( com.android.internal.R.integer.config_lowBatteryWarningLevel); - final long lowThreshold = getLowStorageThreshold(); mAbortPostBootUpdate.set(false); - new Thread("BackgroundDexOptService_PostBootUpdate") { + + for (String pkg : pkgs) { + if (mAbortPostBootUpdate.get()) { + // JobScheduler requested an early abort. + return; + } + if (mExitPostBootUpdate.get()) { + // Different job, which supersedes this one, is running. + break; + } + if (getBatteryLevel() < lowBatteryThreshold) { + // Rather bail than completely drain the battery. + break; + } + long usableSpace = mDataDir.getUsableSpace(); + if (usableSpace < lowThreshold) { + // Rather bail than completely fill up the disk. + Log.w(TAG, "Aborting background dex opt job due to low storage: " + + usableSpace); + break; + } + + if (DEBUG_DEXOPT) { + Log.i(TAG, "Updating package " + pkg); + } + + // Update package if needed. Note that there can be no race between concurrent + // jobs because PackageDexOptimizer.performDexOpt is synchronized. + + // checkProfiles is false to avoid merging profiles during boot which + // might interfere with background compilation (b/28612421). + // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will + // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a + // trade-off worth doing to save boot time work. + pm.performDexOpt(pkg, + /* checkProfiles */ false, + PackageManagerService.REASON_BOOT, + /* force */ false); + } + // Ran to completion, so we abandon our timeslice and do not reschedule. + jobFinished(jobParams, /* reschedule */ false); + } + + private boolean runIdleOptimization(final JobParameters jobParams, + final PackageManagerService pm, final ArraySet<String> pkgs) { + new Thread("BackgroundDexOptService_IdleOptimization") { @Override public void run() { - for (String pkg : pkgs) { - if (mAbortPostBootUpdate.get()) { - // JobScheduler requested an early abort. - return; - } - if (mExitPostBootUpdate.get()) { - // Different job, which supersedes this one, is running. - break; - } - if (getBatteryLevel() < lowBatteryThreshold) { - // Rather bail than completely drain the battery. - break; - } - long usableSpace = dataDir.getUsableSpace(); - if (usableSpace < lowThreshold) { - // Rather bail than completely fill up the disk. - Log.w(TAG, "Aborting background dex opt job due to low storage: " + - usableSpace); - break; - } - - if (DEBUG_DEXOPT) { - Log.i(TAG, "Updating package " + pkg); - } - - // Update package if needed. Note that there can be no race between concurrent - // jobs because PackageDexOptimizer.performDexOpt is synchronized. - - // checkProfiles is false to avoid merging profiles during boot which - // might interfere with background compilation (b/28612421). - // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will - // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a - // trade-off worth doing to save boot time work. - pm.performDexOpt(pkg, - /* checkProfiles */ false, - PackageManagerService.REASON_BOOT, - /* force */ false); - } - // Ran to completion, so we abandon our timeslice and do not reschedule. - jobFinished(jobParams, /* reschedule */ false); + idleOptimization(jobParams, pm, pkgs); } }.start(); return true; } - private boolean runIdleOptimization(final JobParameters jobParams, - final PackageManagerService pm, final ArraySet<String> pkgs) { + private void idleOptimization(JobParameters jobParams, PackageManagerService pm, + ArraySet<String> pkgs) { // If post-boot update is still running, request that it exits early. mExitPostBootUpdate.set(true); mAbortIdleOptimization.set(false); final long lowThreshold = getLowStorageThreshold(); + for (String pkg : pkgs) { + if (mAbortIdleOptimization.get()) { + // JobScheduler requested an early abort. + return; + } - new Thread("BackgroundDexOptService_IdleOptimization") { - @Override - public void run() { - for (String pkg : pkgs) { - if (mAbortIdleOptimization.get()) { - // JobScheduler requested an early abort. - return; - } - if (sFailedPackageNames.contains(pkg)) { - // Skip previously failing package - continue; - } - - long usableSpace = dataDir.getUsableSpace(); - if (usableSpace < lowThreshold) { - // Rather bail than completely fill up the disk. - Log.w(TAG, "Aborting background dex opt job due to low storage: " + - usableSpace); - break; - } - - // Conservatively add package to the list of failing ones in case performDexOpt - // never returns. - synchronized (sFailedPackageNames) { - sFailedPackageNames.add(pkg); - } - // Optimize package if needed. Note that there can be no race between - // concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized. - if (pm.performDexOpt(pkg, - /* checkProfiles */ true, - PackageManagerService.REASON_BACKGROUND_DEXOPT, - /* force */ false)) { - // Dexopt succeeded, remove package from the list of failing ones. - synchronized (sFailedPackageNames) { - sFailedPackageNames.remove(pkg); - } - } + synchronized (sFailedPackageNames) { + if (sFailedPackageNames.contains(pkg)) { + // Skip previously failing package + continue; } - // Ran to completion, so we abandon our timeslice and do not reschedule. - jobFinished(jobParams, /* reschedule */ false); } - }.start(); - return true; + + long usableSpace = mDataDir.getUsableSpace(); + if (usableSpace < lowThreshold) { + // Rather bail than completely fill up the disk. + Log.w(TAG, "Aborting background dex opt job due to low storage: " + + usableSpace); + break; + } + + // Conservatively add package to the list of failing ones in case performDexOpt + // never returns. + synchronized (sFailedPackageNames) { + sFailedPackageNames.add(pkg); + } + // Optimize package if needed. Note that there can be no race between + // concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized. + if (pm.performDexOpt(pkg, + /* checkProfiles */ true, + PackageManagerService.REASON_BACKGROUND_DEXOPT, + /* force */ false)) { + // Dexopt succeeded, remove package from the list of failing ones. + synchronized (sFailedPackageNames) { + sFailedPackageNames.remove(pkg); + } + } + } + // Ran to completion, so we abandon our timeslice and do not reschedule. + jobFinished(jobParams, /* reschedule */ false); } @Override |