Merge "Ensure AlarmManager knows of IDLE state." into udc-dev
This commit is contained in:
@@ -2402,7 +2402,6 @@ public class DeviceIdleController extends SystemService
|
||||
return mConstants;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the current elapsed realtime in milliseconds. */
|
||||
long getElapsedRealtime() {
|
||||
return SystemClock.elapsedRealtime();
|
||||
@@ -3819,6 +3818,7 @@ public class DeviceIdleController extends SystemService
|
||||
|
||||
// Everything is in place to go into IDLE state.
|
||||
case STATE_IDLE_MAINTENANCE:
|
||||
moveToStateLocked(STATE_IDLE, reason);
|
||||
scheduleAlarmLocked(mNextIdleDelay, true);
|
||||
if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
|
||||
" ms.");
|
||||
@@ -3829,7 +3829,6 @@ public class DeviceIdleController extends SystemService
|
||||
if (mNextIdleDelay < mConstants.IDLE_TIMEOUT) {
|
||||
mNextIdleDelay = mConstants.IDLE_TIMEOUT;
|
||||
}
|
||||
moveToStateLocked(STATE_IDLE, reason);
|
||||
if (mLightState != LIGHT_STATE_OVERRIDE) {
|
||||
moveToLightStateLocked(LIGHT_STATE_OVERRIDE, "deep");
|
||||
cancelLightAlarmLocked();
|
||||
@@ -3842,6 +3841,7 @@ public class DeviceIdleController extends SystemService
|
||||
// We have been idling long enough, now it is time to do some work.
|
||||
mActiveIdleOpCount = 1;
|
||||
mActiveIdleWakeLock.acquire();
|
||||
moveToStateLocked(STATE_IDLE_MAINTENANCE, reason);
|
||||
scheduleAlarmLocked(mNextIdlePendingDelay, false);
|
||||
if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
|
||||
"Next alarm in " + mNextIdlePendingDelay + " ms.");
|
||||
@@ -3851,7 +3851,6 @@ public class DeviceIdleController extends SystemService
|
||||
if (mNextIdlePendingDelay < mConstants.IDLE_PENDING_TIMEOUT) {
|
||||
mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
|
||||
}
|
||||
moveToStateLocked(STATE_IDLE_MAINTENANCE, reason);
|
||||
addEvent(EVENT_DEEP_MAINTENANCE, null);
|
||||
mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
|
||||
break;
|
||||
|
||||
@@ -154,6 +154,7 @@ public class DeviceIdleControllerTest {
|
||||
ConstraintController constraintController;
|
||||
// Freeze time for testing.
|
||||
long nowElapsed;
|
||||
boolean useMotionSensor = true;
|
||||
|
||||
InjectorForTest(Context ctx) {
|
||||
super(ctx);
|
||||
@@ -245,7 +246,7 @@ public class DeviceIdleControllerTest {
|
||||
|
||||
@Override
|
||||
boolean useMotionSensor() {
|
||||
return true;
|
||||
return useMotionSensor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +346,12 @@ public class DeviceIdleControllerTest {
|
||||
mAnyMotionDetector = new AnyMotionDetectorForTest();
|
||||
mInjector = new InjectorForTest(getContext());
|
||||
|
||||
setupDeviceIdleController();
|
||||
}
|
||||
|
||||
private void setupDeviceIdleController() {
|
||||
reset(mTelephonyManager);
|
||||
|
||||
mDeviceIdleController = new DeviceIdleController(getContext(), mInjector);
|
||||
spyOn(mDeviceIdleController);
|
||||
doNothing().when(mDeviceIdleController).publishBinderService(any(), any());
|
||||
@@ -371,6 +378,10 @@ public class DeviceIdleControllerTest {
|
||||
if (mMockingSession != null) {
|
||||
mMockingSession.finishMocking();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanupDeviceIdleController() {
|
||||
// DeviceIdleController adds these to LocalServices in the constructor, so we have to remove
|
||||
// them after each test, otherwise, subsequent tests will fail.
|
||||
LocalServices.removeServiceForTest(AppStateTracker.class);
|
||||
@@ -617,6 +628,60 @@ public class DeviceIdleControllerTest {
|
||||
.scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT), eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStateActiveToStateInactive_DoNotUseMotionSensor() {
|
||||
mInjector.useMotionSensor = false;
|
||||
cleanupDeviceIdleController();
|
||||
setupDeviceIdleController();
|
||||
mDeviceIdleController.becomeActiveLocked("testing", 0);
|
||||
verifyStateConditions(STATE_ACTIVE);
|
||||
|
||||
setAlarmSoon(false);
|
||||
setChargingOn(false);
|
||||
setScreenOn(false);
|
||||
setEmergencyCallActive(false);
|
||||
|
||||
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
|
||||
verifyStateConditions(STATE_INACTIVE);
|
||||
verify(mDeviceIdleController)
|
||||
.scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT), eq(false));
|
||||
// The device configuration doesn't require a motion sensor to proceed with idling.
|
||||
// This should be the case on TVs or other such devices. We should set an alarm to move
|
||||
// forward if the motion sensor is missing in this case.
|
||||
verify(mAlarmManager).setWindow(
|
||||
anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStateActiveToStateInactive_MissingMotionSensor() {
|
||||
mInjector.useMotionSensor = true;
|
||||
mMotionSensor = null;
|
||||
cleanupDeviceIdleController();
|
||||
setupDeviceIdleController();
|
||||
mDeviceIdleController.becomeActiveLocked("testing", 0);
|
||||
verifyStateConditions(STATE_ACTIVE);
|
||||
|
||||
setAlarmSoon(false);
|
||||
setChargingOn(false);
|
||||
setScreenOn(false);
|
||||
setEmergencyCallActive(false);
|
||||
|
||||
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
|
||||
verifyStateConditions(STATE_INACTIVE);
|
||||
verify(mDeviceIdleController)
|
||||
.scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT), eq(false));
|
||||
// The device configuration requires a motion sensor to proceed with idling,
|
||||
// so we should never set an alarm to move forward if the motion sensor is
|
||||
// missing in this case.
|
||||
verify(mAlarmManager, never()).setWindow(
|
||||
anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
verify(mAlarmManager, never()).set(
|
||||
anyInt(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStateActiveToStateInactive_UpcomingAlarm() {
|
||||
final long timeUntilAlarm = mConstants.MIN_TIME_TO_ALARM / 2;
|
||||
@@ -756,6 +821,94 @@ public class DeviceIdleControllerTest {
|
||||
verifyStateConditions(STATE_IDLE_MAINTENANCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStepIdleStateLocked_ValidStates_MissingMotionSensor() {
|
||||
mInjector.useMotionSensor = true;
|
||||
mMotionSensor = null;
|
||||
cleanupDeviceIdleController();
|
||||
setupDeviceIdleController();
|
||||
mInjector.locationManager = mLocationManager;
|
||||
doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
|
||||
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
|
||||
setAlarmSoon(false);
|
||||
|
||||
InOrder alarmManagerInOrder = inOrder(mAlarmManager);
|
||||
|
||||
// Set state to INACTIVE.
|
||||
mDeviceIdleController.becomeActiveLocked("testing", 0);
|
||||
setChargingOn(false);
|
||||
setScreenOn(false);
|
||||
verifyStateConditions(STATE_INACTIVE);
|
||||
|
||||
// The device configuration requires a motion sensor to proceed with idling,
|
||||
// so we should never set an alarm to move forward if the motion sensor is
|
||||
// missing in this case.
|
||||
alarmManagerInOrder.verify(mAlarmManager, never())
|
||||
.setWindow(anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
// Pretend that someone is forcing state stepping via adb
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
// verifyStateConditions knows this state typically shouldn't happen during normal
|
||||
// operation, so we can't use it directly here. For this test, all we care about
|
||||
// is that the state stepped forward.
|
||||
assertEquals(STATE_IDLE_PENDING, mDeviceIdleController.getState());
|
||||
// Still no alarm
|
||||
alarmManagerInOrder.verify(mAlarmManager, never())
|
||||
.setWindow(anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
// verifyStateConditions knows this state typically shouldn't happen during normal
|
||||
// operation, so we can't use it directly here. For this test, all we care about
|
||||
// is that the state stepped forward.
|
||||
assertEquals(STATE_SENSING, mDeviceIdleController.getState());
|
||||
// Still no alarm
|
||||
alarmManagerInOrder.verify(mAlarmManager, never())
|
||||
.setWindow(anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
// Location manager exists with a provider, so SENSING should go to LOCATING.
|
||||
// verifyStateConditions knows this state typically shouldn't happen during normal
|
||||
// operation, so we can't use it directly here. For this test, all we care about
|
||||
// is that the state stepped forward.
|
||||
assertEquals(STATE_LOCATING, mDeviceIdleController.getState());
|
||||
// Still no alarm
|
||||
alarmManagerInOrder.verify(mAlarmManager, never())
|
||||
.setWindow(anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
verifyStateConditions(STATE_IDLE);
|
||||
// The device was forced into IDLE. AlarmManager should be notified.
|
||||
alarmManagerInOrder.verify(mAlarmManager)
|
||||
.setIdleUntil(anyInt(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
// Should just alternate between IDLE and IDLE_MAINTENANCE now. Since we've gotten to this
|
||||
// point, alarms should be set on each transition.
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
verifyStateConditions(STATE_IDLE_MAINTENANCE);
|
||||
alarmManagerInOrder.verify(mAlarmManager)
|
||||
.setWindow(anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
verifyStateConditions(STATE_IDLE);
|
||||
alarmManagerInOrder.verify(mAlarmManager)
|
||||
.setIdleUntil(anyInt(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
|
||||
mDeviceIdleController.stepIdleStateLocked("testing");
|
||||
verifyStateConditions(STATE_IDLE_MAINTENANCE);
|
||||
alarmManagerInOrder.verify(mAlarmManager)
|
||||
.setWindow(anyInt(), anyLong(), anyLong(),
|
||||
eq("DeviceIdleController.deep"), any(), any(Handler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStepIdleStateLocked_ValidStates_WithWakeFromIdleAlarmSoon() {
|
||||
enterDeepState(STATE_ACTIVE);
|
||||
|
||||
Reference in New Issue
Block a user