Loading apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +21 −8 Original line number Diff line number Diff line Loading @@ -663,7 +663,7 @@ public class AppStandbyController implements AppStandbyInternal { if (app.lastRestrictAttemptElapsedTime > app.lastUsedByUserElapsedTime && elapsedTimeAdjusted - app.lastUsedByUserElapsedTime >= mInjector.getRestrictedBucketDelayMs()) { >= mInjector.getAutoRestrictedBucketDelayMs()) { newBucket = STANDBY_BUCKET_RESTRICTED; reason = app.lastRestrictReason; if (DEBUG) { Loading Loading @@ -1219,7 +1219,7 @@ public class AppStandbyController implements AppStandbyInternal { } } else { final long timeUntilRestrictPossibleMs = app.lastUsedByUserElapsedTime + mInjector.getRestrictedBucketDelayMs() - elapsedRealtime; + mInjector.getAutoRestrictedBucketDelayMs() - elapsedRealtime; if (timeUntilRestrictPossibleMs > 0) { Slog.w(TAG, "Tried to restrict recently used app: " + packageName + " due to " + reason); Loading Loading @@ -1566,10 +1566,9 @@ public class AppStandbyController implements AppStandbyInternal { int mBootPhase; /** * The minimum amount of time required since the last user interaction before an app can be * placed in the RESTRICTED bucket. * automatically placed in the RESTRICTED bucket. */ // TODO: make configurable via DeviceConfig private long mRestrictedBucketDelayMs = ONE_DAY; long mAutoRestrictedBucketDelayMs = ONE_DAY; Injector(Context context, Looper looper) { mContext = context; Loading Loading @@ -1598,7 +1597,7 @@ public class AppStandbyController implements AppStandbyInternal { final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); if (activityManager.isLowRamDevice() || ActivityManager.isSmallBatteryDevice()) { mRestrictedBucketDelayMs = 12 * ONE_HOUR; mAutoRestrictedBucketDelayMs = 12 * ONE_HOUR; } } mBootPhase = phase; Loading Loading @@ -1639,8 +1638,13 @@ public class AppStandbyController implements AppStandbyInternal { return Environment.getDataSystemDirectory(); } long getRestrictedBucketDelayMs() { return mRestrictedBucketDelayMs; /** * Return the minimum amount of time that must have passed since the last user usage before * an app can be automatically put into the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket. */ long getAutoRestrictedBucketDelayMs() { return mAutoRestrictedBucketDelayMs; } void noteEvent(int event, String packageName, int uid) throws RemoteException { Loading Loading @@ -1816,6 +1820,8 @@ public class AppStandbyController implements AppStandbyInternal { "system_interaction_duration"; private static final String KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION = "initial_foreground_service_start_duration"; private static final String KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS = "auto_restricted_bucket_delay_ms"; public static final long DEFAULT_STRONG_USAGE_TIMEOUT = 1 * ONE_HOUR; public static final long DEFAULT_NOTIFICATION_TIMEOUT = 12 * ONE_HOUR; public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = 2 * ONE_HOUR; Loading @@ -1826,6 +1832,7 @@ public class AppStandbyController implements AppStandbyInternal { public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE; public static final long DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT = 10 * ONE_MINUTE; public static final long DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT = 30 * ONE_MINUTE; public static final long DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS = ONE_DAY; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -1925,6 +1932,12 @@ public class AppStandbyController implements AppStandbyInternal { KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT); mInjector.mAutoRestrictedBucketDelayMs = Math.max( COMPRESS_TIME ? ONE_MINUTE : 2 * ONE_HOUR, mParser.getDurationMillis(KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS)); } // Check if app_idle_enabled has changed. Do this after getting the rest of the settings Loading services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +24 −1 Original line number Diff line number Diff line Loading @@ -685,7 +685,30 @@ public class AppStandbyControllerTests { reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1); assertBucket(STANDBY_BUCKET_ACTIVE); mInjector.mElapsedRealtime += mInjector.getRestrictedBucketDelayMs() - 5000; mInjector.mElapsedRealtime += mInjector.getAutoRestrictedBucketDelayMs() - 5000; mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_SYSTEM); // Bucket shouldn't change assertBucket(STANDBY_BUCKET_ACTIVE); // bucketing works after timeout mInjector.mElapsedRealtime += 6000; Thread.sleep(6000); // Enough time has passed. The app should automatically be put into the RESTRICTED bucket. assertBucket(STANDBY_BUCKET_RESTRICTED); } /** * Test that an app is put into the RESTRICTED bucket after enough time has passed. */ @Test public void testRestrictedDelay_DelayChange() throws Exception { reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1); assertBucket(STANDBY_BUCKET_ACTIVE); mInjector.mAutoRestrictedBucketDelayMs = 2 * HOUR_MS; mInjector.mElapsedRealtime += 2 * HOUR_MS - 5000; mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_SYSTEM); // Bucket shouldn't change Loading Loading
apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +21 −8 Original line number Diff line number Diff line Loading @@ -663,7 +663,7 @@ public class AppStandbyController implements AppStandbyInternal { if (app.lastRestrictAttemptElapsedTime > app.lastUsedByUserElapsedTime && elapsedTimeAdjusted - app.lastUsedByUserElapsedTime >= mInjector.getRestrictedBucketDelayMs()) { >= mInjector.getAutoRestrictedBucketDelayMs()) { newBucket = STANDBY_BUCKET_RESTRICTED; reason = app.lastRestrictReason; if (DEBUG) { Loading Loading @@ -1219,7 +1219,7 @@ public class AppStandbyController implements AppStandbyInternal { } } else { final long timeUntilRestrictPossibleMs = app.lastUsedByUserElapsedTime + mInjector.getRestrictedBucketDelayMs() - elapsedRealtime; + mInjector.getAutoRestrictedBucketDelayMs() - elapsedRealtime; if (timeUntilRestrictPossibleMs > 0) { Slog.w(TAG, "Tried to restrict recently used app: " + packageName + " due to " + reason); Loading Loading @@ -1566,10 +1566,9 @@ public class AppStandbyController implements AppStandbyInternal { int mBootPhase; /** * The minimum amount of time required since the last user interaction before an app can be * placed in the RESTRICTED bucket. * automatically placed in the RESTRICTED bucket. */ // TODO: make configurable via DeviceConfig private long mRestrictedBucketDelayMs = ONE_DAY; long mAutoRestrictedBucketDelayMs = ONE_DAY; Injector(Context context, Looper looper) { mContext = context; Loading Loading @@ -1598,7 +1597,7 @@ public class AppStandbyController implements AppStandbyInternal { final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); if (activityManager.isLowRamDevice() || ActivityManager.isSmallBatteryDevice()) { mRestrictedBucketDelayMs = 12 * ONE_HOUR; mAutoRestrictedBucketDelayMs = 12 * ONE_HOUR; } } mBootPhase = phase; Loading Loading @@ -1639,8 +1638,13 @@ public class AppStandbyController implements AppStandbyInternal { return Environment.getDataSystemDirectory(); } long getRestrictedBucketDelayMs() { return mRestrictedBucketDelayMs; /** * Return the minimum amount of time that must have passed since the last user usage before * an app can be automatically put into the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket. */ long getAutoRestrictedBucketDelayMs() { return mAutoRestrictedBucketDelayMs; } void noteEvent(int event, String packageName, int uid) throws RemoteException { Loading Loading @@ -1816,6 +1820,8 @@ public class AppStandbyController implements AppStandbyInternal { "system_interaction_duration"; private static final String KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION = "initial_foreground_service_start_duration"; private static final String KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS = "auto_restricted_bucket_delay_ms"; public static final long DEFAULT_STRONG_USAGE_TIMEOUT = 1 * ONE_HOUR; public static final long DEFAULT_NOTIFICATION_TIMEOUT = 12 * ONE_HOUR; public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = 2 * ONE_HOUR; Loading @@ -1826,6 +1832,7 @@ public class AppStandbyController implements AppStandbyInternal { public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE; public static final long DEFAULT_UNEXEMPTED_SYNC_SCHEDULED_TIMEOUT = 10 * ONE_MINUTE; public static final long DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT = 30 * ONE_MINUTE; public static final long DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS = ONE_DAY; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -1925,6 +1932,12 @@ public class AppStandbyController implements AppStandbyInternal { KEY_INITIAL_FOREGROUND_SERVICE_START_HOLD_DURATION, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_INITIAL_FOREGROUND_SERVICE_START_TIMEOUT); mInjector.mAutoRestrictedBucketDelayMs = Math.max( COMPRESS_TIME ? ONE_MINUTE : 2 * ONE_HOUR, mParser.getDurationMillis(KEY_AUTO_RESTRICTED_BUCKET_DELAY_MS, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_AUTO_RESTRICTED_BUCKET_DELAY_MS)); } // Check if app_idle_enabled has changed. Do this after getting the rest of the settings Loading
services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +24 −1 Original line number Diff line number Diff line Loading @@ -685,7 +685,30 @@ public class AppStandbyControllerTests { reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1); assertBucket(STANDBY_BUCKET_ACTIVE); mInjector.mElapsedRealtime += mInjector.getRestrictedBucketDelayMs() - 5000; mInjector.mElapsedRealtime += mInjector.getAutoRestrictedBucketDelayMs() - 5000; mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_SYSTEM); // Bucket shouldn't change assertBucket(STANDBY_BUCKET_ACTIVE); // bucketing works after timeout mInjector.mElapsedRealtime += 6000; Thread.sleep(6000); // Enough time has passed. The app should automatically be put into the RESTRICTED bucket. assertBucket(STANDBY_BUCKET_RESTRICTED); } /** * Test that an app is put into the RESTRICTED bucket after enough time has passed. */ @Test public void testRestrictedDelay_DelayChange() throws Exception { reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1); assertBucket(STANDBY_BUCKET_ACTIVE); mInjector.mAutoRestrictedBucketDelayMs = 2 * HOUR_MS; mInjector.mElapsedRealtime += 2 * HOUR_MS - 5000; mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED, REASON_MAIN_FORCED_BY_SYSTEM); // Bucket shouldn't change Loading