diff options
| author | 2018-10-09 02:45:18 +0000 | |
|---|---|---|
| committer | 2018-10-09 02:45:18 +0000 | |
| commit | bf90544829837f8e565ba335d0d842f1fdbd6c04 (patch) | |
| tree | 2160e9c0893067e3ca181a35f31e1780eadc81ef | |
| parent | dae6ec0db7473133e1ca97b65c1f67085af28a0e (diff) | |
| parent | a457f4e177b461dae82ba7843edd0977e753f382 (diff) | |
Merge "DeviceIdleController state exit conditions tests."
| -rw-r--r-- | services/core/java/com/android/server/DeviceIdleController.java | 30 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java | 533 |
2 files changed, 553 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 376bc0df1d87..26421a2acb66 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -666,7 +666,8 @@ public class DeviceIdleController extends SystemService * global Settings. Any access to this class or its fields should be done while * holding the DeviceIdleController lock. */ - private final class Constants extends ContentObserver { + @VisibleForTesting + final class Constants extends ContentObserver { // Key names stored in the settings value. private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = "light_after_inactive_to"; @@ -1529,12 +1530,17 @@ public class DeviceIdleController extends SystemService return (ConnectivityService) ServiceManager.getService(Context.CONNECTIVITY_SERVICE); } + Constants getConstants(DeviceIdleController controller, Handler handler, + ContentResolver resolver) { + return controller.new Constants(handler, resolver); + } + LocationManager getLocationManager() { return mContext.getSystemService(LocationManager.class); } - MyHandler getHandler(DeviceIdleController ctlr) { - return ctlr.new MyHandler(BackgroundThread.getHandler().getLooper()); + MyHandler getHandler(DeviceIdleController controller) { + return controller.new MyHandler(BackgroundThread.getHandler().getLooper()); } PowerManager getPowerManager() { @@ -1623,7 +1629,7 @@ public class DeviceIdleController extends SystemService } } - mConstants = new Constants(mHandler, getContext().getContentResolver()); + mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver()); readConfigFileLocked(); updateWhitelistAppIdsLocked(); @@ -2325,6 +2331,16 @@ public class DeviceIdleController extends SystemService } } + /** + * Must only be used in tests. + * + * This sets the state value directly and thus doesn't trigger any behavioral changes. + */ + @VisibleForTesting + void setLightStateForTest(int lightState) { + mLightState = lightState; + } + @VisibleForTesting int getLightState() { return mLightState; @@ -2556,6 +2572,12 @@ public class DeviceIdleController extends SystemService } } + /** Must only be used in tests. */ + @VisibleForTesting + void setActiveIdleOpsForTest(int count) { + mActiveIdleOpCount = count; + } + void setJobsActive(boolean active) { synchronized (this) { mJobsActive = active; diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java index 66650700f599..95ed00f3ad5b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java @@ -51,6 +51,7 @@ import static org.mockito.ArgumentMatchers.anyString; import android.app.ActivityManagerInternal; import android.app.AlarmManager; import android.app.IActivityManager; +import android.content.ContentResolver; import android.content.Context; import android.hardware.SensorManager; import android.location.LocationManager; @@ -59,6 +60,7 @@ import android.os.Handler; import android.os.Looper; import android.os.PowerManager; import android.os.PowerManagerInternal; +import android.os.SystemClock; import androidx.test.runner.AndroidJUnit4; @@ -84,15 +86,17 @@ public class DeviceIdleControllerTest { private MockitoSession mMockingSession; @Mock - private PowerManager mPowerManager; + private AlarmManager mAlarmManager; @Mock - private PowerManager.WakeLock mWakeLock; + private DeviceIdleController.Constants mConstants; @Mock - private AlarmManager mAlarmManager; + private IActivityManager mIActivityManager; @Mock private LocationManager mLocationManager; @Mock - private IActivityManager mIActivityManager; + private PowerManager mPowerManager; + @Mock + private PowerManager.WakeLock mWakeLock; class InjectorForTest extends DeviceIdleController.Injector { @@ -122,12 +126,18 @@ public class DeviceIdleControllerTest { } @Override + DeviceIdleController.Constants getConstants(DeviceIdleController controller, Handler handler, + ContentResolver resolver) { + return mConstants; + } + + @Override LocationManager getLocationManager() { return mLocationManager; } @Override - DeviceIdleController.MyHandler getHandler(DeviceIdleController ctlr) { + DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) { return mock(DeviceIdleController.MyHandler.class); } @@ -452,6 +462,514 @@ public class DeviceIdleControllerTest { verifyStateConditions(STATE_IDLE_MAINTENANCE); } + @Test + public void testExitMaintenanceEarlyIfNeededLocked_deep_noActiveOps() { + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterDeepState(STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE_PENDING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_PENDING); + + enterDeepState(STATE_SENSING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_SENSING); + + enterDeepState(STATE_LOCATING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_LOCATING); + + enterDeepState(STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE); + + enterDeepState(STATE_IDLE_MAINTENANCE); + // Going into IDLE_MAINTENANCE increments the active idle op count. + mDeviceIdleController.setActiveIdleOpsForTest(0); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_deep_activeJobs() { + mDeviceIdleController.setJobsActive(true); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterDeepState(STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE_PENDING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_PENDING); + + enterDeepState(STATE_SENSING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_SENSING); + + enterDeepState(STATE_LOCATING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_LOCATING); + + enterDeepState(STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE); + + enterDeepState(STATE_IDLE_MAINTENANCE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_MAINTENANCE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_deep_activeAlarms() { + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(true); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterDeepState(STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE_PENDING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_PENDING); + + enterDeepState(STATE_SENSING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_SENSING); + + enterDeepState(STATE_LOCATING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_LOCATING); + + enterDeepState(STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE); + + enterDeepState(STATE_IDLE_MAINTENANCE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_MAINTENANCE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_deep_activeOps() { + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(1); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterDeepState(STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE_PENDING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_PENDING); + + enterDeepState(STATE_SENSING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_SENSING); + + enterDeepState(STATE_LOCATING); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_LOCATING); + + enterDeepState(STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE); + + enterDeepState(STATE_IDLE_MAINTENANCE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyStateConditions(STATE_IDLE_MAINTENANCE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_light_noActiveOps() { + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterLightState(LIGHT_STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + + enterLightState(LIGHT_STATE_PRE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK); + + enterLightState(LIGHT_STATE_IDLE_MAINTENANCE); + // Going into IDLE_MAINTENANCE increments the active idle op count. + mDeviceIdleController.setActiveIdleOpsForTest(0); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_OVERRIDE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_OVERRIDE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_light_activeJobs() { + mDeviceIdleController.setJobsActive(true); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterLightState(LIGHT_STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + + enterLightState(LIGHT_STATE_PRE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_PRE_IDLE); + + enterLightState(LIGHT_STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK); + + enterLightState(LIGHT_STATE_IDLE_MAINTENANCE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); + + enterLightState(LIGHT_STATE_OVERRIDE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_OVERRIDE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_light_activeAlarms() { + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(true); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterLightState(LIGHT_STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + + enterLightState(LIGHT_STATE_PRE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_PRE_IDLE); + + enterLightState(LIGHT_STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK); + + enterLightState(LIGHT_STATE_IDLE_MAINTENANCE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); + + enterLightState(LIGHT_STATE_OVERRIDE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_OVERRIDE); + } + + @Test + public void testExitMaintenanceEarlyIfNeededLocked_light_activeOps() { + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(1); + + // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states. + + enterLightState(LIGHT_STATE_ACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_INACTIVE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + + enterLightState(LIGHT_STATE_PRE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_PRE_IDLE); + + enterLightState(LIGHT_STATE_IDLE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK); + + enterLightState(LIGHT_STATE_IDLE_MAINTENANCE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); + + enterLightState(LIGHT_STATE_OVERRIDE); + mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked(); + verifyLightStateConditions(LIGHT_STATE_OVERRIDE); + } + + @Test + public void testHandleMotionDetectedLocked_deep() { + enterDeepState(STATE_ACTIVE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_ACTIVE); + + // Anything that wasn't ACTIVE before motion detection should end up in the INACTIVE state. + + enterDeepState(STATE_INACTIVE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE_PENDING); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_SENSING); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_LOCATING); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_INACTIVE); + + enterDeepState(STATE_IDLE_MAINTENANCE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyStateConditions(STATE_INACTIVE); + } + + @Test + public void testHandleMotionDetectedLocked_light() { + enterLightState(LIGHT_STATE_ACTIVE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + // Motion shouldn't affect light idle, so LIGHT states should stay as they were except for + // OVERRIDE. OVERRIDE means deep was active, so if motion was detected, + // LIGHT_STATE_OVERRIDE should end up as LIGHT_STATE_INACTIVE. + + enterLightState(LIGHT_STATE_INACTIVE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + + enterLightState(LIGHT_STATE_PRE_IDLE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_PRE_IDLE); + + enterLightState(LIGHT_STATE_IDLE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_IDLE); + + enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK); + + enterLightState(LIGHT_STATE_IDLE_MAINTENANCE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); + + enterLightState(LIGHT_STATE_OVERRIDE); + mDeviceIdleController.handleMotionDetectedLocked(50, "test"); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + } + + @Test + public void testbecomeActiveLocked_deep() { + // becomeActiveLocked should put everything into ACTIVE. + + enterDeepState(STATE_ACTIVE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_INACTIVE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_IDLE_PENDING); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_SENSING); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_LOCATING); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_IDLE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + + enterDeepState(STATE_IDLE_MAINTENANCE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyStateConditions(STATE_ACTIVE); + } + + @Test + public void testbecomeActiveLocked_light() { + // becomeActiveLocked should put everything into ACTIVE. + + enterLightState(LIGHT_STATE_ACTIVE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_INACTIVE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_PRE_IDLE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_IDLE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_IDLE_MAINTENANCE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + + enterLightState(LIGHT_STATE_OVERRIDE); + mDeviceIdleController.becomeActiveLocked("test", 1000); + verifyLightStateConditions(LIGHT_STATE_ACTIVE); + } + + private void enterDeepState(int state) { + switch (state) { + case STATE_ACTIVE: + setScreenOn(true); + mDeviceIdleController.becomeActiveLocked("testing", 0); + break; + case STATE_LOCATING: + doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider( + anyString()); + // Fallthrough to step loop. + case STATE_IDLE_PENDING: + case STATE_SENSING: + case STATE_IDLE: + case STATE_IDLE_MAINTENANCE: + // Make sure the controller doesn't think there's a wake-from-idle alarm coming + // soon. + doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime(); + case STATE_INACTIVE: + setScreenOn(false); + setChargingOn(false); + mDeviceIdleController.becomeInactiveIfAppropriateLocked(); + //fail(stateToString(mDeviceIdleController.getState())); + int count = 0; + while (mDeviceIdleController.getState() != state) { + // Stepping through each state ensures that the proper features are turned + // on/off. + mDeviceIdleController.stepIdleStateLocked("testing"); + count++; + if (count > 10) { + fail(stateToString(mDeviceIdleController.getState())); + } + } + break; + default: + fail("Unknown deep state " + stateToString(state)); + } + } + + private void enterLightState(int lightState) { + switch (lightState) { + case LIGHT_STATE_ACTIVE: + setScreenOn(true); + mDeviceIdleController.becomeActiveLocked("testing", 0); + break; + case LIGHT_STATE_INACTIVE: + case LIGHT_STATE_IDLE: + case LIGHT_STATE_IDLE_MAINTENANCE: + setScreenOn(false); + setChargingOn(false); + int count = 0; + mDeviceIdleController.becomeInactiveIfAppropriateLocked(); + while (mDeviceIdleController.getLightState() != lightState) { + // Stepping through each state ensures that the proper features are turned + // on/off. + mDeviceIdleController.stepLightIdleStateLocked("testing"); + + count++; + if (count > 10) { + fail(lightStateToString(mDeviceIdleController.getLightState())); + } + } + break; + case LIGHT_STATE_PRE_IDLE: + case LIGHT_STATE_WAITING_FOR_NETWORK: + case LIGHT_STATE_OVERRIDE: + setScreenOn(false); + setChargingOn(false); + mDeviceIdleController.setLightStateForTest(lightState); + break; + default: + fail("Unknown light state " + lightStateToString(lightState)); + } + } + private void setChargingOn(boolean on) { mDeviceIdleController.updateChargingLocked(on); } @@ -525,7 +1043,10 @@ public class DeviceIdleControllerTest { switch (expectedLightState) { case LIGHT_STATE_ACTIVE: assertTrue( - mDeviceIdleController.isCharging() || mDeviceIdleController.isScreenOn()); + mDeviceIdleController.isCharging() || mDeviceIdleController.isScreenOn() + // Or there's an alarm coming up soon. + || SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM + > mAlarmManager.getNextWakeFromIdleTime()); break; case LIGHT_STATE_INACTIVE: case LIGHT_STATE_PRE_IDLE: |