Loading core/java/android/provider/Settings.java +12 −2 Original line number Diff line number Diff line Loading @@ -9587,9 +9587,10 @@ public final class Settings { /** * App standby (app idle) specific settings. * This is encoded as a key=value list, separated by commas. Ex: * * <p> * "idle_duration=5000,parole_interval=4500" * * <p> * All durations are in millis. * The following keys are supported: * * <pre> Loading Loading @@ -9738,6 +9739,15 @@ public final class Settings { */ public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants"; /** * Whether or not App Standby feature is enabled. This controls throttling of apps * based on usage patterns and predictions. * Type: int (0 for false, 1 for true) * Default: 1 * @hide */ public static final java.lang.String APP_STANDBY_ENABLED = "app_standby_enabled"; /** * Get the key that retrieves a bluetooth headset's priority. * @hide Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class SettingsBackupTest { Settings.Global.APN_DB_UPDATE_CONTENT_URL, Settings.Global.APN_DB_UPDATE_METADATA_URL, Settings.Global.APP_IDLE_CONSTANTS, Settings.Global.APP_STANDBY_ENABLED, Settings.Global.ASSISTED_GPS_ENABLED, Settings.Global.AUDIO_SAFE_VOLUME_STATE, Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD, Loading services/usage/java/com/android/server/usage/AppIdleHistory.java +29 −18 Original line number Diff line number Diff line Loading @@ -16,6 +16,15 @@ package com.android.server.usage; import static android.app.usage.UsageStatsManager.REASON_DEFAULT; import static android.app.usage.UsageStatsManager.REASON_FORCED; import static android.app.usage.UsageStatsManager.REASON_PREDICTED; import static android.app.usage.UsageStatsManager.REASON_USAGE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import android.app.usage.UsageStatsManager; import android.os.SystemClock; import android.util.ArrayMap; Loading Loading @@ -197,14 +206,14 @@ public class AppIdleHistory { + (elapsedRealtime - mElapsedSnapshot); appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime); appUsageHistory.recent[HISTORY_SIZE - 1] = FLAG_LAST_STATE | FLAG_PARTIAL_ACTIVE; if (appUsageHistory.currentBucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE; if (appUsageHistory.currentBucket > STANDBY_BUCKET_ACTIVE) { appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE; if (DEBUG) { Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket + ", reason=" + appUsageHistory.bucketingReason); } } appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE; appUsageHistory.bucketingReason = REASON_USAGE; return appUsageHistory.currentBucket; } Loading @@ -213,15 +222,15 @@ public class AppIdleHistory { ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName, elapsedRealtime, true); if (appUsageHistory.currentBucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_WORKING_SET; if (appUsageHistory.currentBucket > STANDBY_BUCKET_WORKING_SET) { appUsageHistory.currentBucket = STANDBY_BUCKET_WORKING_SET; if (DEBUG) { Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket + ", reason=" + appUsageHistory.bucketingReason); } } // TODO: Should this be a different reason for partial usage? appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE; appUsageHistory.bucketingReason = REASON_USAGE; return appUsageHistory.currentBucket; } Loading Loading @@ -279,8 +288,8 @@ public class AppIdleHistory { appUsageHistory.lastUsedElapsedTime = getElapsedTime(elapsedRealtime); appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime); appUsageHistory.lastPredictedTime = getElapsedTime(0); appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_NEVER; appUsageHistory.bucketingReason = UsageStatsManager.REASON_DEFAULT; appUsageHistory.currentBucket = STANDBY_BUCKET_NEVER; appUsageHistory.bucketingReason = REASON_DEFAULT; appUsageHistory.lastInformedBucket = -1; userHistory.put(packageName, appUsageHistory); } Loading @@ -298,7 +307,7 @@ public class AppIdleHistory { if (appUsageHistory == null) { return false; // Default to not idle } else { return appUsageHistory.currentBucket >= UsageStatsManager.STANDBY_BUCKET_RARE; return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE; // Whether or not it's passed will now be externally calculated and the // bucket will be pushed to the history using setAppStandbyBucket() //return hasPassedThresholds(appUsageHistory, elapsedRealtime); Loading @@ -320,7 +329,7 @@ public class AppIdleHistory { getPackageHistory(userHistory, packageName, elapsedRealtime, true); appUsageHistory.currentBucket = bucket; appUsageHistory.bucketingReason = reason; if (reason.startsWith(UsageStatsManager.REASON_PREDICTED)) { if (reason.startsWith(REASON_PREDICTED)) { appUsageHistory.lastPredictedTime = getElapsedTime(elapsedRealtime); } if (DEBUG) { Loading @@ -336,12 +345,14 @@ public class AppIdleHistory { return appUsageHistory.currentBucket; } public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) { public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime, boolean appIdleEnabled) { ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); int size = userHistory.size(); HashMap<String, Integer> buckets = new HashMap<>(size); for (int i = 0; i < size; i++) { buckets.put(userHistory.keyAt(i), userHistory.valueAt(i).currentBucket); buckets.put(userHistory.keyAt(i), appIdleEnabled ? userHistory.valueAt(i).currentBucket : STANDBY_BUCKET_ACTIVE); } return buckets; } Loading @@ -363,12 +374,12 @@ public class AppIdleHistory { AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName, elapsedRealtime, true); if (idle) { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_RARE; appUsageHistory.bucketingReason = UsageStatsManager.REASON_FORCED; appUsageHistory.currentBucket = STANDBY_BUCKET_RARE; appUsageHistory.bucketingReason = REASON_FORCED; } else { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE; appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE; // This is to pretend that the app was just used, don't freeze the state anymore. appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE; appUsageHistory.bucketingReason = REASON_USAGE; } return appUsageHistory.currentBucket; } Loading Loading @@ -471,12 +482,12 @@ public class AppIdleHistory { String currentBucketString = parser.getAttributeValue(null, ATTR_CURRENT_BUCKET); appUsageHistory.currentBucket = currentBucketString == null ? UsageStatsManager.STANDBY_BUCKET_ACTIVE ? STANDBY_BUCKET_ACTIVE : Integer.parseInt(currentBucketString); appUsageHistory.bucketingReason = parser.getAttributeValue(null, ATTR_BUCKETING_REASON); if (appUsageHistory.bucketingReason == null) { appUsageHistory.bucketingReason = UsageStatsManager.REASON_DEFAULT; appUsageHistory.bucketingReason = REASON_DEFAULT; } appUsageHistory.lastInformedBucket = -1; userHistory.put(packageName, appUsageHistory); Loading services/usage/java/com/android/server/usage/AppStandbyController.java +52 −23 Original line number Diff line number Diff line Loading @@ -162,12 +162,14 @@ public class AppStandbyController { long[] mAppStandbyScreenThresholds = SCREEN_TIME_THRESHOLDS; long[] mAppStandbyElapsedThresholds = ELAPSED_TIME_THRESHOLDS; boolean mAppIdleEnabled; volatile boolean mAppIdleEnabled; boolean mAppIdleTempParoled; boolean mCharging; private long mLastAppIdleParoledTime; private boolean mSystemServicesReady = false; private final DeviceStateReceiver mDeviceStateReceiver; private volatile boolean mPendingOneTimeCheckIdleStates; private final AppStandbyHandler mHandler; Loading @@ -178,7 +180,7 @@ public class AppStandbyController { private AppWidgetManager mAppWidgetManager; private PowerManager mPowerManager; private PackageManager mPackageManager; private Injector mInjector; Injector mInjector; AppStandbyController(Context context, Looper looper) { Loading @@ -190,14 +192,13 @@ public class AppStandbyController { mContext = mInjector.getContext(); mHandler = new AppStandbyHandler(mInjector.getLooper()); mPackageManager = mContext.getPackageManager(); mAppIdleEnabled = mInjector.isAppIdleEnabled(); mDeviceStateReceiver = new DeviceStateReceiver(); if (mAppIdleEnabled) { IntentFilter deviceStates = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); deviceStates.addAction(BatteryManager.ACTION_DISCHARGING); deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); mContext.registerReceiver(new DeviceStateReceiver(), deviceStates); } mContext.registerReceiver(mDeviceStateReceiver, deviceStates); synchronized (mAppIdleLock) { mAppIdleHistory = new AppIdleHistory(mInjector.getDataSystemDirectory(), mInjector.elapsedRealtime()); Loading @@ -213,9 +214,14 @@ public class AppStandbyController { null, mHandler); } void setAppIdleEnabled(boolean enabled) { mAppIdleEnabled = enabled; } public void onBootPhase(int phase) { mInjector.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { setAppIdleEnabled(mInjector.isAppIdleEnabled()); // Observe changes to the threshold SettingsObserver settingsObserver = new SettingsObserver(mHandler); settingsObserver.registerObserver(); Loading @@ -240,6 +246,8 @@ public class AppStandbyController { } void reportContentProviderUsage(String authority, String providerPkgName, int userId) { if (!mAppIdleEnabled) return; // Get sync adapters for the authority String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser( authority, userId); Loading Loading @@ -295,6 +303,7 @@ public class AppStandbyController { } boolean isParoledOrCharging() { if (!mAppIdleEnabled) return true; synchronized (mAppIdleLock) { return mAppIdleTempParoled || mCharging; } Loading Loading @@ -520,6 +529,7 @@ public class AppStandbyController { } void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) { if (!mAppIdleEnabled) return; synchronized (mAppIdleLock) { // TODO: Ideally this should call isAppIdleFiltered() to avoid calling back // about apps that are on some kind of whitelist anyway. Loading Loading @@ -559,6 +569,8 @@ public class AppStandbyController { * required. */ void forceIdleState(String packageName, int userId, boolean idle) { if (!mAppIdleEnabled) return; final int appId = getAppId(packageName); if (appId < 0) return; final long elapsedRealtime = mInjector.elapsedRealtime(); Loading Loading @@ -763,7 +775,7 @@ public class AppStandbyController { } void setAppIdleAsync(String packageName, boolean idle, int userId) { if (packageName == null) return; if (packageName == null || !mAppIdleEnabled) return; mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName) .sendToTarget(); Loading @@ -771,8 +783,8 @@ public class AppStandbyController { @StandbyBuckets public int getAppStandbyBucket(String packageName, int userId, long elapsedRealtime, boolean shouldObfuscateInstantApps) { if (shouldObfuscateInstantApps && mInjector.isPackageEphemeral(userId, packageName)) { if (!mAppIdleEnabled || (shouldObfuscateInstantApps && mInjector.isPackageEphemeral(userId, packageName))) { return STANDBY_BUCKET_ACTIVE; } Loading @@ -783,7 +795,7 @@ public class AppStandbyController { public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) { synchronized (mAppIdleLock) { return mAppIdleHistory.getAppStandbyBuckets(userId, elapsedRealtime); return mAppIdleHistory.getAppStandbyBuckets(userId, elapsedRealtime, mAppIdleEnabled); } } Loading Loading @@ -1058,8 +1070,11 @@ public class AppStandbyController { } boolean isAppIdleEnabled() { return mContext.getResources().getBoolean( final boolean buildFlag = mContext.getResources().getBoolean( com.android.internal.R.bool.config_enableAutoPowerModes); final boolean runtimeFlag = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.APP_STANDBY_ENABLED, 1) == 1; return buildFlag && runtimeFlag; } boolean isCharging() { Loading Loading @@ -1130,7 +1145,7 @@ public class AppStandbyController { break; case MSG_CHECK_IDLE_STATES: if (checkIdleStates(msg.arg1)) { if (checkIdleStates(msg.arg1) && mAppIdleEnabled) { mHandler.sendMessageDelayed(mHandler.obtainMessage( MSG_CHECK_IDLE_STATES, msg.arg1, 0), mCheckIdleIntervalMillis); Loading Loading @@ -1229,6 +1244,8 @@ public class AppStandbyController { void registerObserver() { mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( Settings.Global.APP_IDLE_CONSTANTS), false, this); mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( Settings.Global.APP_STANDBY_ENABLED), false, this); } @Override Loading @@ -1238,7 +1255,17 @@ public class AppStandbyController { } void updateSettings() { synchronized (mAppIdleLock) { if (DEBUG) { Slog.d(TAG, "appidle=" + Settings.Global.getString(mContext.getContentResolver(), Settings.Global.APP_STANDBY_ENABLED)); Slog.d(TAG, "appidleconstants=" + Settings.Global.getString( mContext.getContentResolver(), Settings.Global.APP_IDLE_CONSTANTS)); } // Check if app_idle_enabled has changed setAppIdleEnabled(mInjector.isAppIdleEnabled()); // Look at global settings for this. // TODO: Maybe apply different thresholds for different users. try { Loading @@ -1248,6 +1275,8 @@ public class AppStandbyController { // fallthrough, mParser is empty and all defaults will be returned. } synchronized (mAppIdleLock) { // Default: 24 hours between paroles mAppIdleParoleIntervalMillis = mParser.getLong(KEY_PAROLE_INTERVAL, COMPRESS_TIME ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE); Loading Loading
core/java/android/provider/Settings.java +12 −2 Original line number Diff line number Diff line Loading @@ -9587,9 +9587,10 @@ public final class Settings { /** * App standby (app idle) specific settings. * This is encoded as a key=value list, separated by commas. Ex: * * <p> * "idle_duration=5000,parole_interval=4500" * * <p> * All durations are in millis. * The following keys are supported: * * <pre> Loading Loading @@ -9738,6 +9739,15 @@ public final class Settings { */ public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants"; /** * Whether or not App Standby feature is enabled. This controls throttling of apps * based on usage patterns and predictions. * Type: int (0 for false, 1 for true) * Default: 1 * @hide */ public static final java.lang.String APP_STANDBY_ENABLED = "app_standby_enabled"; /** * Get the key that retrieves a bluetooth headset's priority. * @hide Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ public class SettingsBackupTest { Settings.Global.APN_DB_UPDATE_CONTENT_URL, Settings.Global.APN_DB_UPDATE_METADATA_URL, Settings.Global.APP_IDLE_CONSTANTS, Settings.Global.APP_STANDBY_ENABLED, Settings.Global.ASSISTED_GPS_ENABLED, Settings.Global.AUDIO_SAFE_VOLUME_STATE, Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD, Loading
services/usage/java/com/android/server/usage/AppIdleHistory.java +29 −18 Original line number Diff line number Diff line Loading @@ -16,6 +16,15 @@ package com.android.server.usage; import static android.app.usage.UsageStatsManager.REASON_DEFAULT; import static android.app.usage.UsageStatsManager.REASON_FORCED; import static android.app.usage.UsageStatsManager.REASON_PREDICTED; import static android.app.usage.UsageStatsManager.REASON_USAGE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import android.app.usage.UsageStatsManager; import android.os.SystemClock; import android.util.ArrayMap; Loading Loading @@ -197,14 +206,14 @@ public class AppIdleHistory { + (elapsedRealtime - mElapsedSnapshot); appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime); appUsageHistory.recent[HISTORY_SIZE - 1] = FLAG_LAST_STATE | FLAG_PARTIAL_ACTIVE; if (appUsageHistory.currentBucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE; if (appUsageHistory.currentBucket > STANDBY_BUCKET_ACTIVE) { appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE; if (DEBUG) { Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket + ", reason=" + appUsageHistory.bucketingReason); } } appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE; appUsageHistory.bucketingReason = REASON_USAGE; return appUsageHistory.currentBucket; } Loading @@ -213,15 +222,15 @@ public class AppIdleHistory { ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName, elapsedRealtime, true); if (appUsageHistory.currentBucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_WORKING_SET; if (appUsageHistory.currentBucket > STANDBY_BUCKET_WORKING_SET) { appUsageHistory.currentBucket = STANDBY_BUCKET_WORKING_SET; if (DEBUG) { Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket + ", reason=" + appUsageHistory.bucketingReason); } } // TODO: Should this be a different reason for partial usage? appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE; appUsageHistory.bucketingReason = REASON_USAGE; return appUsageHistory.currentBucket; } Loading Loading @@ -279,8 +288,8 @@ public class AppIdleHistory { appUsageHistory.lastUsedElapsedTime = getElapsedTime(elapsedRealtime); appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime); appUsageHistory.lastPredictedTime = getElapsedTime(0); appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_NEVER; appUsageHistory.bucketingReason = UsageStatsManager.REASON_DEFAULT; appUsageHistory.currentBucket = STANDBY_BUCKET_NEVER; appUsageHistory.bucketingReason = REASON_DEFAULT; appUsageHistory.lastInformedBucket = -1; userHistory.put(packageName, appUsageHistory); } Loading @@ -298,7 +307,7 @@ public class AppIdleHistory { if (appUsageHistory == null) { return false; // Default to not idle } else { return appUsageHistory.currentBucket >= UsageStatsManager.STANDBY_BUCKET_RARE; return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE; // Whether or not it's passed will now be externally calculated and the // bucket will be pushed to the history using setAppStandbyBucket() //return hasPassedThresholds(appUsageHistory, elapsedRealtime); Loading @@ -320,7 +329,7 @@ public class AppIdleHistory { getPackageHistory(userHistory, packageName, elapsedRealtime, true); appUsageHistory.currentBucket = bucket; appUsageHistory.bucketingReason = reason; if (reason.startsWith(UsageStatsManager.REASON_PREDICTED)) { if (reason.startsWith(REASON_PREDICTED)) { appUsageHistory.lastPredictedTime = getElapsedTime(elapsedRealtime); } if (DEBUG) { Loading @@ -336,12 +345,14 @@ public class AppIdleHistory { return appUsageHistory.currentBucket; } public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) { public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime, boolean appIdleEnabled) { ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId); int size = userHistory.size(); HashMap<String, Integer> buckets = new HashMap<>(size); for (int i = 0; i < size; i++) { buckets.put(userHistory.keyAt(i), userHistory.valueAt(i).currentBucket); buckets.put(userHistory.keyAt(i), appIdleEnabled ? userHistory.valueAt(i).currentBucket : STANDBY_BUCKET_ACTIVE); } return buckets; } Loading @@ -363,12 +374,12 @@ public class AppIdleHistory { AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName, elapsedRealtime, true); if (idle) { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_RARE; appUsageHistory.bucketingReason = UsageStatsManager.REASON_FORCED; appUsageHistory.currentBucket = STANDBY_BUCKET_RARE; appUsageHistory.bucketingReason = REASON_FORCED; } else { appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE; appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE; // This is to pretend that the app was just used, don't freeze the state anymore. appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE; appUsageHistory.bucketingReason = REASON_USAGE; } return appUsageHistory.currentBucket; } Loading Loading @@ -471,12 +482,12 @@ public class AppIdleHistory { String currentBucketString = parser.getAttributeValue(null, ATTR_CURRENT_BUCKET); appUsageHistory.currentBucket = currentBucketString == null ? UsageStatsManager.STANDBY_BUCKET_ACTIVE ? STANDBY_BUCKET_ACTIVE : Integer.parseInt(currentBucketString); appUsageHistory.bucketingReason = parser.getAttributeValue(null, ATTR_BUCKETING_REASON); if (appUsageHistory.bucketingReason == null) { appUsageHistory.bucketingReason = UsageStatsManager.REASON_DEFAULT; appUsageHistory.bucketingReason = REASON_DEFAULT; } appUsageHistory.lastInformedBucket = -1; userHistory.put(packageName, appUsageHistory); Loading
services/usage/java/com/android/server/usage/AppStandbyController.java +52 −23 Original line number Diff line number Diff line Loading @@ -162,12 +162,14 @@ public class AppStandbyController { long[] mAppStandbyScreenThresholds = SCREEN_TIME_THRESHOLDS; long[] mAppStandbyElapsedThresholds = ELAPSED_TIME_THRESHOLDS; boolean mAppIdleEnabled; volatile boolean mAppIdleEnabled; boolean mAppIdleTempParoled; boolean mCharging; private long mLastAppIdleParoledTime; private boolean mSystemServicesReady = false; private final DeviceStateReceiver mDeviceStateReceiver; private volatile boolean mPendingOneTimeCheckIdleStates; private final AppStandbyHandler mHandler; Loading @@ -178,7 +180,7 @@ public class AppStandbyController { private AppWidgetManager mAppWidgetManager; private PowerManager mPowerManager; private PackageManager mPackageManager; private Injector mInjector; Injector mInjector; AppStandbyController(Context context, Looper looper) { Loading @@ -190,14 +192,13 @@ public class AppStandbyController { mContext = mInjector.getContext(); mHandler = new AppStandbyHandler(mInjector.getLooper()); mPackageManager = mContext.getPackageManager(); mAppIdleEnabled = mInjector.isAppIdleEnabled(); mDeviceStateReceiver = new DeviceStateReceiver(); if (mAppIdleEnabled) { IntentFilter deviceStates = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); deviceStates.addAction(BatteryManager.ACTION_DISCHARGING); deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); mContext.registerReceiver(new DeviceStateReceiver(), deviceStates); } mContext.registerReceiver(mDeviceStateReceiver, deviceStates); synchronized (mAppIdleLock) { mAppIdleHistory = new AppIdleHistory(mInjector.getDataSystemDirectory(), mInjector.elapsedRealtime()); Loading @@ -213,9 +214,14 @@ public class AppStandbyController { null, mHandler); } void setAppIdleEnabled(boolean enabled) { mAppIdleEnabled = enabled; } public void onBootPhase(int phase) { mInjector.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { setAppIdleEnabled(mInjector.isAppIdleEnabled()); // Observe changes to the threshold SettingsObserver settingsObserver = new SettingsObserver(mHandler); settingsObserver.registerObserver(); Loading @@ -240,6 +246,8 @@ public class AppStandbyController { } void reportContentProviderUsage(String authority, String providerPkgName, int userId) { if (!mAppIdleEnabled) return; // Get sync adapters for the authority String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser( authority, userId); Loading Loading @@ -295,6 +303,7 @@ public class AppStandbyController { } boolean isParoledOrCharging() { if (!mAppIdleEnabled) return true; synchronized (mAppIdleLock) { return mAppIdleTempParoled || mCharging; } Loading Loading @@ -520,6 +529,7 @@ public class AppStandbyController { } void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) { if (!mAppIdleEnabled) return; synchronized (mAppIdleLock) { // TODO: Ideally this should call isAppIdleFiltered() to avoid calling back // about apps that are on some kind of whitelist anyway. Loading Loading @@ -559,6 +569,8 @@ public class AppStandbyController { * required. */ void forceIdleState(String packageName, int userId, boolean idle) { if (!mAppIdleEnabled) return; final int appId = getAppId(packageName); if (appId < 0) return; final long elapsedRealtime = mInjector.elapsedRealtime(); Loading Loading @@ -763,7 +775,7 @@ public class AppStandbyController { } void setAppIdleAsync(String packageName, boolean idle, int userId) { if (packageName == null) return; if (packageName == null || !mAppIdleEnabled) return; mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName) .sendToTarget(); Loading @@ -771,8 +783,8 @@ public class AppStandbyController { @StandbyBuckets public int getAppStandbyBucket(String packageName, int userId, long elapsedRealtime, boolean shouldObfuscateInstantApps) { if (shouldObfuscateInstantApps && mInjector.isPackageEphemeral(userId, packageName)) { if (!mAppIdleEnabled || (shouldObfuscateInstantApps && mInjector.isPackageEphemeral(userId, packageName))) { return STANDBY_BUCKET_ACTIVE; } Loading @@ -783,7 +795,7 @@ public class AppStandbyController { public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) { synchronized (mAppIdleLock) { return mAppIdleHistory.getAppStandbyBuckets(userId, elapsedRealtime); return mAppIdleHistory.getAppStandbyBuckets(userId, elapsedRealtime, mAppIdleEnabled); } } Loading Loading @@ -1058,8 +1070,11 @@ public class AppStandbyController { } boolean isAppIdleEnabled() { return mContext.getResources().getBoolean( final boolean buildFlag = mContext.getResources().getBoolean( com.android.internal.R.bool.config_enableAutoPowerModes); final boolean runtimeFlag = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.APP_STANDBY_ENABLED, 1) == 1; return buildFlag && runtimeFlag; } boolean isCharging() { Loading Loading @@ -1130,7 +1145,7 @@ public class AppStandbyController { break; case MSG_CHECK_IDLE_STATES: if (checkIdleStates(msg.arg1)) { if (checkIdleStates(msg.arg1) && mAppIdleEnabled) { mHandler.sendMessageDelayed(mHandler.obtainMessage( MSG_CHECK_IDLE_STATES, msg.arg1, 0), mCheckIdleIntervalMillis); Loading Loading @@ -1229,6 +1244,8 @@ public class AppStandbyController { void registerObserver() { mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( Settings.Global.APP_IDLE_CONSTANTS), false, this); mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( Settings.Global.APP_STANDBY_ENABLED), false, this); } @Override Loading @@ -1238,7 +1255,17 @@ public class AppStandbyController { } void updateSettings() { synchronized (mAppIdleLock) { if (DEBUG) { Slog.d(TAG, "appidle=" + Settings.Global.getString(mContext.getContentResolver(), Settings.Global.APP_STANDBY_ENABLED)); Slog.d(TAG, "appidleconstants=" + Settings.Global.getString( mContext.getContentResolver(), Settings.Global.APP_IDLE_CONSTANTS)); } // Check if app_idle_enabled has changed setAppIdleEnabled(mInjector.isAppIdleEnabled()); // Look at global settings for this. // TODO: Maybe apply different thresholds for different users. try { Loading @@ -1248,6 +1275,8 @@ public class AppStandbyController { // fallthrough, mParser is empty and all defaults will be returned. } synchronized (mAppIdleLock) { // Default: 24 hours between paroles mAppIdleParoleIntervalMillis = mParser.getLong(KEY_PAROLE_INTERVAL, COMPRESS_TIME ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE); Loading