Loading services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +78 −2 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ public class AppStandbyControllerTests { static class MyInjector extends AppStandbyController.Injector { long mElapsedRealtime; boolean mIsAppIdleEnabled = true; boolean mIsCharging; List<String> mPowerSaveWhitelistExceptIdle = new ArrayList<>(); boolean mDisplayOn; Loading Loading @@ -155,7 +156,7 @@ public class AppStandbyControllerTests { @Override boolean isAppIdleEnabled() { return true; return mIsAppIdleEnabled; } @Override Loading Loading @@ -266,6 +267,13 @@ public class AppStandbyControllerTests { } } private void setAppIdleEnabled(AppStandbyController controller, boolean enabled) { mInjector.mIsAppIdleEnabled = enabled; if (controller != null) { controller.setAppIdleEnabled(enabled); } } private AppStandbyController setupController() throws Exception { mInjector.mElapsedRealtime = 0; setupPm(mInjector.getContext().getPackageManager()); Loading Loading @@ -335,7 +343,7 @@ public class AppStandbyControllerTests { public void onParoleStateChanged(boolean isParoleOn) { synchronized (this) { // Only record information if it is being looked for if (mLatch.getCount() > 0) { if (mLatch != null && mLatch.getCount() > 0) { mOnParole = isParoleOn; mLastParoleChangeTime = getCurrentTime(); mLatch.countDown(); Loading Loading @@ -396,6 +404,74 @@ public class AppStandbyControllerTests { marginOfError); } @Test public void testEnabledState() throws Exception { TestParoleListener paroleListener = new TestParoleListener(); mController.addListener(paroleListener); long lastUpdateTime; // Test that listeners are notified if enabled changes when the device is not in parole. setChargingState(mController, false); // Start off not enabled. Device is effectively on permanent parole. setAppIdleEnabled(mController, false); // Enable controller paroleListener.rearmLatch(); setAppIdleEnabled(mController, true); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertFalse(paroleListener.mOnParole); lastUpdateTime = paroleListener.getLastParoleChangeTime(); paroleListener.rearmLatch(); setAppIdleEnabled(mController, true); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertFalse(paroleListener.mOnParole); // Make sure AppStandbyController doesn't notify listeners when there's no change. assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); // Disable controller paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); lastUpdateTime = paroleListener.getLastParoleChangeTime(); paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); // Make sure AppStandbyController doesn't notify listeners when there's no change. assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); // Test that listeners aren't notified if enabled status changes when the device is already // in parole. // A device is in parole whenever it's charging. setChargingState(mController, true); // Start off not enabled. paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); lastUpdateTime = paroleListener.getLastParoleChangeTime(); // Test that toggling doesn't notify the listener. paroleListener.rearmLatch(); setAppIdleEnabled(mController, true); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); } private void assertTimeout(AppStandbyController controller, long elapsedTime, int bucket) { mInjector.mElapsedRealtime = elapsedTime; controller.checkIdleStates(USER_ID); Loading services/usage/java/com/android/server/usage/AppStandbyController.java +16 −6 Original line number Diff line number Diff line Loading @@ -30,18 +30,19 @@ import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED_PRIV; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYNC_ADAPTER; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_INTERACTION; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_UPDATE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED_PRIV; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT; 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 static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; Loading Loading @@ -340,14 +341,21 @@ public class AppStandbyController { } void setAppIdleEnabled(boolean enabled) { synchronized (mAppIdleLock) { if (mAppIdleEnabled != enabled) { final boolean oldParoleState = isParoledOrCharging(); mAppIdleEnabled = enabled; if (isParoledOrCharging() != oldParoleState) { postParoleStateChanged(); } } } } public void onBootPhase(int phase) { mInjector.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { Slog.d(TAG, "Setting app idle enabled state"); setAppIdleEnabled(mInjector.isAppIdleEnabled()); // Observe changes to the threshold SettingsObserver settingsObserver = new SettingsObserver(mHandler); settingsObserver.registerObserver(); Loading Loading @@ -1807,8 +1815,6 @@ public class AppStandbyController { mContext.getContentResolver(), 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. Loading Loading @@ -1880,6 +1886,10 @@ public class AppStandbyController { (KEY_STABLE_CHARGING_THRESHOLD, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_STABLE_CHARGING_THRESHOLD); } // Check if app_idle_enabled has changed. Do this after getting the rest of the settings // in case we need to change something based on the new values. setAppIdleEnabled(mInjector.isAppIdleEnabled()); } long[] parseLongArray(String values, long[] defaults) { Loading Loading
services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +78 −2 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ public class AppStandbyControllerTests { static class MyInjector extends AppStandbyController.Injector { long mElapsedRealtime; boolean mIsAppIdleEnabled = true; boolean mIsCharging; List<String> mPowerSaveWhitelistExceptIdle = new ArrayList<>(); boolean mDisplayOn; Loading Loading @@ -155,7 +156,7 @@ public class AppStandbyControllerTests { @Override boolean isAppIdleEnabled() { return true; return mIsAppIdleEnabled; } @Override Loading Loading @@ -266,6 +267,13 @@ public class AppStandbyControllerTests { } } private void setAppIdleEnabled(AppStandbyController controller, boolean enabled) { mInjector.mIsAppIdleEnabled = enabled; if (controller != null) { controller.setAppIdleEnabled(enabled); } } private AppStandbyController setupController() throws Exception { mInjector.mElapsedRealtime = 0; setupPm(mInjector.getContext().getPackageManager()); Loading Loading @@ -335,7 +343,7 @@ public class AppStandbyControllerTests { public void onParoleStateChanged(boolean isParoleOn) { synchronized (this) { // Only record information if it is being looked for if (mLatch.getCount() > 0) { if (mLatch != null && mLatch.getCount() > 0) { mOnParole = isParoleOn; mLastParoleChangeTime = getCurrentTime(); mLatch.countDown(); Loading Loading @@ -396,6 +404,74 @@ public class AppStandbyControllerTests { marginOfError); } @Test public void testEnabledState() throws Exception { TestParoleListener paroleListener = new TestParoleListener(); mController.addListener(paroleListener); long lastUpdateTime; // Test that listeners are notified if enabled changes when the device is not in parole. setChargingState(mController, false); // Start off not enabled. Device is effectively on permanent parole. setAppIdleEnabled(mController, false); // Enable controller paroleListener.rearmLatch(); setAppIdleEnabled(mController, true); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertFalse(paroleListener.mOnParole); lastUpdateTime = paroleListener.getLastParoleChangeTime(); paroleListener.rearmLatch(); setAppIdleEnabled(mController, true); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertFalse(paroleListener.mOnParole); // Make sure AppStandbyController doesn't notify listeners when there's no change. assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); // Disable controller paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); lastUpdateTime = paroleListener.getLastParoleChangeTime(); paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); // Make sure AppStandbyController doesn't notify listeners when there's no change. assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); // Test that listeners aren't notified if enabled status changes when the device is already // in parole. // A device is in parole whenever it's charging. setChargingState(mController, true); // Start off not enabled. paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); lastUpdateTime = paroleListener.getLastParoleChangeTime(); // Test that toggling doesn't notify the listener. paroleListener.rearmLatch(); setAppIdleEnabled(mController, true); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); paroleListener.rearmLatch(); setAppIdleEnabled(mController, false); paroleListener.awaitOnLatch(STABLE_CHARGING_THRESHOLD * 3 / 2); assertTrue(paroleListener.mOnParole); assertEquals(lastUpdateTime, paroleListener.getLastParoleChangeTime()); } private void assertTimeout(AppStandbyController controller, long elapsedTime, int bucket) { mInjector.mElapsedRealtime = elapsedTime; controller.checkIdleStates(USER_ID); Loading
services/usage/java/com/android/server/usage/AppStandbyController.java +16 −6 Original line number Diff line number Diff line Loading @@ -30,18 +30,19 @@ import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED_PRIV; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYNC_ADAPTER; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_INTERACTION; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_UPDATE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SLICE_PINNED_PRIV; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT; 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 static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; Loading Loading @@ -340,14 +341,21 @@ public class AppStandbyController { } void setAppIdleEnabled(boolean enabled) { synchronized (mAppIdleLock) { if (mAppIdleEnabled != enabled) { final boolean oldParoleState = isParoledOrCharging(); mAppIdleEnabled = enabled; if (isParoledOrCharging() != oldParoleState) { postParoleStateChanged(); } } } } public void onBootPhase(int phase) { mInjector.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { Slog.d(TAG, "Setting app idle enabled state"); setAppIdleEnabled(mInjector.isAppIdleEnabled()); // Observe changes to the threshold SettingsObserver settingsObserver = new SettingsObserver(mHandler); settingsObserver.registerObserver(); Loading Loading @@ -1807,8 +1815,6 @@ public class AppStandbyController { mContext.getContentResolver(), 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. Loading Loading @@ -1880,6 +1886,10 @@ public class AppStandbyController { (KEY_STABLE_CHARGING_THRESHOLD, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_STABLE_CHARGING_THRESHOLD); } // Check if app_idle_enabled has changed. Do this after getting the rest of the settings // in case we need to change something based on the new values. setAppIdleEnabled(mInjector.isAppIdleEnabled()); } long[] parseLongArray(String values, long[] defaults) { Loading