Loading services/core/java/com/android/server/AlarmManagerInternal.java +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ public interface AlarmManagerInternal { void broadcastAlarmComplete(int recipientUid); } /** Returns true if AlarmManager is delaying alarms due to device idle. */ boolean isIdling(); public void removeAlarmsForUid(int uid); public void registerInFlightListener(InFlightListener callback); } services/core/java/com/android/server/AlarmManagerService.java +11 −0 Original line number Diff line number Diff line Loading @@ -1990,6 +1990,11 @@ class AlarmManagerService extends SystemService { * System-process internal API */ private final class LocalService implements AlarmManagerInternal { @Override public boolean isIdling() { return isIdlingImpl(); } @Override public void removeAlarmsForUid(int uid) { synchronized (mLock) { Loading Loading @@ -2823,6 +2828,12 @@ class AlarmManagerService extends SystemService { } } private boolean isIdlingImpl() { synchronized (mLock) { return mPendingIdleUntil != null; } } AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { synchronized (mLock) { return mNextAlarmClockForUser.get(userId); Loading services/core/java/com/android/server/DeviceIdleController.java +110 −75 Original line number Diff line number Diff line Loading @@ -271,6 +271,7 @@ public class DeviceIdleController extends SystemService private static final int EVENT_BUFFER_SIZE = 100; private AlarmManager mAlarmManager; private AlarmManagerInternal mLocalAlarmManager; private IBatteryStats mBatteryStats; private ActivityManagerInternal mLocalActivityManager; private ActivityTaskManagerInternal mLocalActivityTaskManager; Loading Loading @@ -616,7 +617,8 @@ public class DeviceIdleController extends SystemService } }; private final AlarmManager.OnAlarmListener mDeepAlarmListener @VisibleForTesting final AlarmManager.OnAlarmListener mDeepAlarmListener = new AlarmManager.OnAlarmListener() { @Override public void onAlarm() { Loading Loading @@ -1874,6 +1876,7 @@ public class DeviceIdleController extends SystemService if (phase == PHASE_SYSTEM_SERVICES_READY) { synchronized (this) { mAlarmManager = mInjector.getAlarmManager(); mLocalAlarmManager = getLocalService(AlarmManagerInternal.class); mBatteryStats = BatteryStatsService.getService(); mLocalActivityManager = getLocalService(ActivityManagerInternal.class); mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class); Loading Loading @@ -2605,6 +2608,16 @@ public class DeviceIdleController extends SystemService // next natural time to come out of it. } /** Returns true if the screen is locked. */ @VisibleForTesting boolean isKeyguardShowing() { synchronized (this) { return mScreenLocked; } } @VisibleForTesting void keyguardShowingLocked(boolean showing) { if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing); if (mScreenLocked != showing) { Loading @@ -2616,27 +2629,40 @@ public class DeviceIdleController extends SystemService } } @VisibleForTesting void scheduleReportActiveLocked(String activeReason, int activeUid) { Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason); mHandler.sendMessage(msg); } void becomeActiveLocked(String activeReason, int activeUid) { if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason); becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true); } private void becomeActiveLocked(String activeReason, int activeUid, long newInactiveTimeout, boolean changeLightIdle) { if (DEBUG) { Slog.i(TAG, "becomeActiveLocked, reason=" + activeReason + ", changeLightIdle=" + changeLightIdle); } if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) { EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason); EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); scheduleReportActiveLocked(activeReason, activeUid); mState = STATE_ACTIVE; mLightState = LIGHT_STATE_ACTIVE; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; mInactiveTimeout = newInactiveTimeout; mCurIdleBudget = 0; mMaintenanceStartTime = 0; resetIdleManagementLocked(); if (changeLightIdle) { EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); mLightState = LIGHT_STATE_ACTIVE; resetLightIdleManagementLocked(); // Only report active if light is also ACTIVE. scheduleReportActiveLocked(activeReason, activeUid); addEvent(EVENT_NORMAL, activeReason); } } } /** Must only be used in tests. */ @VisibleForTesting Loading @@ -2654,9 +2680,42 @@ public class DeviceIdleController extends SystemService } } /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */ private void verifyAlarmStateLocked() { if (mState == STATE_ACTIVE && mNextAlarmTime != 0) { Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime); } if (mState != STATE_IDLE && mLocalAlarmManager.isIdling()) { Slog.wtf(TAG, "mState=" + stateToString(mState) + " but AlarmManager is idling"); } if (mState == STATE_IDLE && !mLocalAlarmManager.isIdling()) { Slog.wtf(TAG, "mState=IDLE but AlarmManager is not idling"); } if (mLightState == LIGHT_STATE_ACTIVE && mNextLightAlarmTime != 0) { Slog.wtf(TAG, "mLightState=ACTIVE but mNextLightAlarmTime is " + TimeUtils.formatDuration(mNextLightAlarmTime - SystemClock.elapsedRealtime()) + " from now"); } } void becomeInactiveIfAppropriateLocked() { if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()"); if ((!mScreenOn && !mCharging) || mForceIdle) { verifyAlarmStateLocked(); final boolean isScreenBlockingInactive = mScreenOn && (!mConstants.WAIT_FOR_UNLOCK || !mScreenLocked); if (DEBUG) { Slog.d(TAG, "becomeInactiveIfAppropriateLocked():" + " isScreenBlockingInactive=" + isScreenBlockingInactive + " (mScreenOn=" + mScreenOn + ", WAIT_FOR_UNLOCK=" + mConstants.WAIT_FOR_UNLOCK + ", mScreenLocked=" + mScreenLocked + ")" + " mCharging=" + mCharging + " mForceIdle=" + mForceIdle ); } if (!mForceIdle && (mCharging || isScreenBlockingInactive)) { return; } // Become inactive and determine if we will ultimately go idle. if (mDeepEnabled) { if (mQuickDozeActivated) { Loading Loading @@ -2698,7 +2757,6 @@ public class DeviceIdleController extends SystemService EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); } } } private void resetIdleManagementLocked() { mNextIdlePendingDelay = 0; Loading Loading @@ -3216,33 +3274,10 @@ public class DeviceIdleController extends SystemService // The device is not yet active, so we want to go back to the pending idle // state to wait again for no motion. Note that we only monitor for motion // after moving out of the inactive state, so no need to worry about that. boolean becomeInactive = false; if (mState != STATE_ACTIVE) { // Motion shouldn't affect light state, if it's already in doze-light or maintenance boolean lightIdle = mLightState == LIGHT_STATE_IDLE || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK || mLightState == LIGHT_STATE_IDLE_MAINTENANCE; if (!lightIdle) { // Only switch to active state if we're not in either idle state scheduleReportActiveLocked(type, Process.myUid()); addEvent(EVENT_NORMAL, type); } mActiveReason = ACTIVE_REASON_MOTION; mState = STATE_ACTIVE; mInactiveTimeout = timeout; mCurIdleBudget = 0; mMaintenanceStartTime = 0; EventLogTags.writeDeviceIdle(mState, type); becomeInactive = true; updateActiveConstraintsLocked(); } if (mLightState == LIGHT_STATE_OVERRIDE) { // We went out of light idle mode because we had started deep idle mode... let's // now go back and reset things so we resume light idling if appropriate. mLightState = LIGHT_STATE_ACTIVE; EventLogTags.writeDeviceIdleLight(mLightState, type); becomeInactive = true; } final boolean becomeInactive = mState != STATE_ACTIVE || mLightState == LIGHT_STATE_OVERRIDE; // We only want to change the IDLE state if it's OVERRIDE. becomeActiveLocked(type, Process.myUid(), timeout, mLightState == LIGHT_STATE_OVERRIDE); if (becomeInactive) { becomeInactiveIfAppropriateLocked(); } Loading services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +217 −13 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import static androidx.test.InstrumentationRegistry.getContext; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; Loading Loading @@ -51,6 +52,9 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import android.app.ActivityManagerInternal; import android.app.AlarmManager; Loading Loading @@ -82,6 +86,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; Loading @@ -105,6 +110,8 @@ public class DeviceIdleControllerTest { @Mock private ContentResolver mContentResolver; @Mock private DeviceIdleController.MyHandler mHandler; @Mock private IActivityManager mIActivityManager; @Mock private LocationManager mLocationManager; Loading Loading @@ -154,7 +161,7 @@ public class DeviceIdleControllerTest { @Override DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) { return mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS); return mHandler; } @Override Loading Loading @@ -232,10 +239,12 @@ public class DeviceIdleControllerTest { .when(() -> LocalServices.getService(ActivityManagerInternal.class)); doReturn(mock(ActivityTaskManagerInternal.class)) .when(() -> LocalServices.getService(ActivityTaskManagerInternal.class)); doReturn(mock(AlarmManagerInternal.class)) .when(() -> LocalServices.getService(AlarmManagerInternal.class)); doReturn(mPowerManagerInternal) .when(() -> LocalServices.getService(PowerManagerInternal.class)); when(mPowerManagerInternal.getLowPowerState(anyInt())).thenReturn( mock(PowerSaveState.class)); when(mPowerManagerInternal.getLowPowerState(anyInt())) .thenReturn(mock(PowerSaveState.class)); doReturn(mock(NetworkPolicyManagerInternal.class)) .when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class)); when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock); Loading @@ -246,8 +255,11 @@ public class DeviceIdleControllerTest { doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt()); mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper()); mAnyMotionDetector = new AnyMotionDetectorForTest(); mHandler = mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS); doNothing().when(mHandler).handleMessage(any()); mInjector = new InjectorForTest(getContext()); doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any()); mDeviceIdleController = new DeviceIdleController(getContext(), mInjector); spyOn(mDeviceIdleController); doNothing().when(mDeviceIdleController).publishBinderService(any(), any()); Loading Loading @@ -423,6 +435,29 @@ public class DeviceIdleControllerTest { mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); mConstants.WAIT_FOR_UNLOCK = false; setScreenLocked(true); setScreenOn(true); setChargingOn(false); mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); setScreenLocked(false); setScreenOn(true); setChargingOn(false); mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); mConstants.WAIT_FOR_UNLOCK = true; setScreenLocked(false); setScreenOn(true); setChargingOn(false); mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); } @Test Loading Loading @@ -1307,7 +1342,7 @@ public class DeviceIdleControllerTest { } @Test public void testbecomeActiveLocked_deep() { public void testBecomeActiveLocked_deep() { // becomeActiveLocked should put everything into ACTIVE. enterDeepState(STATE_ACTIVE); Loading Loading @@ -1344,7 +1379,7 @@ public class DeviceIdleControllerTest { } @Test public void testbecomeActiveLocked_light() { public void testBecomeActiveLocked_light() { // becomeActiveLocked should put everything into ACTIVE. enterLightState(LIGHT_STATE_ACTIVE); Loading Loading @@ -1376,6 +1411,163 @@ public class DeviceIdleControllerTest { verifyLightStateConditions(LIGHT_STATE_ACTIVE); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_ScreenThenMotion() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(true); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself // shouldn't bring the device out of deep IDLE. verifyStateConditions(STATE_IDLE); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // Motion should bring the device out of Doze. Since the screen is still locked (albeit // on), the states should go back into INACTIVE. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener)); verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt()); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_ScreenThenMotion() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(false); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener)); verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt()); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_MotionThenScreen() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); InOrder alarmManagerInOrder = inOrder(mAlarmManager); InOrder controllerInOrder = inOrder(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(true); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // The screen is still off, so motion should result in the INACTIVE state. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself // shouldn't bring the device all the way to ACTIVE. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager, never()).cancel( eq(mDeviceIdleController.mDeepAlarmListener)); // User finally unlocks the device. Device should be fully active. mDeviceIdleController.keyguardShowingLocked(false); verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_MotionThenScreen() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); InOrder alarmManagerInOrder = inOrder(mAlarmManager); InOrder controllerInOrder = inOrder(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(false); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // The screen is still off, so motion should result in the INACTIVE state. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); } @Test public void testExitNotifiesDependencies_WaitForUnlockOff_Screen() { mConstants.WAIT_FOR_UNLOCK = false; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); setScreenOn(true); // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener)); verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt()); } @Test public void testExitNotifiesDependencies_WaitForUnlockOff_MotionThenScreen() { mConstants.WAIT_FOR_UNLOCK = false; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); InOrder alarmManagerInOrder = inOrder(mAlarmManager); InOrder controllerInOrder = inOrder(mDeviceIdleController); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // The screen is still off, so motion should result in the INACTIVE state. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); setScreenOn(true); // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); } @Test public void testStepToIdleMode() { float delta = mDeviceIdleController.MIN_PRE_IDLE_FACTOR_CHANGE; Loading Loading @@ -1508,6 +1700,10 @@ public class DeviceIdleControllerTest { mDeviceIdleController.updateChargingLocked(on); } private void setScreenLocked(boolean locked) { mDeviceIdleController.keyguardShowingLocked(locked); } private void setScreenOn(boolean on) { doReturn(on).when(mPowerManager).isInteractive(); mDeviceIdleController.updateInteractivityLocked(); Loading Loading @@ -1549,7 +1745,8 @@ public class DeviceIdleControllerTest { assertFalse(mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_IDLE_PENDING: assertEquals( Loading @@ -1557,7 +1754,8 @@ public class DeviceIdleControllerTest { mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_SENSING: assertEquals( Loading @@ -1567,14 +1765,16 @@ public class DeviceIdleControllerTest { mDeviceIdleController.hasMotionSensor(), mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_LOCATING: assertEquals( mDeviceIdleController.hasMotionSensor(), mDeviceIdleController.mMotionListener.isActive()); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_IDLE: if (mDeviceIdleController.hasMotionSensor()) { Loading @@ -1584,7 +1784,8 @@ public class DeviceIdleControllerTest { } assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); // Light state should be OVERRIDE at this point. verifyLightStateConditions(LIGHT_STATE_OVERRIDE); break; Loading @@ -1596,14 +1797,16 @@ public class DeviceIdleControllerTest { } assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_QUICK_DOZE_DELAY: // If quick doze is enabled, the motion listener should NOT be active. assertFalse(mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; default: fail("Conditions for " + stateToString(expectedState) + " unknown."); Loading Loading @@ -1632,7 +1835,8 @@ public class DeviceIdleControllerTest { case LIGHT_STATE_IDLE_MAINTENANCE: case LIGHT_STATE_OVERRIDE: assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; default: fail("Conditions for " + lightStateToString(expectedLightState) + " unknown."); Loading Loading
services/core/java/com/android/server/AlarmManagerInternal.java +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ public interface AlarmManagerInternal { void broadcastAlarmComplete(int recipientUid); } /** Returns true if AlarmManager is delaying alarms due to device idle. */ boolean isIdling(); public void removeAlarmsForUid(int uid); public void registerInFlightListener(InFlightListener callback); }
services/core/java/com/android/server/AlarmManagerService.java +11 −0 Original line number Diff line number Diff line Loading @@ -1990,6 +1990,11 @@ class AlarmManagerService extends SystemService { * System-process internal API */ private final class LocalService implements AlarmManagerInternal { @Override public boolean isIdling() { return isIdlingImpl(); } @Override public void removeAlarmsForUid(int uid) { synchronized (mLock) { Loading Loading @@ -2823,6 +2828,12 @@ class AlarmManagerService extends SystemService { } } private boolean isIdlingImpl() { synchronized (mLock) { return mPendingIdleUntil != null; } } AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { synchronized (mLock) { return mNextAlarmClockForUser.get(userId); Loading
services/core/java/com/android/server/DeviceIdleController.java +110 −75 Original line number Diff line number Diff line Loading @@ -271,6 +271,7 @@ public class DeviceIdleController extends SystemService private static final int EVENT_BUFFER_SIZE = 100; private AlarmManager mAlarmManager; private AlarmManagerInternal mLocalAlarmManager; private IBatteryStats mBatteryStats; private ActivityManagerInternal mLocalActivityManager; private ActivityTaskManagerInternal mLocalActivityTaskManager; Loading Loading @@ -616,7 +617,8 @@ public class DeviceIdleController extends SystemService } }; private final AlarmManager.OnAlarmListener mDeepAlarmListener @VisibleForTesting final AlarmManager.OnAlarmListener mDeepAlarmListener = new AlarmManager.OnAlarmListener() { @Override public void onAlarm() { Loading Loading @@ -1874,6 +1876,7 @@ public class DeviceIdleController extends SystemService if (phase == PHASE_SYSTEM_SERVICES_READY) { synchronized (this) { mAlarmManager = mInjector.getAlarmManager(); mLocalAlarmManager = getLocalService(AlarmManagerInternal.class); mBatteryStats = BatteryStatsService.getService(); mLocalActivityManager = getLocalService(ActivityManagerInternal.class); mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class); Loading Loading @@ -2605,6 +2608,16 @@ public class DeviceIdleController extends SystemService // next natural time to come out of it. } /** Returns true if the screen is locked. */ @VisibleForTesting boolean isKeyguardShowing() { synchronized (this) { return mScreenLocked; } } @VisibleForTesting void keyguardShowingLocked(boolean showing) { if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing); if (mScreenLocked != showing) { Loading @@ -2616,27 +2629,40 @@ public class DeviceIdleController extends SystemService } } @VisibleForTesting void scheduleReportActiveLocked(String activeReason, int activeUid) { Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid, 0, activeReason); mHandler.sendMessage(msg); } void becomeActiveLocked(String activeReason, int activeUid) { if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason); becomeActiveLocked(activeReason, activeUid, mConstants.INACTIVE_TIMEOUT, true); } private void becomeActiveLocked(String activeReason, int activeUid, long newInactiveTimeout, boolean changeLightIdle) { if (DEBUG) { Slog.i(TAG, "becomeActiveLocked, reason=" + activeReason + ", changeLightIdle=" + changeLightIdle); } if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) { EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason); EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); scheduleReportActiveLocked(activeReason, activeUid); mState = STATE_ACTIVE; mLightState = LIGHT_STATE_ACTIVE; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; mInactiveTimeout = newInactiveTimeout; mCurIdleBudget = 0; mMaintenanceStartTime = 0; resetIdleManagementLocked(); if (changeLightIdle) { EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason); mLightState = LIGHT_STATE_ACTIVE; resetLightIdleManagementLocked(); // Only report active if light is also ACTIVE. scheduleReportActiveLocked(activeReason, activeUid); addEvent(EVENT_NORMAL, activeReason); } } } /** Must only be used in tests. */ @VisibleForTesting Loading @@ -2654,9 +2680,42 @@ public class DeviceIdleController extends SystemService } } /** Sanity check to make sure DeviceIdleController and AlarmManager are on the same page. */ private void verifyAlarmStateLocked() { if (mState == STATE_ACTIVE && mNextAlarmTime != 0) { Slog.wtf(TAG, "mState=ACTIVE but mNextAlarmTime=" + mNextAlarmTime); } if (mState != STATE_IDLE && mLocalAlarmManager.isIdling()) { Slog.wtf(TAG, "mState=" + stateToString(mState) + " but AlarmManager is idling"); } if (mState == STATE_IDLE && !mLocalAlarmManager.isIdling()) { Slog.wtf(TAG, "mState=IDLE but AlarmManager is not idling"); } if (mLightState == LIGHT_STATE_ACTIVE && mNextLightAlarmTime != 0) { Slog.wtf(TAG, "mLightState=ACTIVE but mNextLightAlarmTime is " + TimeUtils.formatDuration(mNextLightAlarmTime - SystemClock.elapsedRealtime()) + " from now"); } } void becomeInactiveIfAppropriateLocked() { if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()"); if ((!mScreenOn && !mCharging) || mForceIdle) { verifyAlarmStateLocked(); final boolean isScreenBlockingInactive = mScreenOn && (!mConstants.WAIT_FOR_UNLOCK || !mScreenLocked); if (DEBUG) { Slog.d(TAG, "becomeInactiveIfAppropriateLocked():" + " isScreenBlockingInactive=" + isScreenBlockingInactive + " (mScreenOn=" + mScreenOn + ", WAIT_FOR_UNLOCK=" + mConstants.WAIT_FOR_UNLOCK + ", mScreenLocked=" + mScreenLocked + ")" + " mCharging=" + mCharging + " mForceIdle=" + mForceIdle ); } if (!mForceIdle && (mCharging || isScreenBlockingInactive)) { return; } // Become inactive and determine if we will ultimately go idle. if (mDeepEnabled) { if (mQuickDozeActivated) { Loading Loading @@ -2698,7 +2757,6 @@ public class DeviceIdleController extends SystemService EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); } } } private void resetIdleManagementLocked() { mNextIdlePendingDelay = 0; Loading Loading @@ -3216,33 +3274,10 @@ public class DeviceIdleController extends SystemService // The device is not yet active, so we want to go back to the pending idle // state to wait again for no motion. Note that we only monitor for motion // after moving out of the inactive state, so no need to worry about that. boolean becomeInactive = false; if (mState != STATE_ACTIVE) { // Motion shouldn't affect light state, if it's already in doze-light or maintenance boolean lightIdle = mLightState == LIGHT_STATE_IDLE || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK || mLightState == LIGHT_STATE_IDLE_MAINTENANCE; if (!lightIdle) { // Only switch to active state if we're not in either idle state scheduleReportActiveLocked(type, Process.myUid()); addEvent(EVENT_NORMAL, type); } mActiveReason = ACTIVE_REASON_MOTION; mState = STATE_ACTIVE; mInactiveTimeout = timeout; mCurIdleBudget = 0; mMaintenanceStartTime = 0; EventLogTags.writeDeviceIdle(mState, type); becomeInactive = true; updateActiveConstraintsLocked(); } if (mLightState == LIGHT_STATE_OVERRIDE) { // We went out of light idle mode because we had started deep idle mode... let's // now go back and reset things so we resume light idling if appropriate. mLightState = LIGHT_STATE_ACTIVE; EventLogTags.writeDeviceIdleLight(mLightState, type); becomeInactive = true; } final boolean becomeInactive = mState != STATE_ACTIVE || mLightState == LIGHT_STATE_OVERRIDE; // We only want to change the IDLE state if it's OVERRIDE. becomeActiveLocked(type, Process.myUid(), timeout, mLightState == LIGHT_STATE_OVERRIDE); if (becomeInactive) { becomeInactiveIfAppropriateLocked(); } Loading
services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +217 −13 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import static androidx.test.InstrumentationRegistry.getContext; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; Loading Loading @@ -51,6 +52,9 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import android.app.ActivityManagerInternal; import android.app.AlarmManager; Loading Loading @@ -82,6 +86,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; Loading @@ -105,6 +110,8 @@ public class DeviceIdleControllerTest { @Mock private ContentResolver mContentResolver; @Mock private DeviceIdleController.MyHandler mHandler; @Mock private IActivityManager mIActivityManager; @Mock private LocationManager mLocationManager; Loading Loading @@ -154,7 +161,7 @@ public class DeviceIdleControllerTest { @Override DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) { return mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS); return mHandler; } @Override Loading Loading @@ -232,10 +239,12 @@ public class DeviceIdleControllerTest { .when(() -> LocalServices.getService(ActivityManagerInternal.class)); doReturn(mock(ActivityTaskManagerInternal.class)) .when(() -> LocalServices.getService(ActivityTaskManagerInternal.class)); doReturn(mock(AlarmManagerInternal.class)) .when(() -> LocalServices.getService(AlarmManagerInternal.class)); doReturn(mPowerManagerInternal) .when(() -> LocalServices.getService(PowerManagerInternal.class)); when(mPowerManagerInternal.getLowPowerState(anyInt())).thenReturn( mock(PowerSaveState.class)); when(mPowerManagerInternal.getLowPowerState(anyInt())) .thenReturn(mock(PowerSaveState.class)); doReturn(mock(NetworkPolicyManagerInternal.class)) .when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class)); when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock); Loading @@ -246,8 +255,11 @@ public class DeviceIdleControllerTest { doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt()); mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper()); mAnyMotionDetector = new AnyMotionDetectorForTest(); mHandler = mock(DeviceIdleController.MyHandler.class, Answers.RETURNS_DEEP_STUBS); doNothing().when(mHandler).handleMessage(any()); mInjector = new InjectorForTest(getContext()); doNothing().when(mContentResolver).registerContentObserver(any(), anyBoolean(), any()); mDeviceIdleController = new DeviceIdleController(getContext(), mInjector); spyOn(mDeviceIdleController); doNothing().when(mDeviceIdleController).publishBinderService(any(), any()); Loading Loading @@ -423,6 +435,29 @@ public class DeviceIdleControllerTest { mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); mConstants.WAIT_FOR_UNLOCK = false; setScreenLocked(true); setScreenOn(true); setChargingOn(false); mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); setScreenLocked(false); setScreenOn(true); setChargingOn(false); mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); mConstants.WAIT_FOR_UNLOCK = true; setScreenLocked(false); setScreenOn(true); setChargingOn(false); mDeviceIdleController.becomeInactiveIfAppropriateLocked(); verifyStateConditions(STATE_ACTIVE); } @Test Loading Loading @@ -1307,7 +1342,7 @@ public class DeviceIdleControllerTest { } @Test public void testbecomeActiveLocked_deep() { public void testBecomeActiveLocked_deep() { // becomeActiveLocked should put everything into ACTIVE. enterDeepState(STATE_ACTIVE); Loading Loading @@ -1344,7 +1379,7 @@ public class DeviceIdleControllerTest { } @Test public void testbecomeActiveLocked_light() { public void testBecomeActiveLocked_light() { // becomeActiveLocked should put everything into ACTIVE. enterLightState(LIGHT_STATE_ACTIVE); Loading Loading @@ -1376,6 +1411,163 @@ public class DeviceIdleControllerTest { verifyLightStateConditions(LIGHT_STATE_ACTIVE); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_ScreenThenMotion() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(true); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself // shouldn't bring the device out of deep IDLE. verifyStateConditions(STATE_IDLE); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // Motion should bring the device out of Doze. Since the screen is still locked (albeit // on), the states should go back into INACTIVE. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener)); verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt()); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_ScreenThenMotion() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(false); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener)); verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt()); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_MotionThenScreen() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); InOrder alarmManagerInOrder = inOrder(mAlarmManager); InOrder controllerInOrder = inOrder(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(true); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // The screen is still off, so motion should result in the INACTIVE state. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself // shouldn't bring the device all the way to ACTIVE. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager, never()).cancel( eq(mDeviceIdleController.mDeepAlarmListener)); // User finally unlocks the device. Device should be fully active. mDeviceIdleController.keyguardShowingLocked(false); verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); } /** Test based on b/119058625. */ @Test public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_MotionThenScreen() { mConstants.WAIT_FOR_UNLOCK = true; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); InOrder alarmManagerInOrder = inOrder(mAlarmManager); InOrder controllerInOrder = inOrder(mDeviceIdleController); mDeviceIdleController.keyguardShowingLocked(false); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // The screen is still off, so motion should result in the INACTIVE state. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); setScreenOn(true); // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); } @Test public void testExitNotifiesDependencies_WaitForUnlockOff_Screen() { mConstants.WAIT_FOR_UNLOCK = false; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); setScreenOn(true); // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener)); verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt()); } @Test public void testExitNotifiesDependencies_WaitForUnlockOff_MotionThenScreen() { mConstants.WAIT_FOR_UNLOCK = false; enterDeepState(STATE_IDLE); reset(mAlarmManager); spyOn(mDeviceIdleController); InOrder alarmManagerInOrder = inOrder(mAlarmManager); InOrder controllerInOrder = inOrder(mDeviceIdleController); mDeviceIdleController.handleMotionDetectedLocked(1000, "test"); // The screen is still off, so motion should result in the INACTIVE state. verifyStateConditions(STATE_INACTIVE); verifyLightStateConditions(LIGHT_STATE_INACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); setScreenOn(true); // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself // should bring the device out of deep IDLE. verifyStateConditions(STATE_ACTIVE); verifyLightStateConditions(LIGHT_STATE_ACTIVE); alarmManagerInOrder.verify(mAlarmManager) .cancel(eq(mDeviceIdleController.mDeepAlarmListener)); controllerInOrder.verify(mDeviceIdleController) .scheduleReportActiveLocked(anyString(), anyInt()); } @Test public void testStepToIdleMode() { float delta = mDeviceIdleController.MIN_PRE_IDLE_FACTOR_CHANGE; Loading Loading @@ -1508,6 +1700,10 @@ public class DeviceIdleControllerTest { mDeviceIdleController.updateChargingLocked(on); } private void setScreenLocked(boolean locked) { mDeviceIdleController.keyguardShowingLocked(locked); } private void setScreenOn(boolean on) { doReturn(on).when(mPowerManager).isInteractive(); mDeviceIdleController.updateInteractivityLocked(); Loading Loading @@ -1549,7 +1745,8 @@ public class DeviceIdleControllerTest { assertFalse(mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_IDLE_PENDING: assertEquals( Loading @@ -1557,7 +1754,8 @@ public class DeviceIdleControllerTest { mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_SENSING: assertEquals( Loading @@ -1567,14 +1765,16 @@ public class DeviceIdleControllerTest { mDeviceIdleController.hasMotionSensor(), mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_LOCATING: assertEquals( mDeviceIdleController.hasMotionSensor(), mDeviceIdleController.mMotionListener.isActive()); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_IDLE: if (mDeviceIdleController.hasMotionSensor()) { Loading @@ -1584,7 +1784,8 @@ public class DeviceIdleControllerTest { } assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); // Light state should be OVERRIDE at this point. verifyLightStateConditions(LIGHT_STATE_OVERRIDE); break; Loading @@ -1596,14 +1797,16 @@ public class DeviceIdleControllerTest { } assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; case STATE_QUICK_DOZE_DELAY: // If quick doze is enabled, the motion listener should NOT be active. assertFalse(mDeviceIdleController.mMotionListener.isActive()); assertFalse(mAnyMotionDetector.isMonitoring); assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; default: fail("Conditions for " + stateToString(expectedState) + " unknown."); Loading Loading @@ -1632,7 +1835,8 @@ public class DeviceIdleControllerTest { case LIGHT_STATE_IDLE_MAINTENANCE: case LIGHT_STATE_OVERRIDE: assertFalse(mDeviceIdleController.isCharging()); assertFalse(mDeviceIdleController.isScreenOn()); assertFalse(mDeviceIdleController.isScreenOn() && !mDeviceIdleController.isKeyguardShowing()); break; default: fail("Conditions for " + lightStateToString(expectedLightState) + " unknown."); Loading