A bit more refactoring in BackgroundDexOptService
Extract convenient methods to help with:
- adding a shell command to run the background dexopt job
- extending idleOptimizations to cover secondary dex files
Test: device boots, background job run.
Bug: 32871170
(cherry picked from commit c660475aaf)
Change-Id: I146e4faeea90f2d58144a5dba26ae7f90a36b402
Merged-In: I18fde62a1cb05c030a620722d5f217589beaefb1
This commit is contained in:
@@ -124,9 +124,9 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
return (100 * level / scale);
|
return (100 * level / scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getLowStorageThreshold() {
|
private long getLowStorageThreshold(Context context) {
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
final long lowThreshold = StorageManager.from(this).getStorageLowBytes(mDataDir);
|
final long lowThreshold = StorageManager.from(context).getStorageLowBytes(mDataDir);
|
||||||
if (lowThreshold == 0) {
|
if (lowThreshold == 0) {
|
||||||
Log.e(TAG, "Invalid low storage threshold");
|
Log.e(TAG, "Invalid low storage threshold");
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
// Load low battery threshold from the system config. This is a 0-100 integer.
|
// Load low battery threshold from the system config. This is a 0-100 integer.
|
||||||
final int lowBatteryThreshold = getResources().getInteger(
|
final int lowBatteryThreshold = getResources().getInteger(
|
||||||
com.android.internal.R.integer.config_lowBatteryWarningLevel);
|
com.android.internal.R.integer.config_lowBatteryWarningLevel);
|
||||||
final long lowThreshold = getLowStorageThreshold();
|
final long lowThreshold = getLowStorageThreshold(this);
|
||||||
|
|
||||||
mAbortPostBootUpdate.set(false);
|
mAbortPostBootUpdate.set(false);
|
||||||
|
|
||||||
@@ -206,47 +206,48 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
new Thread("BackgroundDexOptService_IdleOptimization") {
|
new Thread("BackgroundDexOptService_IdleOptimization") {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
idleOptimization(jobParams, pm, pkgs);
|
idleOptimization(pm, pkgs, BackgroundDexOptService.this);
|
||||||
|
if (!mAbortIdleOptimization.get()) {
|
||||||
|
// If we didn't abort we ran to completion (or stopped because of space).
|
||||||
|
// Abandon our timeslice and do not reschedule.
|
||||||
|
jobFinished(jobParams, /* reschedule */ false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void idleOptimization(JobParameters jobParams, PackageManagerService pm,
|
// Optimize the given packages and return true if the process was not aborted.
|
||||||
ArraySet<String> pkgs) {
|
// The abort can happen either because of job scheduler or because of lack of space.
|
||||||
|
private boolean idleOptimization(PackageManagerService pm, ArraySet<String> pkgs,
|
||||||
|
Context context) {
|
||||||
Log.i(TAG, "Performing idle optimizations");
|
Log.i(TAG, "Performing idle optimizations");
|
||||||
// If post-boot update is still running, request that it exits early.
|
// If post-boot update is still running, request that it exits early.
|
||||||
mExitPostBootUpdate.set(true);
|
mExitPostBootUpdate.set(true);
|
||||||
|
|
||||||
mAbortIdleOptimization.set(false);
|
mAbortIdleOptimization.set(false);
|
||||||
|
|
||||||
final long lowThreshold = getLowStorageThreshold();
|
long lowStorageThreshold = getLowStorageThreshold(context);
|
||||||
|
return optimizePackages(pm, pkgs, lowStorageThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean optimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
|
||||||
|
long lowStorageThreshold) {
|
||||||
for (String pkg : pkgs) {
|
for (String pkg : pkgs) {
|
||||||
if (mAbortIdleOptimization.get()) {
|
if (abortIdleOptimizations(lowStorageThreshold)) {
|
||||||
// JobScheduler requested an early abort.
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (sFailedPackageNames) {
|
synchronized (sFailedPackageNames) {
|
||||||
if (sFailedPackageNames.contains(pkg)) {
|
if (sFailedPackageNames.contains(pkg)) {
|
||||||
// Skip previously failing package
|
// Skip previously failing package
|
||||||
continue;
|
continue;
|
||||||
|
} else {
|
||||||
|
// Conservatively add package to the list of failing ones in case performDexOpt
|
||||||
|
// never returns.
|
||||||
|
sFailedPackageNames.add(pkg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// Optimize package if needed. Note that there can be no race between
|
||||||
// concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
|
// concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
|
||||||
if (pm.performDexOpt(pkg,
|
if (pm.performDexOpt(pkg,
|
||||||
@@ -259,8 +260,24 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ran to completion, so we abandon our timeslice and do not reschedule.
|
return true;
|
||||||
jobFinished(jobParams, /* reschedule */ false);
|
}
|
||||||
|
|
||||||
|
// Return true if the idle optimizations should be aborted because of a space constraints
|
||||||
|
// or because the JobScheduler requested so.
|
||||||
|
private boolean abortIdleOptimizations(long lowStorageThreshold) {
|
||||||
|
if (mAbortIdleOptimization.get()) {
|
||||||
|
// JobScheduler requested an early abort.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
long usableSpace = mDataDir.getUsableSpace();
|
||||||
|
if (usableSpace < lowStorageThreshold) {
|
||||||
|
// Rather bail than completely fill up the disk.
|
||||||
|
Log.w(TAG, "Aborting background dex opt job due to low storage: " + usableSpace);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -281,7 +298,7 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ArraySet<String> pkgs = pm.getOptimizablePackages();
|
final ArraySet<String> pkgs = pm.getOptimizablePackages();
|
||||||
if (pkgs == null || pkgs.isEmpty()) {
|
if (pkgs.isEmpty()) {
|
||||||
if (DEBUG_DEXOPT) {
|
if (DEBUG_DEXOPT) {
|
||||||
Log.i(TAG, "No packages to optimize");
|
Log.i(TAG, "No packages to optimize");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user