Merge changes Ia3ec6198,I211696c8
am: 9cbb19d0a8
Change-Id: Id6bf69626cf3d2c52980cb2f55b5121f3746e5fe
This commit is contained in:
@@ -139,6 +139,9 @@ message Atom {
|
|||||||
BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event = 125;
|
BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event = 125;
|
||||||
BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed = 126;
|
BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed = 126;
|
||||||
BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed = 127;
|
BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed = 127;
|
||||||
|
AppDowngraded app_downgraded = 128;
|
||||||
|
AppOptimizedAfterDowngraded app_optimized_after_downgraded = 129;
|
||||||
|
LowStorageStateChanged low_storage_state_changed = 130;
|
||||||
NfcErrorOccurred nfc_error_occurred = 134;
|
NfcErrorOccurred nfc_error_occurred = 134;
|
||||||
NfcStateChanged nfc_state_changed = 135;
|
NfcStateChanged nfc_state_changed = 135;
|
||||||
NfcBeamOccurred nfc_beam_occurred = 136;
|
NfcBeamOccurred nfc_beam_occurred = 136;
|
||||||
@@ -2006,6 +2009,47 @@ message ActivityForegroundStateChanged {
|
|||||||
optional State state = 4;
|
optional State state = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when a volume entered low Storage state.
|
||||||
|
* Logged from:
|
||||||
|
* frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
|
||||||
|
*/
|
||||||
|
message LowStorageStateChanged {
|
||||||
|
// Volume that ran out of storage.
|
||||||
|
optional string volume_description = 1;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
OFF = 1;
|
||||||
|
ON = 2;
|
||||||
|
}
|
||||||
|
optional State state = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when an app is downgraded.
|
||||||
|
* Logged from:
|
||||||
|
* frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java
|
||||||
|
*/
|
||||||
|
message AppDowngraded {
|
||||||
|
optional string package_name = 1;
|
||||||
|
// Size of the package (all data) before being downgraded.
|
||||||
|
optional int64 size_in_bytes_before = 2;
|
||||||
|
// Size of the package (all data) after being downgraded.
|
||||||
|
optional int64 size_in_bytes_after = 3;
|
||||||
|
|
||||||
|
optional bool aggressive = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when an app is optimized after being downgraded.
|
||||||
|
* Logged from:
|
||||||
|
* frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java
|
||||||
|
*/
|
||||||
|
message AppOptimizedAfterDowngraded {
|
||||||
|
optional string package_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs when an app crashes.
|
* Logs when an app crashes.
|
||||||
* Logged from:
|
* Logged from:
|
||||||
|
|||||||
@@ -27,24 +27,30 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.StatsLog;
|
||||||
|
|
||||||
import com.android.server.pm.dex.DexManager;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.PinnerService;
|
import com.android.server.PinnerService;
|
||||||
|
import com.android.server.pm.dex.DexManager;
|
||||||
import com.android.server.pm.dex.DexoptOptions;
|
import com.android.server.pm.dex.DexoptOptions;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@hide}
|
* {@hide}
|
||||||
@@ -52,7 +58,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class BackgroundDexOptService extends JobService {
|
public class BackgroundDexOptService extends JobService {
|
||||||
private static final String TAG = "BackgroundDexOptService";
|
private static final String TAG = "BackgroundDexOptService";
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
private static final int JOB_IDLE_OPTIMIZE = 800;
|
private static final int JOB_IDLE_OPTIMIZE = 800;
|
||||||
private static final int JOB_POST_BOOT_UPDATE = 801;
|
private static final int JOB_POST_BOOT_UPDATE = 801;
|
||||||
@@ -97,7 +103,6 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
private final AtomicBoolean mExitPostBootUpdate = new AtomicBoolean(false);
|
private final AtomicBoolean mExitPostBootUpdate = new AtomicBoolean(false);
|
||||||
|
|
||||||
private final File mDataDir = Environment.getDataDirectory();
|
private final File mDataDir = Environment.getDataDirectory();
|
||||||
|
|
||||||
private static final long mDowngradeUnusedAppsThresholdInMillis =
|
private static final long mDowngradeUnusedAppsThresholdInMillis =
|
||||||
getDowngradeUnusedAppsThresholdInMillis();
|
getDowngradeUnusedAppsThresholdInMillis();
|
||||||
|
|
||||||
@@ -270,108 +275,147 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
|
|
||||||
long lowStorageThreshold = getLowStorageThreshold(context);
|
long lowStorageThreshold = getLowStorageThreshold(context);
|
||||||
// Optimize primary apks.
|
// Optimize primary apks.
|
||||||
int result = optimizePackages(pm, pkgs, lowStorageThreshold, /*is_for_primary_dex*/ true,
|
int result = optimizePackages(pm, pkgs, lowStorageThreshold,
|
||||||
sFailedPackageNamesPrimary);
|
/*isForPrimaryDex=*/ true);
|
||||||
|
|
||||||
if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
|
if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (supportSecondaryDex()) {
|
||||||
if (SystemProperties.getBoolean("dalvik.vm.dexopt.secondary", false)) {
|
|
||||||
result = reconcileSecondaryDexFiles(pm.getDexManager());
|
result = reconcileSecondaryDexFiles(pm.getDexManager());
|
||||||
if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
|
if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
result = optimizePackages(pm, pkgs, lowStorageThreshold,
|
||||||
result = optimizePackages(pm, pkgs, lowStorageThreshold, /*is_for_primary_dex*/ false,
|
/*isForPrimaryDex=*/ false);
|
||||||
sFailedPackageNamesSecondary);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of the directory. It uses recursion to go over all files.
|
||||||
|
* @param f
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private long getDirectorySize(File f) {
|
||||||
|
long size = 0;
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
for (File file: f.listFiles()) {
|
||||||
|
size += getDirectorySize(file);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size = f.length();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of a package.
|
||||||
|
* @param pkg
|
||||||
|
*/
|
||||||
|
private long getPackageSize(PackageManagerService pm, String pkg) {
|
||||||
|
PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
|
||||||
|
long size = 0;
|
||||||
|
if (info != null && info.applicationInfo != null) {
|
||||||
|
File path = Paths.get(info.applicationInfo.sourceDir).toFile();
|
||||||
|
if (path.isFile()) {
|
||||||
|
path = path.getParentFile();
|
||||||
|
}
|
||||||
|
size += getDirectorySize(path);
|
||||||
|
if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
|
||||||
|
for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
|
||||||
|
path = Paths.get(splitSourceDir).toFile();
|
||||||
|
if (path.isFile()) {
|
||||||
|
path = path.getParentFile();
|
||||||
|
}
|
||||||
|
size += getDirectorySize(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private int optimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
|
private int optimizePackages(PackageManagerService pm, ArraySet<String> pkgs,
|
||||||
long lowStorageThreshold, boolean is_for_primary_dex,
|
long lowStorageThreshold, boolean isForPrimaryDex) {
|
||||||
ArraySet<String> failedPackageNames) {
|
|
||||||
ArraySet<String> updatedPackages = new ArraySet<>();
|
ArraySet<String> updatedPackages = new ArraySet<>();
|
||||||
Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
|
Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
|
||||||
|
Log.d(TAG, "Unsused Packages " + String.join(",", unusedPackages));
|
||||||
// Only downgrade apps when space is low on device.
|
// Only downgrade apps when space is low on device.
|
||||||
// Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
|
// Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
|
||||||
// up disk before user hits the actual lowStorageThreshold.
|
// up disk before user hits the actual lowStorageThreshold.
|
||||||
final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE *
|
final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE *
|
||||||
lowStorageThreshold;
|
lowStorageThreshold;
|
||||||
boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade);
|
boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade);
|
||||||
|
Log.d(TAG, "Should Downgrade " + shouldDowngrade);
|
||||||
|
boolean dex_opt_performed = false;
|
||||||
for (String pkg : pkgs) {
|
for (String pkg : pkgs) {
|
||||||
int abort_code = abortIdleOptimizations(lowStorageThreshold);
|
int abort_code = abortIdleOptimizations(lowStorageThreshold);
|
||||||
if (abort_code == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
|
if (abort_code == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
|
||||||
return abort_code;
|
return abort_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (failedPackageNames) {
|
|
||||||
if (failedPackageNames.contains(pkg)) {
|
|
||||||
// Skip previously failing package
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int reason;
|
|
||||||
boolean downgrade;
|
|
||||||
// Downgrade unused packages.
|
// Downgrade unused packages.
|
||||||
if (unusedPackages.contains(pkg) && shouldDowngrade) {
|
if (unusedPackages.contains(pkg) && shouldDowngrade) {
|
||||||
// This applies for system apps or if packages location is not a directory, i.e.
|
dex_opt_performed = downgradePackage(pm, pkg, isForPrimaryDex);
|
||||||
// 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 {
|
|
||||||
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 {
|
} else {
|
||||||
|
if (abort_code == OPTIMIZE_ABORT_NO_SPACE_LEFT) {
|
||||||
// can't dexopt because of low space.
|
// can't dexopt because of low space.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
dex_opt_performed = optimizePackage(pm, pkg, isForPrimaryDex);
|
||||||
synchronized (failedPackageNames) {
|
|
||||||
// Conservatively add package to the list of failing ones in case
|
|
||||||
// performDexOpt never returns.
|
|
||||||
failedPackageNames.add(pkg);
|
|
||||||
}
|
}
|
||||||
|
if (dex_opt_performed) {
|
||||||
// Optimize package if needed. Note that there can be no race between
|
|
||||||
// concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
|
|
||||||
boolean success;
|
|
||||||
int dexoptFlags =
|
|
||||||
DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
|
|
||||||
DexoptOptions.DEXOPT_BOOT_COMPLETE |
|
|
||||||
(downgrade ? DexoptOptions.DEXOPT_DOWNGRADE : 0) |
|
|
||||||
DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
|
|
||||||
if (is_for_primary_dex) {
|
|
||||||
int result = pm.performDexOptWithStatus(new DexoptOptions(pkg, reason,
|
|
||||||
dexoptFlags));
|
|
||||||
success = result != PackageDexOptimizer.DEX_OPT_FAILED;
|
|
||||||
if (result == PackageDexOptimizer.DEX_OPT_PERFORMED) {
|
|
||||||
updatedPackages.add(pkg);
|
updatedPackages.add(pkg);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
success = pm.performDexOpt(new DexoptOptions(pkg,
|
|
||||||
reason, dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX));
|
|
||||||
}
|
|
||||||
if (success) {
|
|
||||||
// Dexopt succeeded, remove package from the list of failing ones.
|
|
||||||
synchronized (failedPackageNames) {
|
|
||||||
failedPackageNames.remove(pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyPinService(updatedPackages);
|
notifyPinService(updatedPackages);
|
||||||
return OPTIMIZE_PROCESSED;
|
return OPTIMIZE_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to downgrade the package to a smaller compilation filter.
|
||||||
|
* eg. if the package is in speed-profile the package will be downgraded to verify.
|
||||||
|
* @param pm PackageManagerService
|
||||||
|
* @param pkg The package to be downgraded.
|
||||||
|
* @param isForPrimaryDex. Apps can have several dex file, primary and secondary.
|
||||||
|
* @return true if the package was downgraded.
|
||||||
|
*/
|
||||||
|
private boolean downgradePackage(PackageManagerService pm, String pkg,
|
||||||
|
boolean isForPrimaryDex) {
|
||||||
|
Log.d(TAG, "Downgrading " + pkg);
|
||||||
|
boolean dex_opt_performed = false;
|
||||||
|
int reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE;
|
||||||
|
int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
|
||||||
|
| DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB
|
||||||
|
| DexoptOptions.DEXOPT_DOWNGRADE;
|
||||||
|
long package_size_before = getPackageSize(pm, pkg);
|
||||||
|
|
||||||
|
if (isForPrimaryDex) {
|
||||||
|
// This applies for system apps or if packages location is not a directory, i.e.
|
||||||
|
// monolithic install.
|
||||||
|
if (!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);
|
||||||
|
} else {
|
||||||
|
dex_opt_performed = performDexOptPrimary(pm, pkg, reason, dexoptFlags);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dex_opt_performed = performDexOptSecondary(pm, pkg, reason, dexoptFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dex_opt_performed) {
|
||||||
|
StatsLog.write(StatsLog.APP_DOWNGRADED, pkg, package_size_before,
|
||||||
|
getPackageSize(pm, pkg), /*aggressive=*/ false);
|
||||||
|
}
|
||||||
|
return dex_opt_performed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportSecondaryDex() {
|
||||||
|
return (SystemProperties.getBoolean("dalvik.vm.dexopt.secondary", false));
|
||||||
|
}
|
||||||
|
|
||||||
private int reconcileSecondaryDexFiles(DexManager dm) {
|
private int reconcileSecondaryDexFiles(DexManager dm) {
|
||||||
// TODO(calin): should we blacklist packages for which we fail to reconcile?
|
// TODO(calin): should we blacklist packages for which we fail to reconcile?
|
||||||
for (String p : dm.getAllPackagesWithSecondaryDexFiles()) {
|
for (String p : dm.getAllPackagesWithSecondaryDexFiles()) {
|
||||||
@@ -383,6 +427,73 @@ public class BackgroundDexOptService extends JobService {
|
|||||||
return OPTIMIZE_PROCESSED;
|
return OPTIMIZE_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Optimize package if needed. Note that there can be no race between
|
||||||
|
* concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
|
||||||
|
* @param pm An instance of PackageManagerService
|
||||||
|
* @param pkg The package to be downgraded.
|
||||||
|
* @param isForPrimaryDex. Apps can have several dex file, primary and secondary.
|
||||||
|
* @return true if the package was downgraded.
|
||||||
|
*/
|
||||||
|
private boolean optimizePackage(PackageManagerService pm, String pkg,
|
||||||
|
boolean isForPrimaryDex) {
|
||||||
|
int reason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
|
||||||
|
int dexoptFlags = DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
|
||||||
|
| DexoptOptions.DEXOPT_BOOT_COMPLETE
|
||||||
|
| DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB;
|
||||||
|
|
||||||
|
return isForPrimaryDex
|
||||||
|
? performDexOptPrimary(pm, pkg, reason, dexoptFlags)
|
||||||
|
: performDexOptSecondary(pm, pkg, reason, dexoptFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean performDexOptPrimary(PackageManagerService pm, String pkg, int reason,
|
||||||
|
int dexoptFlags) {
|
||||||
|
int result = trackPerformDexOpt(pkg, /*isForPrimaryDex=*/ false,
|
||||||
|
() -> pm.performDexOptWithStatus(new DexoptOptions(pkg, reason, dexoptFlags)));
|
||||||
|
return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean performDexOptSecondary(PackageManagerService pm, String pkg, int reason,
|
||||||
|
int dexoptFlags) {
|
||||||
|
DexoptOptions dexoptOptions = new DexoptOptions(pkg, reason,
|
||||||
|
dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX);
|
||||||
|
int result = trackPerformDexOpt(pkg, /*isForPrimaryDex=*/ true,
|
||||||
|
() -> pm.performDexOpt(dexoptOptions)
|
||||||
|
? PackageDexOptimizer.DEX_OPT_PERFORMED : PackageDexOptimizer.DEX_OPT_FAILED
|
||||||
|
);
|
||||||
|
return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the dexopt wrapper and make sure that if performDexOpt wrapper fails
|
||||||
|
* the package is added to the list of failed packages.
|
||||||
|
* Return one of following result:
|
||||||
|
* {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
|
||||||
|
* {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
|
||||||
|
* {@link PackageDexOptimizer#DEX_OPT_FAILED}
|
||||||
|
*/
|
||||||
|
private int trackPerformDexOpt(String pkg, boolean isForPrimaryDex,
|
||||||
|
Supplier<Integer> performDexOptWrapper) {
|
||||||
|
ArraySet<String> sFailedPackageNames =
|
||||||
|
isForPrimaryDex ? sFailedPackageNamesPrimary : sFailedPackageNamesSecondary;
|
||||||
|
synchronized (sFailedPackageNames) {
|
||||||
|
if (sFailedPackageNames.contains(pkg)) {
|
||||||
|
// Skip previously failing package
|
||||||
|
return PackageDexOptimizer.DEX_OPT_SKIPPED;
|
||||||
|
}
|
||||||
|
sFailedPackageNames.add(pkg);
|
||||||
|
}
|
||||||
|
int result = performDexOptWrapper.get();
|
||||||
|
if (result != PackageDexOptimizer.DEX_OPT_FAILED) {
|
||||||
|
synchronized (sFailedPackageNames) {
|
||||||
|
sFailedPackageNames.remove(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluate whether or not idle optimizations should continue.
|
// Evaluate whether or not idle optimizations should continue.
|
||||||
private int abortIdleOptimizations(long lowStorageThreshold) {
|
private int abortIdleOptimizations(long lowStorageThreshold) {
|
||||||
if (mAbortIdleOptimization.get()) {
|
if (mAbortIdleOptimization.get()) {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import android.app.PendingIntent;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.TrafficStats;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.FileObserver;
|
import android.os.FileObserver;
|
||||||
@@ -42,13 +41,13 @@ import android.text.format.DateUtils;
|
|||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.DataUnit;
|
import android.util.DataUnit;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.util.StatsLog;
|
||||||
|
|
||||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||||
import com.android.internal.notification.SystemNotificationChannels;
|
import com.android.internal.notification.SystemNotificationChannels;
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
import com.android.server.EventLogTags;
|
import com.android.server.EventLogTags;
|
||||||
import com.android.server.IoThread;
|
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
import com.android.server.pm.InstructionSets;
|
import com.android.server.pm.InstructionSets;
|
||||||
import com.android.server.pm.PackageManagerService;
|
import com.android.server.pm.PackageManagerService;
|
||||||
@@ -499,9 +498,15 @@ public class DeviceStorageMonitorService extends SystemService {
|
|||||||
notification.flags |= Notification.FLAG_NO_CLEAR;
|
notification.flags |= Notification.FLAG_NO_CLEAR;
|
||||||
mNotifManager.notifyAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
|
mNotifManager.notifyAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
|
||||||
notification, UserHandle.ALL);
|
notification, UserHandle.ALL);
|
||||||
|
StatsLog.write(StatsLog.LOW_STORAGE_STATE_CHANGED,
|
||||||
|
Objects.toString(vol.getDescription()),
|
||||||
|
StatsLog.LOW_STORAGE_STATE_CHANGED__STATE__ON);
|
||||||
} else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
|
} else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
|
||||||
mNotifManager.cancelAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
|
mNotifManager.cancelAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
|
||||||
UserHandle.ALL);
|
UserHandle.ALL);
|
||||||
|
StatsLog.write(StatsLog.LOW_STORAGE_STATE_CHANGED,
|
||||||
|
Objects.toString(vol.getDescription()),
|
||||||
|
StatsLog.LOW_STORAGE_STATE_CHANGED__STATE__OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user