1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server;
17 
18 import static androidx.test.InstrumentationRegistry.getContext;
19 
20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
27 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
28 import static com.android.server.DeviceIdleController.LIGHT_STATE_ACTIVE;
29 import static com.android.server.DeviceIdleController.LIGHT_STATE_IDLE;
30 import static com.android.server.DeviceIdleController.LIGHT_STATE_IDLE_MAINTENANCE;
31 import static com.android.server.DeviceIdleController.LIGHT_STATE_INACTIVE;
32 import static com.android.server.DeviceIdleController.LIGHT_STATE_OVERRIDE;
33 import static com.android.server.DeviceIdleController.LIGHT_STATE_WAITING_FOR_NETWORK;
34 import static com.android.server.DeviceIdleController.MSG_REPORT_STATIONARY_STATUS;
35 import static com.android.server.DeviceIdleController.MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR;
36 import static com.android.server.DeviceIdleController.MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR;
37 import static com.android.server.DeviceIdleController.STATE_ACTIVE;
38 import static com.android.server.DeviceIdleController.STATE_IDLE;
39 import static com.android.server.DeviceIdleController.STATE_IDLE_MAINTENANCE;
40 import static com.android.server.DeviceIdleController.STATE_IDLE_PENDING;
41 import static com.android.server.DeviceIdleController.STATE_INACTIVE;
42 import static com.android.server.DeviceIdleController.STATE_LOCATING;
43 import static com.android.server.DeviceIdleController.STATE_QUICK_DOZE_DELAY;
44 import static com.android.server.DeviceIdleController.STATE_SENSING;
45 import static com.android.server.DeviceIdleController.lightStateToString;
46 import static com.android.server.DeviceIdleController.stateToString;
47 
48 import static org.junit.Assert.assertEquals;
49 import static org.junit.Assert.assertFalse;
50 import static org.junit.Assert.assertTrue;
51 import static org.junit.Assert.fail;
52 import static org.mockito.ArgumentMatchers.any;
53 import static org.mockito.ArgumentMatchers.anyInt;
54 import static org.mockito.ArgumentMatchers.anyLong;
55 import static org.mockito.ArgumentMatchers.anyString;
56 import static org.mockito.ArgumentMatchers.argThat;
57 import static org.mockito.ArgumentMatchers.eq;
58 import static org.mockito.ArgumentMatchers.longThat;
59 import static org.mockito.Mockito.atLeastOnce;
60 import static org.mockito.Mockito.never;
61 import static org.mockito.Mockito.reset;
62 import static org.mockito.Mockito.timeout;
63 import static org.mockito.Mockito.verify;
64 
65 import android.app.ActivityManagerInternal;
66 import android.app.AlarmManager;
67 import android.app.IActivityManager;
68 import android.content.Context;
69 import android.content.Intent;
70 import android.hardware.Sensor;
71 import android.hardware.SensorEvent;
72 import android.hardware.SensorEventListener;
73 import android.hardware.SensorManager;
74 import android.hardware.TriggerEvent;
75 import android.hardware.TriggerEventListener;
76 import android.location.LocationManager;
77 import android.location.LocationProvider;
78 import android.net.ConnectivityManager;
79 import android.net.NetworkInfo;
80 import android.os.Handler;
81 import android.os.Looper;
82 import android.os.Message;
83 import android.os.PowerManager;
84 import android.os.PowerManagerInternal;
85 import android.os.PowerSaveState;
86 import android.os.SystemClock;
87 import android.provider.DeviceConfig;
88 import android.telephony.TelephonyCallback;
89 import android.telephony.TelephonyManager;
90 import android.telephony.emergency.EmergencyNumber;
91 
92 import androidx.test.runner.AndroidJUnit4;
93 
94 import com.android.server.deviceidle.ConstraintController;
95 import com.android.server.net.NetworkPolicyManagerInternal;
96 import com.android.server.wm.ActivityTaskManagerInternal;
97 
98 import org.junit.After;
99 import org.junit.Before;
100 import org.junit.Test;
101 import org.junit.runner.RunWith;
102 import org.mockito.ArgumentCaptor;
103 import org.mockito.ArgumentMatchers;
104 import org.mockito.InOrder;
105 import org.mockito.Mock;
106 import org.mockito.MockitoSession;
107 import org.mockito.invocation.InvocationOnMock;
108 import org.mockito.quality.Strictness;
109 import org.mockito.stubbing.Answer;
110 
111 import java.util.concurrent.Executor;
112 
113 /**
114  * Tests for {@link com.android.server.DeviceIdleController}.
115  */
116 @SuppressWarnings("GuardedBy")
117 @RunWith(AndroidJUnit4.class)
118 public class DeviceIdleControllerTest {
119     private DeviceIdleController mDeviceIdleController;
120     private DeviceIdleController.MyHandler mHandler;
121     private AnyMotionDetectorForTest mAnyMotionDetector;
122     private AppStateTrackerForTest mAppStateTracker;
123     private DeviceIdleController.Constants mConstants;
124     private TelephonyCallback.OutgoingEmergencyCallListener mEmergencyCallListener;
125     private TelephonyCallback.CallStateListener mCallStateListener;
126     private InjectorForTest mInjector;
127 
128     private MockitoSession mMockingSession;
129     @Mock
130     private AlarmManager mAlarmManager;
131     @Mock
132     private ConnectivityManager mConnectivityManager;
133     @Mock
134     private IActivityManager mIActivityManager;
135     @Mock
136     private LocationManager mLocationManager;
137     @Mock
138     private PowerManager mPowerManager;
139     @Mock
140     private PowerManager.WakeLock mWakeLock;
141     @Mock
142     private PowerManagerInternal mPowerManagerInternal;
143     @Mock
144     private Sensor mMotionSensor;
145     @Mock
146     private SensorManager mSensorManager;
147     @Mock
148     private TelephonyManager mTelephonyManager;
149 
150     class InjectorForTest extends DeviceIdleController.Injector {
151         ConnectivityManager connectivityManager;
152         LocationManager locationManager;
153         ConstraintController constraintController;
154         // Freeze time for testing.
155         long nowElapsed;
156         boolean useMotionSensor = true;
157         boolean isLocationPrefetchEnabled = true;
158 
InjectorForTest(Context ctx)159         InjectorForTest(Context ctx) {
160             super(ctx);
161             nowElapsed = SystemClock.elapsedRealtime();
162         }
163 
164         @Override
getAlarmManager()165         AlarmManager getAlarmManager() {
166             return mAlarmManager;
167         }
168 
169         @Override
getAnyMotionDetector(Handler handler, SensorManager sm, AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold)170         AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
171                 AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
172             return mAnyMotionDetector;
173         }
174 
175         @Override
getAppStateTracker(Context ctx, Looper loop)176         AppStateTrackerImpl getAppStateTracker(Context ctx, Looper loop) {
177             return mAppStateTracker;
178         }
179 
180         @Override
getConnectivityManager()181         ConnectivityManager getConnectivityManager() {
182             return connectivityManager;
183         }
184 
185         @Override
getElapsedRealtime()186         long getElapsedRealtime() {
187             return nowElapsed;
188         }
189 
190         @Override
getLocationManager()191         LocationManager getLocationManager() {
192             return locationManager;
193         }
194 
195         @Override
getHandler(DeviceIdleController controller)196         DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) {
197             if (mHandler == null) {
198                 mHandler = controller.new MyHandler(getContext().getMainLooper());
199                 spyOn(mHandler);
200                 doNothing().when(mHandler).handleMessage(argThat((message) ->
201                         message.what != MSG_REPORT_STATIONARY_STATUS
202                         && message.what != MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR
203                         && message.what != MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR));
204                 doAnswer(new Answer<Boolean>() {
205                     @Override
206                     public Boolean answer(InvocationOnMock invocation) throws Throwable {
207                         Message msg = invocation.getArgument(0);
208                         mHandler.handleMessage(msg);
209                         return true;
210                     }
211                 }).when(mHandler).sendMessageDelayed(
212                         argThat((message) -> message.what == MSG_REPORT_STATIONARY_STATUS
213                                 || message.what == MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR
214                                 || message.what == MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR),
215                         anyLong());
216             }
217 
218             return mHandler;
219         }
220 
221         @Override
getMotionSensor()222         Sensor getMotionSensor() {
223             return mMotionSensor;
224         }
225 
226         @Override
isLocationPrefetchEnabled()227         boolean isLocationPrefetchEnabled() {
228             return isLocationPrefetchEnabled;
229         }
230 
231         @Override
getPowerManager()232         PowerManager getPowerManager() {
233             return mPowerManager;
234         }
235 
236         @Override
getSensorManager()237         SensorManager getSensorManager() {
238             return mSensorManager;
239         }
240 
241         @Override
getConstraintController( Handler handler, DeviceIdleInternal localService)242         ConstraintController getConstraintController(
243                 Handler handler, DeviceIdleInternal localService) {
244             return constraintController;
245         }
246 
247         @Override
getTelephonyManager()248         TelephonyManager getTelephonyManager() {
249             return mTelephonyManager;
250         }
251 
252         @Override
useMotionSensor()253         boolean useMotionSensor() {
254             return useMotionSensor;
255         }
256     }
257 
258     private class AnyMotionDetectorForTest extends AnyMotionDetector {
259         boolean isMonitoring = false;
260 
AnyMotionDetectorForTest()261         AnyMotionDetectorForTest() {
262             super(mPowerManager, mock(Handler.class), mSensorManager,
263                     mock(DeviceIdleCallback.class), 0.5f);
264         }
265 
266         @Override
hasSensor()267         public boolean hasSensor() {
268             return true;
269         }
270 
271         @Override
checkForAnyMotion()272         public void checkForAnyMotion() {
273             isMonitoring = true;
274         }
275 
276         @Override
stop()277         public void stop() {
278             isMonitoring = false;
279         }
280     }
281 
282     private class AppStateTrackerForTest extends AppStateTrackerImpl {
AppStateTrackerForTest(Context ctx, Looper looper)283         AppStateTrackerForTest(Context ctx, Looper looper) {
284             super(ctx, looper);
285         }
286 
287         @Override
onSystemServicesReady()288         public void onSystemServicesReady() {
289             // Do nothing.
290         }
291 
292         @Override
injectIActivityManager()293         IActivityManager injectIActivityManager() {
294             return mIActivityManager;
295         }
296     }
297 
298     private class StationaryListenerForTest implements DeviceIdleInternal.StationaryListener {
299         boolean motionExpected = false;
300         boolean isStationary = false;
301 
302         @Override
onDeviceStationaryChanged(boolean isStationary)303         public void onDeviceStationaryChanged(boolean isStationary) {
304             if (isStationary == motionExpected) {
305                 fail("Got unexpected device stationary status: " + isStationary);
306             }
307             this.isStationary = isStationary;
308         }
309     }
310 
311     @Before
setUp()312     public void setUp() {
313         mMockingSession = mockitoSession()
314                 .initMocks(this)
315                 .strictness(Strictness.LENIENT)
316                 .spyStatic(DeviceConfig.class)
317                 .spyStatic(LocalServices.class)
318                 .startMocking();
319         spyOn(getContext());
320         doReturn(null).when(getContext()).registerReceiver(any(), any());
321         doReturn(mock(ActivityManagerInternal.class))
322                 .when(() -> LocalServices.getService(ActivityManagerInternal.class));
323         doReturn(mock(ActivityTaskManagerInternal.class))
324                 .when(() -> LocalServices.getService(ActivityTaskManagerInternal.class));
325         doReturn(mock(AlarmManagerInternal.class))
326                 .when(() -> LocalServices.getService(AlarmManagerInternal.class));
327         doReturn(mPowerManagerInternal)
328                 .when(() -> LocalServices.getService(PowerManagerInternal.class));
329         when(mPowerManagerInternal.getLowPowerState(anyInt()))
330                 .thenReturn(mock(PowerSaveState.class));
331         doReturn(mock(NetworkPolicyManagerInternal.class))
332                 .when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class));
333         doAnswer((Answer<Void>) invocationOnMock -> null)
334                 .when(() -> DeviceConfig.addOnPropertiesChangedListener(
335                         anyString(), any(Executor.class),
336                         any(DeviceConfig.OnPropertiesChangedListener.class)));
337         doAnswer((Answer<DeviceConfig.Properties>) invocationOnMock
338                 -> mock(DeviceConfig.Properties.class))
339                 .when(() -> DeviceConfig.getProperties(
340                         anyString(), ArgumentMatchers.<String>any()));
341         when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
342         doNothing().when(mWakeLock).acquire();
343         doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any());
344         doNothing().when(mAlarmManager).setExact(anyInt(), anyLong(), anyString(), any(), any());
345         doNothing().when(mAlarmManager)
346                 .setWindow(anyInt(), anyLong(), anyLong(), anyString(), any(), any(Handler.class));
347         doReturn(mock(Sensor.class)).when(mSensorManager)
348                 .getDefaultSensor(eq(Sensor.TYPE_SIGNIFICANT_MOTION), eq(true));
349         doReturn(true).when(mSensorManager).registerListener(any(), any(), anyInt());
350         mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
351         mAnyMotionDetector = new AnyMotionDetectorForTest();
352         mInjector = new InjectorForTest(getContext());
353 
354         setupDeviceIdleController();
355     }
356 
setupDeviceIdleController()357     private void setupDeviceIdleController() {
358         reset(mTelephonyManager);
359 
360         mDeviceIdleController = new DeviceIdleController(getContext(), mInjector);
361         spyOn(mDeviceIdleController);
362         doNothing().when(mDeviceIdleController).publishBinderService(any(), any());
363         mDeviceIdleController.onStart();
364         mDeviceIdleController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
365         mDeviceIdleController.setDeepEnabledForTest(true);
366         mDeviceIdleController.setLightEnabledForTest(true);
367 
368         // Get the same Constants object that mDeviceIdleController got.
369         mConstants = mInjector.getConstants(mDeviceIdleController);
370 
371         final ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor =
372                 ArgumentCaptor.forClass(TelephonyCallback.class);
373         verify(mTelephonyManager)
374                 .registerTelephonyCallback(any(), telephonyCallbackCaptor.capture());
375         mEmergencyCallListener = (TelephonyCallback.OutgoingEmergencyCallListener)
376                 telephonyCallbackCaptor.getValue();
377         mCallStateListener =
378                 (TelephonyCallback.CallStateListener) telephonyCallbackCaptor.getValue();
379     }
380 
381     @After
tearDown()382     public void tearDown() {
383         if (mMockingSession != null) {
384             mMockingSession.finishMocking();
385         }
386     }
387 
388     @After
cleanupDeviceIdleController()389     public void cleanupDeviceIdleController() {
390         // DeviceIdleController adds these to LocalServices in the constructor, so we have to remove
391         // them after each test, otherwise, subsequent tests will fail.
392         LocalServices.removeServiceForTest(AppStateTracker.class);
393         LocalServices.removeServiceForTest(DeviceIdleInternal.class);
394         LocalServices.removeServiceForTest(PowerAllowlistInternal.class);
395     }
396 
397     @Test
testUpdateInteractivityLocked()398     public void testUpdateInteractivityLocked() {
399         doReturn(false).when(mPowerManager).isInteractive();
400         mDeviceIdleController.updateInteractivityLocked();
401         assertFalse(mDeviceIdleController.isScreenOn());
402 
403         // Make sure setting false when screen is already off doesn't change anything.
404         doReturn(false).when(mPowerManager).isInteractive();
405         mDeviceIdleController.updateInteractivityLocked();
406         assertFalse(mDeviceIdleController.isScreenOn());
407 
408         // Test changing from screen off to screen on.
409         doReturn(true).when(mPowerManager).isInteractive();
410         mDeviceIdleController.updateInteractivityLocked();
411         assertTrue(mDeviceIdleController.isScreenOn());
412 
413         // Make sure setting true when screen is already on doesn't change anything.
414         doReturn(true).when(mPowerManager).isInteractive();
415         mDeviceIdleController.updateInteractivityLocked();
416         assertTrue(mDeviceIdleController.isScreenOn());
417 
418         // Test changing from screen on to screen off.
419         doReturn(false).when(mPowerManager).isInteractive();
420         mDeviceIdleController.updateInteractivityLocked();
421         assertFalse(mDeviceIdleController.isScreenOn());
422     }
423 
424     @Test
testUpdateChargingLocked()425     public void testUpdateChargingLocked() {
426         mDeviceIdleController.updateChargingLocked(false);
427         assertFalse(mDeviceIdleController.isCharging());
428 
429         // Make sure setting false when charging is already off doesn't change anything.
430         mDeviceIdleController.updateChargingLocked(false);
431         assertFalse(mDeviceIdleController.isCharging());
432 
433         // Test changing from charging off to charging on.
434         mDeviceIdleController.updateChargingLocked(true);
435         assertTrue(mDeviceIdleController.isCharging());
436 
437         // Make sure setting true when charging is already on doesn't change anything.
438         mDeviceIdleController.updateChargingLocked(true);
439         assertTrue(mDeviceIdleController.isCharging());
440 
441         // Test changing from charging on to charging off.
442         mDeviceIdleController.updateChargingLocked(false);
443         assertFalse(mDeviceIdleController.isCharging());
444     }
445 
446     @Test
testUpdateConnectivityState()447     public void testUpdateConnectivityState() {
448         // No connectivity service
449         final boolean isConnected = mDeviceIdleController.isNetworkConnected();
450         mInjector.connectivityManager = null;
451         mDeviceIdleController.updateConnectivityState(null);
452         assertEquals(isConnected, mDeviceIdleController.isNetworkConnected());
453 
454         // No active network info
455         mInjector.connectivityManager = mConnectivityManager;
456         doReturn(null).when(mConnectivityManager).getActiveNetworkInfo();
457         mDeviceIdleController.updateConnectivityState(null);
458         assertFalse(mDeviceIdleController.isNetworkConnected());
459 
460         // Active network info says connected.
461         final NetworkInfo ani = mock(NetworkInfo.class);
462         doReturn(ani).when(mConnectivityManager).getActiveNetworkInfo();
463         doReturn(true).when(ani).isConnected();
464         mDeviceIdleController.updateConnectivityState(null);
465         assertTrue(mDeviceIdleController.isNetworkConnected());
466 
467         // Active network info says not connected.
468         doReturn(false).when(ani).isConnected();
469         mDeviceIdleController.updateConnectivityState(null);
470         assertFalse(mDeviceIdleController.isNetworkConnected());
471 
472         // Wrong intent passed (false).
473         Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
474         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3);
475         doReturn(true).when(ani).isConnected();
476         doReturn(1).when(ani).getType();
477         mDeviceIdleController.updateConnectivityState(intent);
478         // Wrong intent means we shouldn't update the connected state.
479         assertFalse(mDeviceIdleController.isNetworkConnected());
480 
481         // Intent says connected.
482         doReturn(1).when(ani).getType();
483         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1);
484         intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
485         mDeviceIdleController.updateConnectivityState(intent);
486         assertTrue(mDeviceIdleController.isNetworkConnected());
487 
488         // Wrong intent passed (true).
489         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3);
490         // Wrong intent means we shouldn't update the connected state.
491         assertTrue(mDeviceIdleController.isNetworkConnected());
492 
493         // Intent says not connected.
494         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1);
495         intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
496         mDeviceIdleController.updateConnectivityState(intent);
497         assertFalse(mDeviceIdleController.isNetworkConnected());
498     }
499 
500     @Test
testUpdateQuickDozeFlagLocked()501     public void testUpdateQuickDozeFlagLocked() {
502         mDeviceIdleController.updateQuickDozeFlagLocked(false);
503         assertFalse(mDeviceIdleController.isQuickDozeEnabled());
504 
505         // Make sure setting false when quick doze is already off doesn't change anything.
506         mDeviceIdleController.updateQuickDozeFlagLocked(false);
507         assertFalse(mDeviceIdleController.isQuickDozeEnabled());
508 
509         // Test changing from quick doze off to quick doze on.
510         mDeviceIdleController.updateQuickDozeFlagLocked(true);
511         assertTrue(mDeviceIdleController.isQuickDozeEnabled());
512 
513         // Make sure setting true when quick doze is already on doesn't change anything.
514         mDeviceIdleController.updateQuickDozeFlagLocked(true);
515         assertTrue(mDeviceIdleController.isQuickDozeEnabled());
516 
517         // Test changing from quick doze on to quick doze off.
518         mDeviceIdleController.updateQuickDozeFlagLocked(false);
519         assertFalse(mDeviceIdleController.isQuickDozeEnabled());
520     }
521 
522     @Test
testStateActiveToStateInactive_ConditionsNotMet()523     public void testStateActiveToStateInactive_ConditionsNotMet() {
524         mDeviceIdleController.becomeActiveLocked("testing", 0);
525         verifyStateConditions(STATE_ACTIVE);
526 
527         // State should stay ACTIVE with screen on and charging.
528         setChargingOn(true);
529         setScreenOn(true);
530 
531         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
532         verifyStateConditions(STATE_ACTIVE);
533 
534         // State should stay ACTIVE with charging on.
535         setChargingOn(true);
536         setScreenOn(false);
537 
538         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
539         verifyStateConditions(STATE_ACTIVE);
540 
541         // State should stay ACTIVE with screen on.
542         // Note the different operation order here makes sure the state doesn't change before test.
543         setScreenOn(true);
544         setChargingOn(false);
545 
546         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
547         verifyStateConditions(STATE_ACTIVE);
548 
549         mConstants.WAIT_FOR_UNLOCK = false;
550         setScreenLocked(true);
551         setScreenOn(true);
552         setChargingOn(false);
553 
554         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
555         verifyStateConditions(STATE_ACTIVE);
556 
557         setScreenLocked(false);
558         setScreenOn(true);
559         setChargingOn(false);
560 
561         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
562         verifyStateConditions(STATE_ACTIVE);
563 
564         mConstants.WAIT_FOR_UNLOCK = true;
565         setScreenLocked(false);
566         setScreenOn(true);
567         setChargingOn(false);
568 
569         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
570         verifyStateConditions(STATE_ACTIVE);
571 
572         // All other conditions allow for going INACTIVE...
573         setAlarmSoon(false);
574         setChargingOn(false);
575         setScreenOn(false);
576         // ...except the emergency call.
577         setEmergencyCallActive(true);
578 
579         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
580         verifyStateConditions(STATE_ACTIVE);
581     }
582 
583     @Test
testLightStateActiveToLightStateInactive_ConditionsNotMet()584     public void testLightStateActiveToLightStateInactive_ConditionsNotMet() {
585         mDeviceIdleController.becomeActiveLocked("testing", 0);
586         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
587 
588         // State should stay ACTIVE with screen on and charging.
589         setChargingOn(true);
590         setScreenOn(true);
591 
592         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
593         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
594 
595         // State should stay ACTIVE with charging on.
596         setChargingOn(true);
597         setScreenOn(false);
598 
599         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
600         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
601 
602         // State should stay ACTIVE with screen on.
603         // Note the different operation order here makes sure the state doesn't change before test.
604         setScreenOn(true);
605         setChargingOn(false);
606 
607         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
608         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
609 
610         // All other conditions allow for going INACTIVE...
611         setChargingOn(false);
612         setScreenOn(false);
613         // ...except the emergency call.
614         setEmergencyCallActive(true);
615 
616         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
617         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
618     }
619 
620     @Test
testStateActiveToStateInactive_ConditionsMet()621     public void testStateActiveToStateInactive_ConditionsMet() {
622         mDeviceIdleController.becomeActiveLocked("testing", 0);
623         verifyStateConditions(STATE_ACTIVE);
624 
625         setAlarmSoon(false);
626         setChargingOn(false);
627         setScreenOn(false);
628         setEmergencyCallActive(false);
629 
630         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
631         verifyStateConditions(STATE_INACTIVE);
632         verify(mDeviceIdleController).scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT));
633     }
634 
635     @Test
testStateActiveToStateInactive_DoNotUseMotionSensor()636     public void testStateActiveToStateInactive_DoNotUseMotionSensor() {
637         mInjector.useMotionSensor = false;
638         cleanupDeviceIdleController();
639         setupDeviceIdleController();
640         mDeviceIdleController.becomeActiveLocked("testing", 0);
641         verifyStateConditions(STATE_ACTIVE);
642 
643         setAlarmSoon(false);
644         setChargingOn(false);
645         setScreenOn(false);
646         setEmergencyCallActive(false);
647 
648         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
649         verifyStateConditions(STATE_INACTIVE);
650         verify(mDeviceIdleController).scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT));
651         // The device configuration doesn't require a motion sensor to proceed with idling.
652         // This should be the case on TVs or other such devices. We should set an alarm to move
653         // forward if the motion sensor is missing in this case.
654         verify(mAlarmManager).setWindow(
655                 anyInt(), anyLong(), anyLong(),
656                 eq("DeviceIdleController.deep"), any(), any(Handler.class));
657     }
658 
659     @Test
testStateActiveToStateInactive_MissingMotionSensor()660     public void testStateActiveToStateInactive_MissingMotionSensor() {
661         mInjector.useMotionSensor = true;
662         mMotionSensor = null;
663         cleanupDeviceIdleController();
664         setupDeviceIdleController();
665         mDeviceIdleController.becomeActiveLocked("testing", 0);
666         verifyStateConditions(STATE_ACTIVE);
667 
668         setAlarmSoon(false);
669         setChargingOn(false);
670         setScreenOn(false);
671         setEmergencyCallActive(false);
672 
673         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
674         verifyStateConditions(STATE_INACTIVE);
675         verify(mDeviceIdleController).scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT));
676         // The device configuration requires a motion sensor to proceed with idling,
677         // so we should never set an alarm to move forward if the motion sensor is
678         // missing in this case.
679         verify(mAlarmManager, never()).setWindow(
680                 anyInt(), anyLong(), anyLong(),
681                 eq("DeviceIdleController.deep"), any(), any(Handler.class));
682         verify(mAlarmManager, never()).set(
683                 anyInt(), anyLong(),
684                 eq("DeviceIdleController.deep"), any(), any(Handler.class));
685     }
686 
687     @Test
testStateActiveToStateInactive_UpcomingAlarm()688     public void testStateActiveToStateInactive_UpcomingAlarm() {
689         final long timeUntilAlarm = mConstants.MIN_TIME_TO_ALARM / 2;
690         // Set an upcoming alarm that will prevent full idle.
691         doReturn(mInjector.getElapsedRealtime() + timeUntilAlarm)
692                 .when(mAlarmManager).getNextWakeFromIdleTime();
693 
694         InOrder inOrder = inOrder(mDeviceIdleController);
695 
696         enterDeepState(STATE_ACTIVE);
697         setQuickDozeEnabled(false);
698         setChargingOn(false);
699         setScreenOn(false);
700 
701         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
702         verifyStateConditions(STATE_INACTIVE);
703         inOrder.verify(mDeviceIdleController)
704                 .scheduleAlarmLocked(eq(timeUntilAlarm + mConstants.INACTIVE_TIMEOUT));
705 
706         enterDeepState(STATE_ACTIVE);
707         setQuickDozeEnabled(true);
708         setChargingOn(false);
709         setScreenOn(false);
710 
711         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
712         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
713         inOrder.verify(mDeviceIdleController).scheduleAlarmLocked(
714                 eq(timeUntilAlarm + mConstants.QUICK_DOZE_DELAY_TIMEOUT));
715     }
716 
717     @Test
testLightStateActiveToLightStateInactive_ConditionsMet()718     public void testLightStateActiveToLightStateInactive_ConditionsMet() {
719         mDeviceIdleController.becomeActiveLocked("testing", 0);
720         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
721 
722         setChargingOn(false);
723         setScreenOn(false);
724         setEmergencyCallActive(false);
725 
726         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
727         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
728     }
729 
730     @Test
testTransitionFromAnyStateToStateQuickDozeDelay()731     public void testTransitionFromAnyStateToStateQuickDozeDelay() {
732         setAlarmSoon(false);
733         InOrder inOrder = inOrder(mDeviceIdleController);
734 
735         enterDeepState(STATE_ACTIVE);
736         setQuickDozeEnabled(true);
737         setChargingOn(false);
738         setScreenOn(false);
739         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
740         inOrder.verify(mDeviceIdleController)
741                 .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
742 
743         enterDeepState(STATE_INACTIVE);
744         setQuickDozeEnabled(true);
745         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
746         inOrder.verify(mDeviceIdleController)
747                 .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
748 
749         enterDeepState(STATE_IDLE_PENDING);
750         setQuickDozeEnabled(true);
751         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
752         inOrder.verify(mDeviceIdleController)
753                 .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
754 
755         enterDeepState(STATE_SENSING);
756         setQuickDozeEnabled(true);
757         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
758         inOrder.verify(mDeviceIdleController)
759                 .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
760 
761         enterDeepState(STATE_LOCATING);
762         setQuickDozeEnabled(true);
763         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
764         inOrder.verify(mDeviceIdleController)
765                 .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
766 
767         // IDLE should stay as IDLE.
768         enterDeepState(STATE_IDLE);
769         // Clear out any alarm setting from the order before checking for this section.
770         inOrder.verify(mDeviceIdleController, atLeastOnce()).scheduleAlarmLocked(anyLong());
771         setQuickDozeEnabled(true);
772         verifyStateConditions(STATE_IDLE);
773         inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong());
774 
775         // IDLE_MAINTENANCE should stay as IDLE_MAINTENANCE.
776         enterDeepState(STATE_IDLE_MAINTENANCE);
777         // Clear out any alarm setting from the order before checking for this section.
778         inOrder.verify(mDeviceIdleController, atLeastOnce()).scheduleAlarmLocked(anyLong());
779         setQuickDozeEnabled(true);
780         verifyStateConditions(STATE_IDLE_MAINTENANCE);
781         inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong());
782 
783         // State is already QUICK_DOZE_DELAY. No work should be done.
784         enterDeepState(STATE_QUICK_DOZE_DELAY);
785         // Clear out any alarm setting from the order before checking for this section.
786         inOrder.verify(mDeviceIdleController, atLeastOnce()).scheduleAlarmLocked(anyLong());
787         setQuickDozeEnabled(true);
788         mDeviceIdleController.becomeInactiveIfAppropriateLocked();
789         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
790         inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong());
791     }
792 
793     @Test
testStepIdleStateLocked_InvalidStates()794     public void testStepIdleStateLocked_InvalidStates() {
795         mDeviceIdleController.becomeActiveLocked("testing", 0);
796         mDeviceIdleController.stepIdleStateLocked("testing");
797         // mDeviceIdleController.stepIdleStateLocked doesn't handle the ACTIVE case, so the state
798         // should stay as ACTIVE.
799         verifyStateConditions(STATE_ACTIVE);
800     }
801 
802     @Test
testStepIdleStateLocked_ValidStates_QuickDoze()803     public void testStepIdleStateLocked_ValidStates_QuickDoze() {
804         setAlarmSoon(false);
805 
806         // Quick doze should go directly into IDLE.
807         enterDeepState(STATE_QUICK_DOZE_DELAY);
808         mDeviceIdleController.stepIdleStateLocked("testing");
809         verifyStateConditions(STATE_IDLE);
810 
811         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
812 
813         mDeviceIdleController.stepIdleStateLocked("testing");
814         verifyStateConditions(STATE_IDLE_MAINTENANCE);
815 
816         mDeviceIdleController.stepIdleStateLocked("testing");
817         verifyStateConditions(STATE_IDLE);
818 
819         mDeviceIdleController.stepIdleStateLocked("testing");
820         verifyStateConditions(STATE_IDLE_MAINTENANCE);
821     }
822 
823     @Test
testStepIdleStateLocked_ValidStates_MissingMotionSensor()824     public void testStepIdleStateLocked_ValidStates_MissingMotionSensor() {
825         mInjector.useMotionSensor = true;
826         mMotionSensor = null;
827         cleanupDeviceIdleController();
828         setupDeviceIdleController();
829         mInjector.locationManager = mLocationManager;
830         doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
831         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
832         setAlarmSoon(false);
833 
834         InOrder alarmManagerInOrder = inOrder(mAlarmManager);
835 
836         // Set state to INACTIVE.
837         mDeviceIdleController.becomeActiveLocked("testing", 0);
838         setChargingOn(false);
839         setScreenOn(false);
840         verifyStateConditions(STATE_INACTIVE);
841 
842         // The device configuration requires a motion sensor to proceed with idling,
843         // so we should never set an alarm to move forward if the motion sensor is
844         // missing in this case.
845         alarmManagerInOrder.verify(mAlarmManager, never())
846                 .setWindow(anyInt(), anyLong(), anyLong(),
847                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
848 
849         // Pretend that someone is forcing state stepping via adb
850 
851         mDeviceIdleController.stepIdleStateLocked("testing");
852         // verifyStateConditions knows this state typically shouldn't happen during normal
853         // operation, so we can't use it directly here. For this test, all we care about
854         // is that the state stepped forward.
855         assertEquals(STATE_IDLE_PENDING, mDeviceIdleController.getState());
856         // Still no alarm
857         alarmManagerInOrder.verify(mAlarmManager, never())
858                 .setWindow(anyInt(), anyLong(), anyLong(),
859                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
860 
861         mDeviceIdleController.stepIdleStateLocked("testing");
862         // verifyStateConditions knows this state typically shouldn't happen during normal
863         // operation, so we can't use it directly here. For this test, all we care about
864         // is that the state stepped forward.
865         assertEquals(STATE_SENSING, mDeviceIdleController.getState());
866         // Still no alarm
867         alarmManagerInOrder.verify(mAlarmManager, never())
868                 .setWindow(anyInt(), anyLong(), anyLong(),
869                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
870 
871         mDeviceIdleController.stepIdleStateLocked("testing");
872         // Location manager exists with a provider, so SENSING should go to LOCATING.
873         // verifyStateConditions knows this state typically shouldn't happen during normal
874         // operation, so we can't use it directly here. For this test, all we care about
875         // is that the state stepped forward.
876         assertEquals(STATE_LOCATING, mDeviceIdleController.getState());
877         // Still no alarm
878         alarmManagerInOrder.verify(mAlarmManager, never())
879                 .setWindow(anyInt(), anyLong(), anyLong(),
880                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
881 
882         mDeviceIdleController.stepIdleStateLocked("testing");
883         verifyStateConditions(STATE_IDLE);
884         // The device was forced into IDLE. AlarmManager should be notified.
885         alarmManagerInOrder.verify(mAlarmManager)
886                 .setIdleUntil(anyInt(), anyLong(),
887                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
888 
889         // Should just alternate between IDLE and IDLE_MAINTENANCE now. Since we've gotten to this
890         // point, alarms should be set on each transition.
891 
892         mDeviceIdleController.stepIdleStateLocked("testing");
893         verifyStateConditions(STATE_IDLE_MAINTENANCE);
894         alarmManagerInOrder.verify(mAlarmManager)
895                 .setWindow(anyInt(), anyLong(), anyLong(),
896                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
897 
898         mDeviceIdleController.stepIdleStateLocked("testing");
899         verifyStateConditions(STATE_IDLE);
900         alarmManagerInOrder.verify(mAlarmManager)
901                 .setIdleUntil(anyInt(), anyLong(),
902                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
903 
904         mDeviceIdleController.stepIdleStateLocked("testing");
905         verifyStateConditions(STATE_IDLE_MAINTENANCE);
906         alarmManagerInOrder.verify(mAlarmManager)
907                 .setWindow(anyInt(), anyLong(), anyLong(),
908                         eq("DeviceIdleController.deep"), any(), any(Handler.class));
909     }
910 
911     @Test
testStepIdleStateLocked_ValidStates_WithWakeFromIdleAlarmSoon()912     public void testStepIdleStateLocked_ValidStates_WithWakeFromIdleAlarmSoon() {
913         enterDeepState(STATE_ACTIVE);
914         // Return that there's an alarm coming soon.
915         setAlarmSoon(true);
916         mDeviceIdleController.stepIdleStateLocked("testing");
917         verifyStateConditions(STATE_ACTIVE);
918 
919         // Everything besides ACTIVE should end up as INACTIVE since the screen would be off.
920 
921         enterDeepState(STATE_INACTIVE);
922         setAlarmSoon(true);
923         mDeviceIdleController.stepIdleStateLocked("testing");
924         verifyStateConditions(STATE_INACTIVE);
925 
926         enterDeepState(STATE_IDLE_PENDING);
927         setAlarmSoon(true);
928         mDeviceIdleController.stepIdleStateLocked("testing");
929         verifyStateConditions(STATE_INACTIVE);
930 
931         enterDeepState(STATE_SENSING);
932         setAlarmSoon(true);
933         mDeviceIdleController.stepIdleStateLocked("testing");
934         verifyStateConditions(STATE_INACTIVE);
935 
936         enterDeepState(STATE_LOCATING);
937         setAlarmSoon(true);
938         mDeviceIdleController.stepIdleStateLocked("testing");
939         verifyStateConditions(STATE_INACTIVE);
940 
941         // With quick doze enabled, we should end up in QUICK_DOZE_DELAY instead of INACTIVE.
942         enterDeepState(STATE_QUICK_DOZE_DELAY);
943         setQuickDozeEnabled(true);
944         setAlarmSoon(true);
945         mDeviceIdleController.stepIdleStateLocked("testing");
946         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
947 
948         // With quick doze disabled, we should end up in INACTIVE instead of QUICK_DOZE_DELAY.
949         enterDeepState(STATE_QUICK_DOZE_DELAY);
950         setQuickDozeEnabled(false);
951         setAlarmSoon(true);
952         mDeviceIdleController.stepIdleStateLocked("testing");
953         verifyStateConditions(STATE_INACTIVE);
954 
955         enterDeepState(STATE_IDLE);
956         setAlarmSoon(true);
957         mDeviceIdleController.stepIdleStateLocked("testing");
958         verifyStateConditions(STATE_INACTIVE);
959 
960         enterDeepState(STATE_IDLE_MAINTENANCE);
961         setAlarmSoon(true);
962         mDeviceIdleController.stepIdleStateLocked("testing");
963         verifyStateConditions(STATE_INACTIVE);
964     }
965 
966     @Test
testStepIdleStateLocked_ValidStates_NoLocationManager()967     public void testStepIdleStateLocked_ValidStates_NoLocationManager() {
968         mInjector.locationManager = null;
969         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
970         setAlarmSoon(false);
971         // Set state to INACTIVE.
972         mDeviceIdleController.becomeActiveLocked("testing", 0);
973         setChargingOn(false);
974         setScreenOn(false);
975         verifyStateConditions(STATE_INACTIVE);
976 
977         mDeviceIdleController.stepIdleStateLocked("testing");
978         verifyStateConditions(STATE_IDLE_PENDING);
979 
980         mDeviceIdleController.stepIdleStateLocked("testing");
981         verifyStateConditions(STATE_SENSING);
982 
983         mDeviceIdleController.stepIdleStateLocked("testing");
984         // No location manager, so SENSING should go straight to IDLE.
985         verifyStateConditions(STATE_IDLE);
986 
987         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
988 
989         mDeviceIdleController.stepIdleStateLocked("testing");
990         verifyStateConditions(STATE_IDLE_MAINTENANCE);
991 
992         mDeviceIdleController.stepIdleStateLocked("testing");
993         verifyStateConditions(STATE_IDLE);
994 
995         mDeviceIdleController.stepIdleStateLocked("testing");
996         verifyStateConditions(STATE_IDLE_MAINTENANCE);
997     }
998 
999     @Test
testStepIdleStateLocked_ValidStates_LocationPrefetchDisabled()1000     public void testStepIdleStateLocked_ValidStates_LocationPrefetchDisabled() {
1001         mInjector.locationManager = mLocationManager;
1002         mInjector.isLocationPrefetchEnabled = false;
1003         cleanupDeviceIdleController();
1004         setupDeviceIdleController();
1005         doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
1006         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
1007         setAlarmSoon(false);
1008         // Set state to INACTIVE.
1009         mDeviceIdleController.becomeActiveLocked("testing", 0);
1010         setChargingOn(false);
1011         setScreenOn(false);
1012         verifyStateConditions(STATE_INACTIVE);
1013 
1014         mDeviceIdleController.stepIdleStateLocked("testing");
1015         verifyStateConditions(STATE_IDLE_PENDING);
1016 
1017         mDeviceIdleController.stepIdleStateLocked("testing");
1018         verifyStateConditions(STATE_SENSING);
1019 
1020         mDeviceIdleController.stepIdleStateLocked("testing");
1021         // Prefetch location is off, so SENSING should go straight through to IDLE.
1022         verifyStateConditions(STATE_IDLE);
1023 
1024         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1025 
1026         mDeviceIdleController.stepIdleStateLocked("testing");
1027         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1028 
1029         mDeviceIdleController.stepIdleStateLocked("testing");
1030         verifyStateConditions(STATE_IDLE);
1031 
1032         mDeviceIdleController.stepIdleStateLocked("testing");
1033         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1034     }
1035 
1036     @Test
testStepIdleStateLocked_ValidStates_WithLocationManager_NoProviders()1037     public void testStepIdleStateLocked_ValidStates_WithLocationManager_NoProviders() {
1038         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
1039         setAlarmSoon(false);
1040         // Set state to INACTIVE.
1041         mDeviceIdleController.becomeActiveLocked("testing", 0);
1042         setChargingOn(false);
1043         setScreenOn(false);
1044         verifyStateConditions(STATE_INACTIVE);
1045 
1046         mDeviceIdleController.stepIdleStateLocked("testing");
1047         verifyStateConditions(STATE_IDLE_PENDING);
1048 
1049         mDeviceIdleController.stepIdleStateLocked("testing");
1050         verifyStateConditions(STATE_SENSING);
1051 
1052         mDeviceIdleController.stepIdleStateLocked("testing");
1053         // Location manager exists but there isn't a network or GPS provider,
1054         // so SENSING should go straight to IDLE.
1055         verifyStateConditions(STATE_IDLE);
1056 
1057         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1058 
1059         mDeviceIdleController.stepIdleStateLocked("testing");
1060         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1061 
1062         mDeviceIdleController.stepIdleStateLocked("testing");
1063         verifyStateConditions(STATE_IDLE);
1064 
1065         mDeviceIdleController.stepIdleStateLocked("testing");
1066         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1067     }
1068 
1069     @Test
testStepIdleStateLocked_ValidStates_WithLocationManager_MissingProviders()1070     public void testStepIdleStateLocked_ValidStates_WithLocationManager_MissingProviders() {
1071         mInjector.locationManager = mLocationManager;
1072         doReturn(null).when(mLocationManager)
1073                 .getProvider(eq(LocationManager.FUSED_PROVIDER));
1074         doReturn(null).when(mLocationManager)
1075                 .getProvider(eq(LocationManager.GPS_PROVIDER));
1076         doReturn(mock(LocationProvider.class)).when(mLocationManager)
1077                 .getProvider(eq(LocationManager.NETWORK_PROVIDER));
1078         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
1079         setAlarmSoon(false);
1080         // Set state to INACTIVE.
1081         mDeviceIdleController.becomeActiveLocked("testing", 0);
1082         setChargingOn(false);
1083         setScreenOn(false);
1084         verifyStateConditions(STATE_INACTIVE);
1085 
1086         mDeviceIdleController.stepIdleStateLocked("testing");
1087         verifyStateConditions(STATE_IDLE_PENDING);
1088 
1089         mDeviceIdleController.stepIdleStateLocked("testing");
1090         verifyStateConditions(STATE_SENSING);
1091 
1092         mDeviceIdleController.stepIdleStateLocked("testing");
1093         // Location manager exists, but the required providers don't exist,
1094         // so SENSING should go straight through to IDLE.
1095         verifyStateConditions(STATE_IDLE);
1096 
1097         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1098 
1099         mDeviceIdleController.stepIdleStateLocked("testing");
1100         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1101 
1102         mDeviceIdleController.stepIdleStateLocked("testing");
1103         verifyStateConditions(STATE_IDLE);
1104 
1105         mDeviceIdleController.stepIdleStateLocked("testing");
1106         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1107     }
1108 
1109     @Test
testStepIdleStateLocked_ValidStates_WithLocationManager_WithProviders()1110     public void testStepIdleStateLocked_ValidStates_WithLocationManager_WithProviders() {
1111         mInjector.locationManager = mLocationManager;
1112         doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
1113         // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
1114         setAlarmSoon(false);
1115         // Set state to INACTIVE.
1116         mDeviceIdleController.becomeActiveLocked("testing", 0);
1117         setChargingOn(false);
1118         setScreenOn(false);
1119         verifyStateConditions(STATE_INACTIVE);
1120 
1121         mDeviceIdleController.stepIdleStateLocked("testing");
1122         verifyStateConditions(STATE_IDLE_PENDING);
1123 
1124         mDeviceIdleController.stepIdleStateLocked("testing");
1125         verifyStateConditions(STATE_SENSING);
1126 
1127         mDeviceIdleController.stepIdleStateLocked("testing");
1128         // Location manager exists with a provider, so SENSING should go to LOCATING.
1129         verifyStateConditions(STATE_LOCATING);
1130 
1131         mDeviceIdleController.stepIdleStateLocked("testing");
1132         verifyStateConditions(STATE_IDLE);
1133 
1134         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1135 
1136         mDeviceIdleController.stepIdleStateLocked("testing");
1137         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1138 
1139         mDeviceIdleController.stepIdleStateLocked("testing");
1140         verifyStateConditions(STATE_IDLE);
1141 
1142         mDeviceIdleController.stepIdleStateLocked("testing");
1143         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1144     }
1145 
1146     @Test
testLightStepIdleStateLocked_InvalidStates()1147     public void testLightStepIdleStateLocked_InvalidStates() {
1148         mDeviceIdleController.becomeActiveLocked("testing", 0);
1149         mDeviceIdleController.stepLightIdleStateLocked("testing");
1150         // stepLightIdleStateLocked doesn't handle the ACTIVE case, so the state
1151         // should stay as ACTIVE.
1152         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1153     }
1154 
1155     /**
1156      * Make sure stepLightIdleStateLocked doesn't change state when the state is
1157      * LIGHT_STATE_OVERRIDE.
1158      */
1159     @Test
testLightStepIdleStateLocked_Overriden()1160     public void testLightStepIdleStateLocked_Overriden() {
1161         enterLightState(LIGHT_STATE_OVERRIDE);
1162         mDeviceIdleController.stepLightIdleStateLocked("testing");
1163         verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
1164     }
1165 
1166     @Test
testLightStepIdleStateLocked_ValidStates_NoActiveOps_NetworkConnected()1167     public void testLightStepIdleStateLocked_ValidStates_NoActiveOps_NetworkConnected() {
1168         setNetworkConnected(true);
1169         mDeviceIdleController.setJobsActive(false);
1170         mDeviceIdleController.setAlarmsActive(false);
1171         mDeviceIdleController.setActiveIdleOpsForTest(0);
1172 
1173         // Set state to INACTIVE.
1174         mDeviceIdleController.becomeActiveLocked("testing", 0);
1175         setChargingOn(false);
1176         setScreenOn(false);
1177         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1178 
1179         // No active ops means INACTIVE should go straight to IDLE.
1180         mDeviceIdleController.stepLightIdleStateLocked("testing");
1181         verifyLightStateConditions(LIGHT_STATE_IDLE);
1182 
1183         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1184 
1185         mDeviceIdleController.stepLightIdleStateLocked("testing");
1186         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1187 
1188         mDeviceIdleController.stepLightIdleStateLocked("testing");
1189         verifyLightStateConditions(LIGHT_STATE_IDLE);
1190 
1191         mDeviceIdleController.stepLightIdleStateLocked("testing");
1192         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1193     }
1194 
1195     @Test
testLightStepIdleStateLocked_ValidStates_ActiveOps_NetworkConnected()1196     public void testLightStepIdleStateLocked_ValidStates_ActiveOps_NetworkConnected() {
1197         setNetworkConnected(true);
1198         // Set state to INACTIVE.
1199         mDeviceIdleController.becomeActiveLocked("testing", 0);
1200         setChargingOn(false);
1201         setScreenOn(false);
1202         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1203 
1204         // After enough time, INACTIVE should go to IDLE regardless of any active ops.
1205         mDeviceIdleController.setJobsActive(true);
1206         mDeviceIdleController.setAlarmsActive(true);
1207         mDeviceIdleController.setActiveIdleOpsForTest(1);
1208         mDeviceIdleController.stepLightIdleStateLocked("testing");
1209         verifyLightStateConditions(LIGHT_STATE_IDLE);
1210 
1211         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1212 
1213         mDeviceIdleController.stepLightIdleStateLocked("testing");
1214         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1215 
1216         mDeviceIdleController.stepLightIdleStateLocked("testing");
1217         verifyLightStateConditions(LIGHT_STATE_IDLE);
1218 
1219         mDeviceIdleController.stepLightIdleStateLocked("testing");
1220         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1221     }
1222 
1223     @Test
testLightStepIdleStateLocked_ValidStates_NoActiveOps_NoNetworkConnected()1224     public void testLightStepIdleStateLocked_ValidStates_NoActiveOps_NoNetworkConnected() {
1225         setNetworkConnected(false);
1226         mDeviceIdleController.setJobsActive(false);
1227         mDeviceIdleController.setAlarmsActive(false);
1228         mDeviceIdleController.setActiveIdleOpsForTest(0);
1229 
1230         // Set state to INACTIVE.
1231         mDeviceIdleController.becomeActiveLocked("testing", 0);
1232         setChargingOn(false);
1233         setScreenOn(false);
1234         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1235 
1236         // No active ops means INACTIVE should go straight to IDLE.
1237         mDeviceIdleController.stepLightIdleStateLocked("testing");
1238         verifyLightStateConditions(LIGHT_STATE_IDLE);
1239 
1240         // Should cycle between IDLE, WAITING_FOR_NETWORK, and IDLE_MAINTENANCE now.
1241 
1242         mDeviceIdleController.stepLightIdleStateLocked("testing");
1243         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1244 
1245         mDeviceIdleController.stepLightIdleStateLocked("testing");
1246         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1247 
1248         mDeviceIdleController.stepLightIdleStateLocked("testing");
1249         verifyLightStateConditions(LIGHT_STATE_IDLE);
1250 
1251         mDeviceIdleController.stepLightIdleStateLocked("testing");
1252         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1253 
1254         mDeviceIdleController.stepLightIdleStateLocked("testing");
1255         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1256     }
1257 
1258     @Test
testLightStepIdleStateLocked_ValidStates_ActiveOps_NoNetworkConnected()1259     public void testLightStepIdleStateLocked_ValidStates_ActiveOps_NoNetworkConnected() {
1260         setNetworkConnected(false);
1261         // Set state to INACTIVE.
1262         mDeviceIdleController.becomeActiveLocked("testing", 0);
1263         setChargingOn(false);
1264         setScreenOn(false);
1265         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1266 
1267         // After enough time, INACTIVE should go to IDLE regardless of any active ops.
1268         mDeviceIdleController.setJobsActive(true);
1269         mDeviceIdleController.setAlarmsActive(true);
1270         mDeviceIdleController.setActiveIdleOpsForTest(1);
1271         mDeviceIdleController.stepLightIdleStateLocked("testing");
1272         verifyLightStateConditions(LIGHT_STATE_IDLE);
1273 
1274         // Should cycle between IDLE, WAITING_FOR_NETWORK, and IDLE_MAINTENANCE now.
1275 
1276         mDeviceIdleController.stepLightIdleStateLocked("testing");
1277         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1278 
1279         mDeviceIdleController.stepLightIdleStateLocked("testing");
1280         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1281 
1282         mDeviceIdleController.stepLightIdleStateLocked("testing");
1283         verifyLightStateConditions(LIGHT_STATE_IDLE);
1284 
1285         mDeviceIdleController.stepLightIdleStateLocked("testing");
1286         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1287 
1288         mDeviceIdleController.stepLightIdleStateLocked("testing");
1289         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1290     }
1291 
1292     @Test
testLightStepIdleStateIdlingTimeIncreases()1293     public void testLightStepIdleStateIdlingTimeIncreases() {
1294         final long maintenanceTimeMs = 60_000L;
1295         mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = maintenanceTimeMs;
1296         mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = maintenanceTimeMs;
1297         mConstants.LIGHT_IDLE_TIMEOUT = 5 * 60_000L;
1298         mConstants.LIGHT_MAX_IDLE_TIMEOUT = 20 * 60_000L;
1299         mConstants.LIGHT_IDLE_FACTOR = 2f;
1300 
1301         setNetworkConnected(true);
1302         mDeviceIdleController.setJobsActive(false);
1303         mDeviceIdleController.setAlarmsActive(false);
1304         mDeviceIdleController.setActiveIdleOpsForTest(0);
1305 
1306         InOrder alarmManagerInOrder = inOrder(mAlarmManager);
1307 
1308         final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = ArgumentCaptor
1309                 .forClass(AlarmManager.OnAlarmListener.class);
1310         doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
1311                 eq("DeviceIdleController.light"), alarmListenerCaptor.capture(), any());
1312 
1313         // Set state to INACTIVE.
1314         mDeviceIdleController.becomeActiveLocked("testing", 0);
1315         setChargingOn(false);
1316         setScreenOn(false);
1317         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1318         long idlingTimeMs = mConstants.LIGHT_IDLE_TIMEOUT;
1319         final long idleAfterInactiveExpiryTime =
1320                 mInjector.nowElapsed + mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
1321         alarmManagerInOrder.verify(mAlarmManager).setWindow(
1322                 eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
1323                 eq(idleAfterInactiveExpiryTime),
1324                 anyLong(), anyString(), any(), any(Handler.class));
1325 
1326         final AlarmManager.OnAlarmListener alarmListener =
1327                 alarmListenerCaptor.getAllValues().get(0);
1328 
1329         // INACTIVE -> IDLE alarm
1330         mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
1331         alarmListener.onAlarm();
1332         verifyLightStateConditions(LIGHT_STATE_IDLE);
1333         alarmManagerInOrder.verify(mAlarmManager).setWindow(
1334                 eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
1335                 eq(mInjector.nowElapsed + idlingTimeMs),
1336                 anyLong(), anyString(), any(), any(Handler.class));
1337 
1338         for (int i = 0; i < 2; ++i) {
1339             // IDLE->MAINTENANCE alarm
1340             mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
1341             alarmListener.onAlarm();
1342             verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1343             long maintenanceExpiryTime = mInjector.nowElapsed + maintenanceTimeMs;
1344             idlingTimeMs *= mConstants.LIGHT_IDLE_FACTOR;
1345             // Set MAINTENANCE->IDLE
1346             alarmManagerInOrder.verify(mAlarmManager).setWindow(
1347                     eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
1348                     eq(maintenanceExpiryTime),
1349                     anyLong(), anyString(), any(), any(Handler.class));
1350 
1351             // MAINTENANCE->IDLE alarm
1352             mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
1353             alarmListener.onAlarm();
1354             verifyLightStateConditions(LIGHT_STATE_IDLE);
1355             // Set IDLE->MAINTENANCE again
1356             alarmManagerInOrder.verify(mAlarmManager).setWindow(
1357                     eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
1358                     eq(mInjector.nowElapsed + idlingTimeMs),
1359                     anyLong(), anyString(), any(), any(Handler.class));
1360         }
1361     }
1362 
1363     @Test
testLightIdleAlarmUnaffectedByMotion()1364     public void testLightIdleAlarmUnaffectedByMotion() {
1365         setNetworkConnected(true);
1366         mDeviceIdleController.setJobsActive(false);
1367         mDeviceIdleController.setAlarmsActive(false);
1368         mDeviceIdleController.setActiveIdleOpsForTest(0);
1369         spyOn(mDeviceIdleController);
1370 
1371         InOrder inOrder = inOrder(mDeviceIdleController);
1372 
1373         // Set state to INACTIVE.
1374         mDeviceIdleController.becomeActiveLocked("testing", 0);
1375         setChargingOn(false);
1376         setScreenOn(false);
1377         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1378 
1379         // No active ops means INACTIVE should go straight to IDLE.
1380         mDeviceIdleController.stepLightIdleStateLocked("testing");
1381         verifyLightStateConditions(LIGHT_STATE_IDLE);
1382         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
1383                 longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT),
1384                 longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
1385                 eq(true));
1386 
1387         // Should just alternate between IDLE and IDLE_MAINTENANCE now.
1388 
1389         mDeviceIdleController.stepLightIdleStateLocked("testing");
1390         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1391         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
1392                 longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
1393                 longThat(l -> l == mConstants.FLEX_TIME_SHORT),
1394                 eq(true));
1395 
1396         mDeviceIdleController.stepLightIdleStateLocked("testing");
1397         verifyLightStateConditions(LIGHT_STATE_IDLE);
1398         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
1399                 longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
1400                 longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
1401                 eq(true));
1402 
1403         mDeviceIdleController.stepLightIdleStateLocked("testing");
1404         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1405         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
1406                 longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
1407                 longThat(l -> l == mConstants.FLEX_TIME_SHORT),
1408                 eq(true));
1409 
1410         // Test that motion doesn't reset the idle timeout.
1411         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1412 
1413         mDeviceIdleController.stepLightIdleStateLocked("testing");
1414         verifyLightStateConditions(LIGHT_STATE_IDLE);
1415         inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
1416                 longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
1417                 longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
1418                 eq(true));
1419     }
1420 
1421     @Test
testEmergencyCallEndTriggersInactive()1422     public void testEmergencyCallEndTriggersInactive() {
1423         setAlarmSoon(false);
1424         setChargingOn(false);
1425         setScreenOn(false);
1426         setEmergencyCallActive(true);
1427 
1428         verifyStateConditions(STATE_ACTIVE);
1429         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1430 
1431         setEmergencyCallActive(false);
1432 
1433         verifyStateConditions(STATE_INACTIVE);
1434         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1435     }
1436 
1437     ///////////////// EXIT conditions ///////////////////
1438 
1439     @Test
testExitMaintenanceEarlyIfNeededLocked_deep_noActiveOps()1440     public void testExitMaintenanceEarlyIfNeededLocked_deep_noActiveOps() {
1441         mDeviceIdleController.setJobsActive(false);
1442         mDeviceIdleController.setAlarmsActive(false);
1443         mDeviceIdleController.setActiveIdleOpsForTest(0);
1444 
1445         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1446 
1447         enterDeepState(STATE_ACTIVE);
1448         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1449         verifyStateConditions(STATE_ACTIVE);
1450 
1451         enterDeepState(STATE_INACTIVE);
1452         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1453         verifyStateConditions(STATE_INACTIVE);
1454 
1455         enterDeepState(STATE_IDLE_PENDING);
1456         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1457         verifyStateConditions(STATE_IDLE_PENDING);
1458 
1459         enterDeepState(STATE_SENSING);
1460         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1461         verifyStateConditions(STATE_SENSING);
1462 
1463         enterDeepState(STATE_LOCATING);
1464         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1465         verifyStateConditions(STATE_LOCATING);
1466 
1467         enterDeepState(STATE_IDLE);
1468         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1469         verifyStateConditions(STATE_IDLE);
1470 
1471         enterDeepState(STATE_IDLE_MAINTENANCE);
1472         // Going into IDLE_MAINTENANCE increments the active idle op count.
1473         mDeviceIdleController.setActiveIdleOpsForTest(0);
1474         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1475         verifyStateConditions(STATE_IDLE);
1476 
1477         enterDeepState(STATE_QUICK_DOZE_DELAY);
1478         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1479         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1480     }
1481 
1482     @Test
testExitMaintenanceEarlyIfNeededLocked_deep_activeJobs()1483     public void testExitMaintenanceEarlyIfNeededLocked_deep_activeJobs() {
1484         mDeviceIdleController.setJobsActive(true);
1485         mDeviceIdleController.setAlarmsActive(false);
1486         mDeviceIdleController.setActiveIdleOpsForTest(0);
1487 
1488         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1489 
1490         enterDeepState(STATE_ACTIVE);
1491         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1492         verifyStateConditions(STATE_ACTIVE);
1493 
1494         enterDeepState(STATE_INACTIVE);
1495         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1496         verifyStateConditions(STATE_INACTIVE);
1497 
1498         enterDeepState(STATE_IDLE_PENDING);
1499         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1500         verifyStateConditions(STATE_IDLE_PENDING);
1501 
1502         enterDeepState(STATE_SENSING);
1503         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1504         verifyStateConditions(STATE_SENSING);
1505 
1506         enterDeepState(STATE_LOCATING);
1507         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1508         verifyStateConditions(STATE_LOCATING);
1509 
1510         enterDeepState(STATE_IDLE);
1511         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1512         verifyStateConditions(STATE_IDLE);
1513 
1514         enterDeepState(STATE_IDLE_MAINTENANCE);
1515         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1516         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1517 
1518         enterDeepState(STATE_QUICK_DOZE_DELAY);
1519         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1520         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1521     }
1522 
1523     @Test
testExitMaintenanceEarlyIfNeededLocked_deep_activeAlarms()1524     public void testExitMaintenanceEarlyIfNeededLocked_deep_activeAlarms() {
1525         mDeviceIdleController.setJobsActive(false);
1526         mDeviceIdleController.setAlarmsActive(true);
1527         mDeviceIdleController.setActiveIdleOpsForTest(0);
1528 
1529         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1530 
1531         enterDeepState(STATE_ACTIVE);
1532         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1533         verifyStateConditions(STATE_ACTIVE);
1534 
1535         enterDeepState(STATE_INACTIVE);
1536         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1537         verifyStateConditions(STATE_INACTIVE);
1538 
1539         enterDeepState(STATE_IDLE_PENDING);
1540         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1541         verifyStateConditions(STATE_IDLE_PENDING);
1542 
1543         enterDeepState(STATE_SENSING);
1544         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1545         verifyStateConditions(STATE_SENSING);
1546 
1547         enterDeepState(STATE_LOCATING);
1548         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1549         verifyStateConditions(STATE_LOCATING);
1550 
1551         enterDeepState(STATE_IDLE);
1552         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1553         verifyStateConditions(STATE_IDLE);
1554 
1555         enterDeepState(STATE_IDLE_MAINTENANCE);
1556         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1557         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1558 
1559         enterDeepState(STATE_QUICK_DOZE_DELAY);
1560         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1561         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1562     }
1563 
1564     @Test
testExitMaintenanceEarlyIfNeededLocked_deep_activeOps()1565     public void testExitMaintenanceEarlyIfNeededLocked_deep_activeOps() {
1566         mDeviceIdleController.setJobsActive(false);
1567         mDeviceIdleController.setAlarmsActive(false);
1568         mDeviceIdleController.setActiveIdleOpsForTest(1);
1569 
1570         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1571 
1572         enterDeepState(STATE_ACTIVE);
1573         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1574         verifyStateConditions(STATE_ACTIVE);
1575 
1576         enterDeepState(STATE_INACTIVE);
1577         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1578         verifyStateConditions(STATE_INACTIVE);
1579 
1580         enterDeepState(STATE_IDLE_PENDING);
1581         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1582         verifyStateConditions(STATE_IDLE_PENDING);
1583 
1584         enterDeepState(STATE_SENSING);
1585         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1586         verifyStateConditions(STATE_SENSING);
1587 
1588         enterDeepState(STATE_LOCATING);
1589         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1590         verifyStateConditions(STATE_LOCATING);
1591 
1592         enterDeepState(STATE_IDLE);
1593         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1594         verifyStateConditions(STATE_IDLE);
1595 
1596         enterDeepState(STATE_IDLE_MAINTENANCE);
1597         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1598         verifyStateConditions(STATE_IDLE_MAINTENANCE);
1599 
1600         enterDeepState(STATE_QUICK_DOZE_DELAY);
1601         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1602         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1603     }
1604 
1605     @Test
testExitMaintenanceEarlyIfNeededLocked_light_noActiveOps()1606     public void testExitMaintenanceEarlyIfNeededLocked_light_noActiveOps() {
1607         mDeviceIdleController.setJobsActive(false);
1608         mDeviceIdleController.setAlarmsActive(false);
1609         mDeviceIdleController.setActiveIdleOpsForTest(0);
1610 
1611         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1612 
1613         enterLightState(LIGHT_STATE_ACTIVE);
1614         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1615         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1616 
1617         enterLightState(LIGHT_STATE_INACTIVE);
1618         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1619         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1620 
1621         enterLightState(LIGHT_STATE_IDLE);
1622         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1623         verifyLightStateConditions(LIGHT_STATE_IDLE);
1624 
1625         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
1626         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1627         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1628 
1629         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
1630         // Going into IDLE_MAINTENANCE increments the active idle op count.
1631         mDeviceIdleController.setActiveIdleOpsForTest(0);
1632         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1633         verifyLightStateConditions(LIGHT_STATE_IDLE);
1634 
1635         enterLightState(LIGHT_STATE_OVERRIDE);
1636         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1637         verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
1638     }
1639 
1640     @Test
testExitMaintenanceEarlyIfNeededLocked_light_activeJobs()1641     public void testExitMaintenanceEarlyIfNeededLocked_light_activeJobs() {
1642         mDeviceIdleController.setJobsActive(true);
1643         mDeviceIdleController.setAlarmsActive(false);
1644         mDeviceIdleController.setActiveIdleOpsForTest(0);
1645 
1646         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1647 
1648         enterLightState(LIGHT_STATE_ACTIVE);
1649         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1650         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1651 
1652         enterLightState(LIGHT_STATE_INACTIVE);
1653         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1654         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1655 
1656         enterLightState(LIGHT_STATE_IDLE);
1657         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1658         verifyLightStateConditions(LIGHT_STATE_IDLE);
1659 
1660         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
1661         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1662         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1663 
1664         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
1665         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1666         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1667 
1668         enterLightState(LIGHT_STATE_OVERRIDE);
1669         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1670         verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
1671     }
1672 
1673     @Test
testExitMaintenanceEarlyIfNeededLocked_light_activeAlarms()1674     public void testExitMaintenanceEarlyIfNeededLocked_light_activeAlarms() {
1675         mDeviceIdleController.setJobsActive(false);
1676         mDeviceIdleController.setAlarmsActive(true);
1677         mDeviceIdleController.setActiveIdleOpsForTest(0);
1678 
1679         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1680 
1681         enterLightState(LIGHT_STATE_ACTIVE);
1682         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1683         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1684 
1685         enterLightState(LIGHT_STATE_INACTIVE);
1686         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1687         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1688 
1689         enterLightState(LIGHT_STATE_IDLE);
1690         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1691         verifyLightStateConditions(LIGHT_STATE_IDLE);
1692 
1693         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
1694         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1695         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1696 
1697         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
1698         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1699         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1700 
1701         enterLightState(LIGHT_STATE_OVERRIDE);
1702         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1703         verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
1704     }
1705 
1706     @Test
testExitMaintenanceEarlyIfNeededLocked_light_activeOps()1707     public void testExitMaintenanceEarlyIfNeededLocked_light_activeOps() {
1708         mDeviceIdleController.setJobsActive(false);
1709         mDeviceIdleController.setAlarmsActive(false);
1710         mDeviceIdleController.setActiveIdleOpsForTest(1);
1711 
1712         // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
1713 
1714         enterLightState(LIGHT_STATE_ACTIVE);
1715         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1716         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1717 
1718         enterLightState(LIGHT_STATE_INACTIVE);
1719         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1720         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1721 
1722         enterLightState(LIGHT_STATE_IDLE);
1723         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1724         verifyLightStateConditions(LIGHT_STATE_IDLE);
1725 
1726         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
1727         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1728         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1729 
1730         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
1731         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1732         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1733 
1734         enterLightState(LIGHT_STATE_OVERRIDE);
1735         mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
1736         verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
1737     }
1738 
1739     @Test
testHandleMotionDetectedLocked_deep_quickDoze_off()1740     public void testHandleMotionDetectedLocked_deep_quickDoze_off() {
1741         enterDeepState(STATE_ACTIVE);
1742         setQuickDozeEnabled(false);
1743         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1744         verifyStateConditions(STATE_ACTIVE);
1745 
1746         // Anything that wasn't ACTIVE before motion detection should end up in the INACTIVE state.
1747 
1748         enterDeepState(STATE_INACTIVE);
1749         setQuickDozeEnabled(false);
1750         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1751         verifyStateConditions(STATE_INACTIVE);
1752 
1753         enterDeepState(STATE_IDLE_PENDING);
1754         setQuickDozeEnabled(false);
1755         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1756         verifyStateConditions(STATE_INACTIVE);
1757 
1758         enterDeepState(STATE_SENSING);
1759         setQuickDozeEnabled(false);
1760         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1761         verifyStateConditions(STATE_INACTIVE);
1762 
1763         enterDeepState(STATE_LOCATING);
1764         setQuickDozeEnabled(false);
1765         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1766         verifyStateConditions(STATE_INACTIVE);
1767 
1768         enterDeepState(STATE_IDLE);
1769         setQuickDozeEnabled(false);
1770         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1771         verifyStateConditions(STATE_INACTIVE);
1772 
1773         enterDeepState(STATE_IDLE_MAINTENANCE);
1774         setQuickDozeEnabled(false);
1775         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1776         verifyStateConditions(STATE_INACTIVE);
1777 
1778         enterDeepState(STATE_QUICK_DOZE_DELAY);
1779         setQuickDozeEnabled(false);
1780         // Disabling quick doze doesn't immediately change the state as coming out is harder than
1781         // going in.
1782         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1783         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1784         verifyStateConditions(STATE_INACTIVE);
1785     }
1786 
1787     @Test
testHandleMotionDetectedLocked_deep_quickDoze_on()1788     public void testHandleMotionDetectedLocked_deep_quickDoze_on() {
1789         enterDeepState(STATE_ACTIVE);
1790         setQuickDozeEnabled(true);
1791         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1792         verifyStateConditions(STATE_ACTIVE);
1793 
1794         // Anything that wasn't ACTIVE before motion detection should end up in the
1795         // QUICK_DOZE_DELAY state since quick doze is enabled.
1796 
1797         enterDeepState(STATE_INACTIVE);
1798         setQuickDozeEnabled(true);
1799         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1800         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1801 
1802         enterDeepState(STATE_IDLE_PENDING);
1803         setQuickDozeEnabled(true);
1804         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1805         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1806 
1807         enterDeepState(STATE_SENSING);
1808         setQuickDozeEnabled(true);
1809         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1810         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1811 
1812         enterDeepState(STATE_LOCATING);
1813         setQuickDozeEnabled(true);
1814         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1815         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1816 
1817         enterDeepState(STATE_IDLE);
1818         setQuickDozeEnabled(true);
1819         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1820         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1821 
1822         enterDeepState(STATE_IDLE_MAINTENANCE);
1823         setQuickDozeEnabled(true);
1824         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1825         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1826 
1827         enterDeepState(STATE_QUICK_DOZE_DELAY);
1828         setQuickDozeEnabled(true);
1829         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1830         verifyStateConditions(STATE_QUICK_DOZE_DELAY);
1831     }
1832 
1833     @Test
testHandleMotionDetectedLocked_light()1834     public void testHandleMotionDetectedLocked_light() {
1835         enterLightState(LIGHT_STATE_ACTIVE);
1836         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1837         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1838 
1839         // Motion shouldn't affect light idle, so LIGHT states should stay as they were except for
1840         // OVERRIDE. OVERRIDE means deep was active, so if motion was detected,
1841         // LIGHT_STATE_OVERRIDE should end up as LIGHT_STATE_INACTIVE.
1842 
1843         enterLightState(LIGHT_STATE_INACTIVE);
1844         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1845         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1846 
1847         enterLightState(LIGHT_STATE_IDLE);
1848         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1849         verifyLightStateConditions(LIGHT_STATE_IDLE);
1850 
1851         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
1852         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1853         verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
1854 
1855         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
1856         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1857         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
1858 
1859         enterLightState(LIGHT_STATE_OVERRIDE);
1860         mDeviceIdleController.handleMotionDetectedLocked(50, "test");
1861         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1862     }
1863 
1864     @Test
testBecomeActiveLocked_deep()1865     public void testBecomeActiveLocked_deep() {
1866         // becomeActiveLocked should put everything into ACTIVE.
1867 
1868         enterDeepState(STATE_ACTIVE);
1869         mDeviceIdleController.becomeActiveLocked("test", 1000);
1870         verifyStateConditions(STATE_ACTIVE);
1871 
1872         enterDeepState(STATE_INACTIVE);
1873         mDeviceIdleController.becomeActiveLocked("test", 1000);
1874         verifyStateConditions(STATE_ACTIVE);
1875 
1876         enterDeepState(STATE_IDLE_PENDING);
1877         mDeviceIdleController.becomeActiveLocked("test", 1000);
1878         verifyStateConditions(STATE_ACTIVE);
1879 
1880         enterDeepState(STATE_SENSING);
1881         mDeviceIdleController.becomeActiveLocked("test", 1000);
1882         verifyStateConditions(STATE_ACTIVE);
1883 
1884         enterDeepState(STATE_LOCATING);
1885         mDeviceIdleController.becomeActiveLocked("test", 1000);
1886         verifyStateConditions(STATE_ACTIVE);
1887 
1888         enterDeepState(STATE_IDLE);
1889         mDeviceIdleController.becomeActiveLocked("test", 1000);
1890         verifyStateConditions(STATE_ACTIVE);
1891 
1892         enterDeepState(STATE_IDLE_MAINTENANCE);
1893         mDeviceIdleController.becomeActiveLocked("test", 1000);
1894         verifyStateConditions(STATE_ACTIVE);
1895 
1896         enterDeepState(STATE_QUICK_DOZE_DELAY);
1897         mDeviceIdleController.becomeActiveLocked("test", 1000);
1898         verifyStateConditions(STATE_ACTIVE);
1899     }
1900 
1901     @Test
testBecomeActiveLocked_light()1902     public void testBecomeActiveLocked_light() {
1903         // becomeActiveLocked should put everything into ACTIVE.
1904 
1905         enterLightState(LIGHT_STATE_ACTIVE);
1906         mDeviceIdleController.becomeActiveLocked("test", 1000);
1907         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1908 
1909         enterLightState(LIGHT_STATE_INACTIVE);
1910         mDeviceIdleController.becomeActiveLocked("test", 1000);
1911         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1912 
1913         enterLightState(LIGHT_STATE_IDLE);
1914         mDeviceIdleController.becomeActiveLocked("test", 1000);
1915         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1916 
1917         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
1918         mDeviceIdleController.becomeActiveLocked("test", 1000);
1919         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1920 
1921         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
1922         mDeviceIdleController.becomeActiveLocked("test", 1000);
1923         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1924 
1925         enterLightState(LIGHT_STATE_OVERRIDE);
1926         mDeviceIdleController.becomeActiveLocked("test", 1000);
1927         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1928     }
1929 
1930     /** Test based on b/119058625. */
1931     @Test
testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_ScreenThenMotion()1932     public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_ScreenThenMotion() {
1933         mConstants.WAIT_FOR_UNLOCK = true;
1934         enterDeepState(STATE_IDLE);
1935         reset(mAlarmManager);
1936         spyOn(mDeviceIdleController);
1937 
1938         mDeviceIdleController.keyguardShowingLocked(true);
1939         setScreenOn(true);
1940         // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself
1941         // shouldn't bring the device out of deep IDLE.
1942         verifyStateConditions(STATE_IDLE);
1943         mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
1944         // Motion should bring the device out of Doze. Since the screen is still locked (albeit
1945         // on), the states should go back into INACTIVE.
1946         verifyStateConditions(STATE_INACTIVE);
1947         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1948         verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener));
1949         verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt());
1950     }
1951 
1952     /** Test based on b/119058625. */
1953     @Test
testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_ScreenThenMotion()1954     public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_ScreenThenMotion() {
1955         mConstants.WAIT_FOR_UNLOCK = true;
1956         enterDeepState(STATE_IDLE);
1957         reset(mAlarmManager);
1958         spyOn(mDeviceIdleController);
1959 
1960         mDeviceIdleController.keyguardShowingLocked(false);
1961         setScreenOn(true);
1962         // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself
1963         // should bring the device out of deep IDLE.
1964         verifyStateConditions(STATE_ACTIVE);
1965         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
1966         verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener));
1967         verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt());
1968     }
1969 
1970     /** Test based on b/119058625. */
1971     @Test
testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_MotionThenScreen()1972     public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOn_MotionThenScreen() {
1973         mConstants.WAIT_FOR_UNLOCK = true;
1974         enterDeepState(STATE_IDLE);
1975         reset(mAlarmManager);
1976         spyOn(mDeviceIdleController);
1977 
1978         InOrder alarmManagerInOrder = inOrder(mAlarmManager);
1979         InOrder controllerInOrder = inOrder(mDeviceIdleController);
1980 
1981         mDeviceIdleController.keyguardShowingLocked(true);
1982         mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
1983         // The screen is still off, so motion should result in the INACTIVE state.
1984         verifyStateConditions(STATE_INACTIVE);
1985         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1986         alarmManagerInOrder.verify(mAlarmManager)
1987                 .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
1988         controllerInOrder.verify(mDeviceIdleController)
1989                 .scheduleReportActiveLocked(anyString(), anyInt());
1990 
1991         setScreenOn(true);
1992         // With WAIT_FOR_UNLOCK = true and the screen locked, turning the screen on by itself
1993         // shouldn't bring the device all the way to ACTIVE.
1994         verifyStateConditions(STATE_INACTIVE);
1995         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
1996         alarmManagerInOrder.verify(mAlarmManager, never()).cancel(
1997                 eq(mDeviceIdleController.mDeepAlarmListener));
1998 
1999         // User finally unlocks the device. Device should be fully active.
2000         mDeviceIdleController.keyguardShowingLocked(false);
2001         verifyStateConditions(STATE_ACTIVE);
2002         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2003         alarmManagerInOrder.verify(mAlarmManager)
2004                 .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
2005         controllerInOrder.verify(mDeviceIdleController)
2006                 .scheduleReportActiveLocked(anyString(), anyInt());
2007     }
2008 
2009     /** Test based on b/119058625. */
2010     @Test
testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_MotionThenScreen()2011     public void testExitNotifiesDependencies_WaitForUnlockOn_KeyguardOff_MotionThenScreen() {
2012         mConstants.WAIT_FOR_UNLOCK = true;
2013         enterDeepState(STATE_IDLE);
2014         reset(mAlarmManager);
2015         spyOn(mDeviceIdleController);
2016 
2017         InOrder alarmManagerInOrder = inOrder(mAlarmManager);
2018         InOrder controllerInOrder = inOrder(mDeviceIdleController);
2019 
2020         mDeviceIdleController.keyguardShowingLocked(false);
2021         mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
2022         // The screen is still off, so motion should result in the INACTIVE state.
2023         verifyStateConditions(STATE_INACTIVE);
2024         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
2025         alarmManagerInOrder.verify(mAlarmManager)
2026                 .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
2027         controllerInOrder.verify(mDeviceIdleController)
2028                 .scheduleReportActiveLocked(anyString(), anyInt());
2029 
2030         setScreenOn(true);
2031         // With WAIT_FOR_UNLOCK = true and the screen unlocked, turning the screen on by itself
2032         // should bring the device out of deep IDLE.
2033         verifyStateConditions(STATE_ACTIVE);
2034         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2035         alarmManagerInOrder.verify(mAlarmManager)
2036                 .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
2037         controllerInOrder.verify(mDeviceIdleController)
2038                 .scheduleReportActiveLocked(anyString(), anyInt());
2039     }
2040 
2041     @Test
testExitNotifiesDependencies_WaitForUnlockOff_Screen()2042     public void testExitNotifiesDependencies_WaitForUnlockOff_Screen() {
2043         mConstants.WAIT_FOR_UNLOCK = false;
2044         enterDeepState(STATE_IDLE);
2045         reset(mAlarmManager);
2046         spyOn(mDeviceIdleController);
2047 
2048         setScreenOn(true);
2049         // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself
2050         // should bring the device out of deep IDLE.
2051         verifyStateConditions(STATE_ACTIVE);
2052         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2053         verify(mAlarmManager).cancel(eq(mDeviceIdleController.mDeepAlarmListener));
2054         verify(mDeviceIdleController).scheduleReportActiveLocked(anyString(), anyInt());
2055     }
2056 
2057     @Test
testExitNotifiesDependencies_WaitForUnlockOff_MotionThenScreen()2058     public void testExitNotifiesDependencies_WaitForUnlockOff_MotionThenScreen() {
2059         mConstants.WAIT_FOR_UNLOCK = false;
2060         enterDeepState(STATE_IDLE);
2061         reset(mAlarmManager);
2062         spyOn(mDeviceIdleController);
2063 
2064         InOrder alarmManagerInOrder = inOrder(mAlarmManager);
2065         InOrder controllerInOrder = inOrder(mDeviceIdleController);
2066 
2067         mDeviceIdleController.handleMotionDetectedLocked(1000, "test");
2068         // The screen is still off, so motion should result in the INACTIVE state.
2069         verifyStateConditions(STATE_INACTIVE);
2070         verifyLightStateConditions(LIGHT_STATE_INACTIVE);
2071         alarmManagerInOrder.verify(mAlarmManager)
2072                 .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
2073         controllerInOrder.verify(mDeviceIdleController)
2074                 .scheduleReportActiveLocked(anyString(), anyInt());
2075 
2076         setScreenOn(true);
2077         // With WAIT_FOR_UNLOCK = false and the screen locked, turning the screen on by itself
2078         // should bring the device out of deep IDLE.
2079         verifyStateConditions(STATE_ACTIVE);
2080         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2081         alarmManagerInOrder.verify(mAlarmManager)
2082                 .cancel(eq(mDeviceIdleController.mDeepAlarmListener));
2083         controllerInOrder.verify(mDeviceIdleController)
2084                 .scheduleReportActiveLocked(anyString(), anyInt());
2085     }
2086 
2087     @Test
testStepToIdleMode()2088     public void testStepToIdleMode() {
2089         float delta = mDeviceIdleController.MIN_PRE_IDLE_FACTOR_CHANGE;
2090         for (int mode = PowerManager.PRE_IDLE_TIMEOUT_MODE_NORMAL;
2091                 mode <= PowerManager.PRE_IDLE_TIMEOUT_MODE_LONG;
2092                 mode++) {
2093             int ret = mDeviceIdleController.setPreIdleTimeoutMode(mode);
2094             if (mode == PowerManager.PRE_IDLE_TIMEOUT_MODE_NORMAL) {
2095                 assertEquals("setPreIdleTimeoutMode: " + mode + " failed.",
2096                         mDeviceIdleController.SET_IDLE_FACTOR_RESULT_IGNORED, ret);
2097             } else {
2098                 assertEquals("setPreIdleTimeoutMode: " + mode + " failed.",
2099                         mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK, ret);
2100             }
2101             //TODO(b/123045185): Mocked Handler of DeviceIdleController to make message loop
2102             //workable in this test class
2103             float expectedfactor = mDeviceIdleController.getPreIdleTimeoutByMode(mode);
2104             float curfactor = mDeviceIdleController.getPreIdleTimeoutFactor();
2105             assertEquals("Pre idle time factor of mode [" + mode + "].",
2106                     expectedfactor, curfactor, delta);
2107             mDeviceIdleController.resetPreIdleTimeoutMode();
2108 
2109             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_INACTIVE);
2110             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_IDLE_PENDING);
2111 
2112             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_SENSING);
2113             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_LOCATING);
2114             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_QUICK_DOZE_DELAY);
2115             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_IDLE_MAINTENANCE);
2116             checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_IDLE);
2117             checkMaybeDoAnImmediateMaintenance(expectedfactor);
2118         }
2119         float curfactor = mDeviceIdleController.getPreIdleTimeoutFactor();
2120         assertEquals("Pre idle time factor of mode default.",
2121                 1.0f, curfactor, delta);
2122     }
2123 
2124     @Test
testStationaryDetection_QuickDozeOff()2125     public void testStationaryDetection_QuickDozeOff() {
2126         setQuickDozeEnabled(false);
2127         enterDeepState(STATE_IDLE);
2128         // Regular progression through states, so time should have increased appropriately.
2129         mInjector.nowElapsed += mConstants.IDLE_AFTER_INACTIVE_TIMEOUT + mConstants.SENSING_TIMEOUT
2130                 + mConstants.LOCATING_TIMEOUT;
2131 
2132         StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
2133 
2134         mDeviceIdleController.registerStationaryListener(stationaryListener);
2135 
2136         // Go to IDLE_MAINTENANCE
2137         mDeviceIdleController.stepIdleStateLocked("testing");
2138 
2139         // Back to IDLE
2140         mDeviceIdleController.stepIdleStateLocked("testing");
2141         assertTrue(stationaryListener.isStationary);
2142 
2143         // Test motion
2144         stationaryListener.motionExpected = true;
2145         mDeviceIdleController.mMotionListener.onTrigger(null);
2146         assertFalse(stationaryListener.isStationary);
2147     }
2148 
2149     @Test
testStationaryDetection_QuickDozeOn_NoMotion()2150     public void testStationaryDetection_QuickDozeOn_NoMotion() {
2151         // Short timeout for testing.
2152         mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
2153         doReturn(Sensor.REPORTING_MODE_ONE_SHOT).when(mMotionSensor).getReportingMode();
2154         doReturn(true).when(mSensorManager)
2155                 .requestTriggerSensor(eq(mDeviceIdleController.mMotionListener), eq(mMotionSensor));
2156         setAlarmSoon(false);
2157         enterDeepState(STATE_QUICK_DOZE_DELAY);
2158         mDeviceIdleController.stepIdleStateLocked("testing");
2159         verifyStateConditions(STATE_IDLE);
2160         // Quick doze progression through states, so time should have increased appropriately.
2161         mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
2162         final ArgumentCaptor<AlarmManager.OnAlarmListener> motionAlarmListener = ArgumentCaptor
2163                 .forClass(AlarmManager.OnAlarmListener.class);
2164         final ArgumentCaptor<AlarmManager.OnAlarmListener> motionRegistrationAlarmListener =
2165                 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);
2166         doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
2167                 eq("DeviceIdleController.motion"), motionAlarmListener.capture(), any());
2168         doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
2169                 eq("DeviceIdleController.motion_registration"),
2170                 motionRegistrationAlarmListener.capture(), any());
2171 
2172         StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
2173         spyOn(stationaryListener);
2174         InOrder inOrder = inOrder(stationaryListener);
2175 
2176         stationaryListener.motionExpected = true;
2177         mDeviceIdleController.registerStationaryListener(stationaryListener);
2178         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2179                 .onDeviceStationaryChanged(eq(false));
2180         assertFalse(stationaryListener.isStationary);
2181 
2182         // Go to IDLE_MAINTENANCE
2183         mDeviceIdleController.stepIdleStateLocked("testing");
2184 
2185         mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT / 2;
2186 
2187         // Back to IDLE
2188         mDeviceIdleController.stepIdleStateLocked("testing");
2189 
2190         // Now enough time has passed.
2191         mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT;
2192         stationaryListener.motionExpected = false;
2193         motionAlarmListener.getValue().onAlarm();
2194         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2195                 .onDeviceStationaryChanged(eq(true));
2196         assertTrue(stationaryListener.isStationary);
2197 
2198         stationaryListener.motionExpected = true;
2199         mDeviceIdleController.mMotionListener.onTrigger(null);
2200         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2201                 .onDeviceStationaryChanged(eq(false));
2202         assertFalse(stationaryListener.isStationary);
2203 
2204         // Since we're in quick doze, the device shouldn't stop idling.
2205         verifyStateConditions(STATE_IDLE);
2206 
2207         // Go to IDLE_MAINTENANCE
2208         mDeviceIdleController.stepIdleStateLocked("testing");
2209 
2210         motionRegistrationAlarmListener.getValue().onAlarm();
2211         mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT / 2;
2212 
2213         // Back to IDLE
2214         stationaryListener.motionExpected = false;
2215         mDeviceIdleController.stepIdleStateLocked("testing");
2216         verify(mSensorManager,
2217                 timeout(mConstants.MOTION_INACTIVE_TIMEOUT).times(2))
2218                 .requestTriggerSensor(eq(mDeviceIdleController.mMotionListener), eq(mMotionSensor));
2219 
2220         // Now enough time has passed.
2221         mInjector.nowElapsed += mConstants.MOTION_INACTIVE_TIMEOUT;
2222         motionAlarmListener.getValue().onAlarm();
2223         inOrder.verify(stationaryListener,
2224                 timeout(mConstants.MOTION_INACTIVE_TIMEOUT).times(1))
2225                 .onDeviceStationaryChanged(eq(true));
2226         assertTrue(stationaryListener.isStationary);
2227     }
2228 
2229     @Test
testStationaryDetection_QuickDozeOn_OneShot()2230     public void testStationaryDetection_QuickDozeOn_OneShot() {
2231         // Short timeout for testing.
2232         mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
2233         doReturn(Sensor.REPORTING_MODE_ONE_SHOT).when(mMotionSensor).getReportingMode();
2234         setAlarmSoon(false);
2235         enterDeepState(STATE_QUICK_DOZE_DELAY);
2236         mDeviceIdleController.stepIdleStateLocked("testing");
2237         verifyStateConditions(STATE_IDLE);
2238         // Quick doze progression through states, so time should have increased appropriately.
2239         mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
2240         final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
2241                 .forClass(AlarmManager.OnAlarmListener.class);
2242         doNothing().when(mAlarmManager).setWindow(
2243                 anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"), any(),
2244                 any(Handler.class));
2245         doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
2246                 eq("DeviceIdleController.motion_registration"),
2247                 alarmListener.capture(), any());
2248         ArgumentCaptor<TriggerEventListener> listenerCaptor =
2249                 ArgumentCaptor.forClass(TriggerEventListener.class);
2250 
2251         StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
2252         spyOn(stationaryListener);
2253         InOrder inOrder = inOrder(stationaryListener, mSensorManager);
2254 
2255         stationaryListener.motionExpected = true;
2256         mDeviceIdleController.registerStationaryListener(stationaryListener);
2257         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2258                 .onDeviceStationaryChanged(eq(false));
2259         assertFalse(stationaryListener.isStationary);
2260         inOrder.verify(mSensorManager)
2261                 .requestTriggerSensor(listenerCaptor.capture(), eq(mMotionSensor));
2262         final TriggerEventListener listener = listenerCaptor.getValue();
2263 
2264         // Trigger motion
2265         listener.onTrigger(mock(TriggerEvent.class));
2266         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2267                 .onDeviceStationaryChanged(eq(false));
2268 
2269         // Make sure the listener is re-registered.
2270         alarmListener.getValue().onAlarm();
2271         inOrder.verify(mSensorManager).requestTriggerSensor(eq(listener), eq(mMotionSensor));
2272     }
2273 
2274     @Test
testStationaryDetection_QuickDozeOn_MultiShot()2275     public void testStationaryDetection_QuickDozeOn_MultiShot() {
2276         // Short timeout for testing.
2277         mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
2278         doReturn(Sensor.REPORTING_MODE_CONTINUOUS).when(mMotionSensor).getReportingMode();
2279         setAlarmSoon(false);
2280         enterDeepState(STATE_QUICK_DOZE_DELAY);
2281         mDeviceIdleController.stepIdleStateLocked("testing");
2282         verifyStateConditions(STATE_IDLE);
2283         // Quick doze progression through states, so time should have increased appropriately.
2284         mInjector.nowElapsed += mConstants.QUICK_DOZE_DELAY_TIMEOUT;
2285         final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListener = ArgumentCaptor
2286                 .forClass(AlarmManager.OnAlarmListener.class);
2287         doNothing().when(mAlarmManager).setWindow(
2288                 anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"), any(),
2289                 any(Handler.class));
2290         doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
2291                 eq("DeviceIdleController.motion_registration"),
2292                 alarmListener.capture(), any());
2293         ArgumentCaptor<SensorEventListener> listenerCaptor =
2294                 ArgumentCaptor.forClass(SensorEventListener.class);
2295 
2296         StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
2297         spyOn(stationaryListener);
2298         InOrder inOrder = inOrder(stationaryListener, mSensorManager);
2299 
2300         stationaryListener.motionExpected = true;
2301         mDeviceIdleController.registerStationaryListener(stationaryListener);
2302         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2303                 .onDeviceStationaryChanged(eq(false));
2304         assertFalse(stationaryListener.isStationary);
2305         inOrder.verify(mSensorManager)
2306                 .registerListener(listenerCaptor.capture(), eq(mMotionSensor),
2307                         eq(SensorManager.SENSOR_DELAY_NORMAL));
2308         final SensorEventListener listener = listenerCaptor.getValue();
2309 
2310         // Trigger motion
2311         listener.onSensorChanged(mock(SensorEvent.class));
2312         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2313                 .onDeviceStationaryChanged(eq(false));
2314 
2315         // Make sure the listener is re-registered.
2316         alarmListener.getValue().onAlarm();
2317         inOrder.verify(mSensorManager)
2318                 .registerListener(eq(listener), eq(mMotionSensor),
2319                         eq(SensorManager.SENSOR_DELAY_NORMAL));
2320     }
2321 
2322     @Test
testStationaryDetection_NoDoze_AfterMotion()2323     public void testStationaryDetection_NoDoze_AfterMotion() {
2324         // Short timeout for testing.
2325         mConstants.MOTION_INACTIVE_TIMEOUT = 6000L;
2326         doReturn(Sensor.REPORTING_MODE_CONTINUOUS).when(mMotionSensor).getReportingMode();
2327         setAlarmSoon(true);
2328 
2329         final ArgumentCaptor<AlarmManager.OnAlarmListener> regAlarmListener = ArgumentCaptor
2330                 .forClass(AlarmManager.OnAlarmListener.class);
2331         final ArgumentCaptor<AlarmManager.OnAlarmListener> motionAlarmListener = ArgumentCaptor
2332                 .forClass(AlarmManager.OnAlarmListener.class);
2333         doNothing().when(mAlarmManager).setWindow(
2334                 anyInt(), anyLong(), anyLong(), eq("DeviceIdleController.motion"),
2335                 motionAlarmListener.capture(), any());
2336         doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
2337                 eq("DeviceIdleController.motion_registration"),
2338                 regAlarmListener.capture(), any());
2339         ArgumentCaptor<SensorEventListener> listenerCaptor =
2340                 ArgumentCaptor.forClass(SensorEventListener.class);
2341 
2342         StationaryListenerForTest stationaryListener = new StationaryListenerForTest();
2343         spyOn(stationaryListener);
2344         InOrder inOrder = inOrder(stationaryListener, mSensorManager, mAlarmManager);
2345 
2346         stationaryListener.motionExpected = true;
2347         mDeviceIdleController.registerStationaryListener(stationaryListener);
2348         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2349                 .onDeviceStationaryChanged(eq(false));
2350         assertFalse(stationaryListener.isStationary);
2351         inOrder.verify(mSensorManager)
2352                 .registerListener(listenerCaptor.capture(), eq(mMotionSensor),
2353                         eq(SensorManager.SENSOR_DELAY_NORMAL));
2354         inOrder.verify(mAlarmManager).setWindow(
2355                 anyInt(), eq(mInjector.nowElapsed + mConstants.MOTION_INACTIVE_TIMEOUT), anyLong(),
2356                 eq("DeviceIdleController.motion"), any(), any(Handler.class));
2357         final SensorEventListener listener = listenerCaptor.getValue();
2358 
2359         // Trigger motion
2360         listener.onSensorChanged(mock(SensorEvent.class));
2361         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2362                 .onDeviceStationaryChanged(eq(false));
2363         final ArgumentCaptor<Long> registrationTimeCaptor = ArgumentCaptor.forClass(Long.class);
2364         inOrder.verify(mAlarmManager).setWindow(
2365                 anyInt(), registrationTimeCaptor.capture(), anyLong(),
2366                 eq("DeviceIdleController.motion_registration"), any(), any(Handler.class));
2367 
2368         // Make sure the listener is re-registered.
2369         mInjector.nowElapsed = registrationTimeCaptor.getValue();
2370         regAlarmListener.getValue().onAlarm();
2371         inOrder.verify(mSensorManager)
2372                 .registerListener(eq(listener), eq(mMotionSensor),
2373                         eq(SensorManager.SENSOR_DELAY_NORMAL));
2374         final ArgumentCaptor<Long> timeoutCaptor = ArgumentCaptor.forClass(Long.class);
2375         inOrder.verify(mAlarmManager).setWindow(anyInt(), timeoutCaptor.capture(), anyLong(),
2376                 eq("DeviceIdleController.motion"), any(), any(Handler.class));
2377 
2378         // No motion before timeout
2379         stationaryListener.motionExpected = false;
2380         mInjector.nowElapsed = timeoutCaptor.getValue();
2381         motionAlarmListener.getValue().onAlarm();
2382         inOrder.verify(stationaryListener, timeout(1000L).times(1))
2383                 .onDeviceStationaryChanged(eq(true));
2384     }
2385 
2386     @Test
testEmergencyEndsIdle()2387     public void testEmergencyEndsIdle() {
2388         enterDeepState(STATE_ACTIVE);
2389         setEmergencyCallActive(true);
2390         verifyStateConditions(STATE_ACTIVE);
2391 
2392         enterDeepState(STATE_INACTIVE);
2393         setEmergencyCallActive(true);
2394         verifyStateConditions(STATE_ACTIVE);
2395 
2396         enterDeepState(STATE_IDLE_PENDING);
2397         setEmergencyCallActive(true);
2398         verifyStateConditions(STATE_ACTIVE);
2399 
2400         enterDeepState(STATE_SENSING);
2401         setEmergencyCallActive(true);
2402         verifyStateConditions(STATE_ACTIVE);
2403 
2404         enterDeepState(STATE_LOCATING);
2405         setEmergencyCallActive(true);
2406         verifyStateConditions(STATE_ACTIVE);
2407 
2408         // Quick doze enabled or not shouldn't affect the end state.
2409         enterDeepState(STATE_QUICK_DOZE_DELAY);
2410         setQuickDozeEnabled(true);
2411         setEmergencyCallActive(true);
2412         verifyStateConditions(STATE_ACTIVE);
2413 
2414         enterDeepState(STATE_QUICK_DOZE_DELAY);
2415         setQuickDozeEnabled(false);
2416         setEmergencyCallActive(true);
2417         verifyStateConditions(STATE_ACTIVE);
2418 
2419         enterDeepState(STATE_IDLE);
2420         setEmergencyCallActive(true);
2421         verifyStateConditions(STATE_ACTIVE);
2422 
2423         enterDeepState(STATE_IDLE_MAINTENANCE);
2424         setEmergencyCallActive(true);
2425         verifyStateConditions(STATE_ACTIVE);
2426     }
2427 
2428     @Test
testEmergencyEndsLightIdle()2429     public void testEmergencyEndsLightIdle() {
2430         enterLightState(LIGHT_STATE_ACTIVE);
2431         setEmergencyCallActive(true);
2432         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2433 
2434         enterLightState(LIGHT_STATE_INACTIVE);
2435         setEmergencyCallActive(true);
2436         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2437 
2438         enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
2439         setEmergencyCallActive(true);
2440         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2441 
2442         enterLightState(LIGHT_STATE_IDLE);
2443         setEmergencyCallActive(true);
2444         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2445 
2446         enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
2447         setEmergencyCallActive(true);
2448         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2449 
2450         enterLightState(LIGHT_STATE_OVERRIDE);
2451         setEmergencyCallActive(true);
2452         verifyLightStateConditions(LIGHT_STATE_ACTIVE);
2453     }
2454 
enterDeepState(int state)2455     private void enterDeepState(int state) {
2456         switch (state) {
2457             case STATE_ACTIVE:
2458                 setScreenOn(true);
2459                 mDeviceIdleController.becomeActiveLocked("testing", 0);
2460                 break;
2461             case STATE_QUICK_DOZE_DELAY:
2462                 // Start off from ACTIVE in case we're already past the desired state.
2463                 enterDeepState(STATE_ACTIVE);
2464                 setQuickDozeEnabled(true);
2465                 setScreenOn(false);
2466                 setChargingOn(false);
2467                 setEmergencyCallActive(false);
2468                 mDeviceIdleController.becomeInactiveIfAppropriateLocked();
2469                 break;
2470             case STATE_LOCATING:
2471                 mInjector.locationManager = mLocationManager;
2472                 doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(
2473                         anyString());
2474                 // Fallthrough to step loop.
2475             case STATE_IDLE_PENDING:
2476             case STATE_SENSING:
2477             case STATE_IDLE:
2478             case STATE_IDLE_MAINTENANCE:
2479                 // Make sure the controller doesn't think there's a wake-from-idle alarm coming
2480                 // soon.
2481                 setAlarmSoon(false);
2482             case STATE_INACTIVE:
2483                 // Start off from ACTIVE in case we're already past the desired state.
2484                 enterDeepState(STATE_ACTIVE);
2485                 setQuickDozeEnabled(false);
2486                 setScreenOn(false);
2487                 setChargingOn(false);
2488                 setEmergencyCallActive(false);
2489                 mDeviceIdleController.becomeInactiveIfAppropriateLocked();
2490                 int count = 0;
2491                 while (mDeviceIdleController.getState() != state) {
2492                     // Stepping through each state ensures that the proper features are turned
2493                     // on/off.
2494                     mDeviceIdleController.stepIdleStateLocked("testing");
2495                     count++;
2496                     if (count > 10) {
2497                         fail("Infinite loop. Check test configuration. Currently at " +
2498                                 stateToString(mDeviceIdleController.getState()));
2499                     }
2500                 }
2501                 break;
2502             default:
2503                 fail("Unknown deep state " + stateToString(state));
2504         }
2505     }
2506 
enterLightState(int lightState)2507     private void enterLightState(int lightState) {
2508         switch (lightState) {
2509             case LIGHT_STATE_ACTIVE:
2510                 setScreenOn(true);
2511                 mDeviceIdleController.becomeActiveLocked("testing", 0);
2512                 break;
2513             case LIGHT_STATE_INACTIVE:
2514             case LIGHT_STATE_IDLE:
2515             case LIGHT_STATE_IDLE_MAINTENANCE:
2516                 // Start off from ACTIVE in case we're already past the desired state.
2517                 enterLightState(LIGHT_STATE_ACTIVE);
2518                 setScreenOn(false);
2519                 setChargingOn(false);
2520                 setEmergencyCallActive(false);
2521                 int count = 0;
2522                 mDeviceIdleController.becomeInactiveIfAppropriateLocked();
2523                 while (mDeviceIdleController.getLightState() != lightState) {
2524                     // Stepping through each state ensures that the proper features are turned
2525                     // on/off.
2526                     mDeviceIdleController.stepLightIdleStateLocked("testing");
2527 
2528                     count++;
2529                     if (count > 10) {
2530                         fail("Infinite loop. Check test configuration. Currently at " +
2531                                 lightStateToString(mDeviceIdleController.getLightState()));
2532                     }
2533                 }
2534                 break;
2535             case LIGHT_STATE_WAITING_FOR_NETWORK:
2536             case LIGHT_STATE_OVERRIDE:
2537                 setScreenOn(false);
2538                 setChargingOn(false);
2539                 setEmergencyCallActive(false);
2540                 mDeviceIdleController.setLightStateForTest(lightState);
2541                 break;
2542             default:
2543                 fail("Unknown light state " + lightStateToString(lightState));
2544         }
2545     }
2546 
setChargingOn(boolean on)2547     private void setChargingOn(boolean on) {
2548         mDeviceIdleController.updateChargingLocked(on);
2549     }
2550 
setEmergencyCallActive(boolean active)2551     private void setEmergencyCallActive(boolean active) {
2552         if (active) {
2553             mEmergencyCallListener.onOutgoingEmergencyCall(mock(EmergencyNumber.class), 0);
2554         } else {
2555             mCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_IDLE);
2556         }
2557     }
2558 
setScreenLocked(boolean locked)2559     private void setScreenLocked(boolean locked) {
2560         mDeviceIdleController.keyguardShowingLocked(locked);
2561     }
2562 
setScreenOn(boolean on)2563     private void setScreenOn(boolean on) {
2564         doReturn(on).when(mPowerManager).isInteractive();
2565         mDeviceIdleController.updateInteractivityLocked();
2566     }
2567 
setNetworkConnected(boolean connected)2568     private void setNetworkConnected(boolean connected) {
2569         mInjector.connectivityManager = mConnectivityManager;
2570         final NetworkInfo ani = mock(NetworkInfo.class);
2571         doReturn(connected).when(ani).isConnected();
2572         doReturn(ani).when(mConnectivityManager).getActiveNetworkInfo();
2573         mDeviceIdleController.updateConnectivityState(null);
2574     }
2575 
setQuickDozeEnabled(boolean on)2576     private void setQuickDozeEnabled(boolean on) {
2577         mDeviceIdleController.updateQuickDozeFlagLocked(on);
2578     }
2579 
setAlarmSoon(boolean isSoon)2580     private void setAlarmSoon(boolean isSoon) {
2581         if (isSoon) {
2582             doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2)
2583                     .when(mAlarmManager).getNextWakeFromIdleTime();
2584         } else {
2585             doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
2586         }
2587     }
2588 
verifyStateConditions(int expectedState)2589     private void verifyStateConditions(int expectedState) {
2590         int curState = mDeviceIdleController.getState();
2591         assertEquals(
2592                 "Expected " + stateToString(expectedState) + " but was " + stateToString(curState),
2593                 expectedState, curState);
2594 
2595         switch (expectedState) {
2596             case STATE_ACTIVE:
2597                 assertFalse(mDeviceIdleController.mMotionListener.isActive());
2598                 assertFalse(mAnyMotionDetector.isMonitoring);
2599                 break;
2600             case STATE_INACTIVE:
2601                 assertFalse(mDeviceIdleController.mMotionListener.isActive());
2602                 assertFalse(mAnyMotionDetector.isMonitoring);
2603                 assertFalse(mDeviceIdleController.isCharging());
2604                 assertFalse(mDeviceIdleController.isScreenOn()
2605                         && !mDeviceIdleController.isKeyguardShowing());
2606                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2607                 break;
2608             case STATE_IDLE_PENDING:
2609                 assertEquals(
2610                         mDeviceIdleController.hasMotionSensor(),
2611                         mDeviceIdleController.mMotionListener.isActive());
2612                 assertFalse(mAnyMotionDetector.isMonitoring);
2613                 assertFalse(mDeviceIdleController.isCharging());
2614                 assertFalse(mDeviceIdleController.isScreenOn()
2615                         && !mDeviceIdleController.isKeyguardShowing());
2616                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2617                 break;
2618             case STATE_SENSING:
2619                 assertEquals(
2620                         mDeviceIdleController.hasMotionSensor(),
2621                         mDeviceIdleController.mMotionListener.isActive());
2622                 assertEquals(
2623                         mDeviceIdleController.hasMotionSensor(),
2624                         mAnyMotionDetector.isMonitoring);
2625                 assertFalse(mDeviceIdleController.isCharging());
2626                 assertFalse(mDeviceIdleController.isScreenOn()
2627                         && !mDeviceIdleController.isKeyguardShowing());
2628                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2629                 break;
2630             case STATE_LOCATING:
2631                 assertEquals(
2632                         mDeviceIdleController.hasMotionSensor(),
2633                         mDeviceIdleController.mMotionListener.isActive());
2634                 assertFalse(mDeviceIdleController.isCharging());
2635                 assertFalse(mDeviceIdleController.isScreenOn()
2636                         && !mDeviceIdleController.isKeyguardShowing());
2637                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2638                 break;
2639             case STATE_IDLE:
2640                 if (mDeviceIdleController.hasMotionSensor()) {
2641                     assertTrue(mDeviceIdleController.mMotionListener.isActive()
2642                         // If quick doze is enabled, the motion listener should NOT be active.
2643                         || mDeviceIdleController.isQuickDozeEnabled());
2644                 }
2645                 assertFalse(mAnyMotionDetector.isMonitoring);
2646                 assertFalse(mDeviceIdleController.isCharging());
2647                 assertFalse(mDeviceIdleController.isScreenOn()
2648                         && !mDeviceIdleController.isKeyguardShowing());
2649                 // Light state should be OVERRIDE at this point.
2650                 verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
2651                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2652                 break;
2653             case STATE_IDLE_MAINTENANCE:
2654                 if (mDeviceIdleController.hasMotionSensor()) {
2655                     assertTrue(mDeviceIdleController.mMotionListener.isActive()
2656                         // If quick doze is enabled, the motion listener should NOT be active.
2657                         || mDeviceIdleController.isQuickDozeEnabled());
2658                 }
2659                 assertFalse(mAnyMotionDetector.isMonitoring);
2660                 assertFalse(mDeviceIdleController.isCharging());
2661                 assertFalse(mDeviceIdleController.isScreenOn()
2662                         && !mDeviceIdleController.isKeyguardShowing());
2663                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2664                 break;
2665             case STATE_QUICK_DOZE_DELAY:
2666                 // If quick doze is enabled, the motion listener should NOT be active.
2667                 assertFalse(mDeviceIdleController.mMotionListener.isActive());
2668                 assertFalse(mAnyMotionDetector.isMonitoring);
2669                 assertFalse(mDeviceIdleController.isCharging());
2670                 assertFalse(mDeviceIdleController.isScreenOn()
2671                         && !mDeviceIdleController.isKeyguardShowing());
2672                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2673                 break;
2674             default:
2675                 fail("Conditions for " + stateToString(expectedState) + " unknown.");
2676         }
2677     }
2678 
verifyLightStateConditions(int expectedLightState)2679     private void verifyLightStateConditions(int expectedLightState) {
2680         int curLightState = mDeviceIdleController.getLightState();
2681         assertEquals(
2682                 "Expected " + lightStateToString(expectedLightState)
2683                         + " but was " + lightStateToString(curLightState),
2684                 expectedLightState, curLightState);
2685 
2686         switch (expectedLightState) {
2687             case LIGHT_STATE_ACTIVE:
2688                 assertTrue(
2689                         mDeviceIdleController.isCharging() || mDeviceIdleController.isScreenOn()
2690                                 || mDeviceIdleController.isEmergencyCallActive()
2691                                 // Or there's an alarm coming up soon.
2692                                 || SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM
2693                                 > mAlarmManager.getNextWakeFromIdleTime());
2694                 break;
2695             case LIGHT_STATE_INACTIVE:
2696             case LIGHT_STATE_IDLE:
2697             case LIGHT_STATE_WAITING_FOR_NETWORK:
2698             case LIGHT_STATE_IDLE_MAINTENANCE:
2699             case LIGHT_STATE_OVERRIDE:
2700                 assertFalse(mDeviceIdleController.isCharging());
2701                 assertFalse(mDeviceIdleController.isScreenOn()
2702                         && !mDeviceIdleController.isKeyguardShowing());
2703                 assertFalse(mDeviceIdleController.isEmergencyCallActive());
2704                 break;
2705             default:
2706                 fail("Conditions for " + lightStateToString(expectedLightState) + " unknown.");
2707         }
2708     }
2709 
checkNextAlarmTimeWithNewPreIdleFactor(float factor, int state)2710     private void checkNextAlarmTimeWithNewPreIdleFactor(float factor, int state) {
2711         final long errorTolerance = 1000;
2712         enterDeepState(state);
2713         long now = SystemClock.elapsedRealtime();
2714         long alarm = mDeviceIdleController.getNextAlarmTime();
2715         if (state == STATE_INACTIVE || state == STATE_IDLE_PENDING) {
2716             int ret = mDeviceIdleController.setPreIdleTimeoutFactor(factor);
2717             if (Float.compare(factor, 1.0f) == 0) {
2718                 assertEquals("setPreIdleTimeoutMode: " + factor + " failed.",
2719                         mDeviceIdleController.SET_IDLE_FACTOR_RESULT_IGNORED, ret);
2720             } else {
2721                 assertEquals("setPreIdleTimeoutMode: " + factor + " failed.",
2722                         mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK, ret);
2723             }
2724             if (ret == mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK) {
2725                 long newAlarm = mDeviceIdleController.getNextAlarmTime();
2726                 long newDelay = (long) ((alarm - now) * factor);
2727                 assertTrue("setPreIdleTimeoutFactor: " + factor,
2728                         Math.abs(newDelay - (newAlarm - now)) <  errorTolerance);
2729                 mDeviceIdleController.resetPreIdleTimeoutMode();
2730                 newAlarm = mDeviceIdleController.getNextAlarmTime();
2731                 assertTrue("resetPreIdleTimeoutMode from: " + factor,
2732                         Math.abs(newAlarm - alarm) < errorTolerance);
2733                 mDeviceIdleController.setPreIdleTimeoutFactor(factor);
2734                 now = SystemClock.elapsedRealtime();
2735                 enterDeepState(state);
2736                 newAlarm = mDeviceIdleController.getNextAlarmTime();
2737                 assertTrue("setPreIdleTimeoutFactor: " + factor + " before step to idle",
2738                         Math.abs(newDelay - (newAlarm - now)) <  errorTolerance);
2739                 mDeviceIdleController.resetPreIdleTimeoutMode();
2740             }
2741         } else {
2742             mDeviceIdleController.setPreIdleTimeoutFactor(factor);
2743             long newAlarm = mDeviceIdleController.getNextAlarmTime();
2744             assertTrue("setPreIdleTimeoutFactor: " + factor
2745                     + " shounld not change next alarm" ,
2746                     (newAlarm == alarm));
2747             mDeviceIdleController.resetPreIdleTimeoutMode();
2748         }
2749     }
2750 
checkMaybeDoAnImmediateMaintenance(float factor)2751     private void checkMaybeDoAnImmediateMaintenance(float factor) {
2752         int ret = mDeviceIdleController.setPreIdleTimeoutFactor(factor);
2753         final long minuteInMillis = 60 * 1000;
2754         if (Float.compare(factor, 1.0f) == 0) {
2755             assertEquals("setPreIdleTimeoutMode: " + factor + " failed.",
2756                     mDeviceIdleController.SET_IDLE_FACTOR_RESULT_IGNORED, ret);
2757         } else {
2758             assertEquals("setPreIdleTimeoutMode: " + factor + " failed.",
2759                     mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK, ret);
2760         }
2761         if (ret == mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK) {
2762             enterDeepState(STATE_IDLE);
2763             long now = SystemClock.elapsedRealtime();
2764             mDeviceIdleController.setIdleStartTimeForTest(
2765                     now - (long) (mConstants.IDLE_TIMEOUT * 0.6));
2766             verifyStateConditions(STATE_IDLE);
2767             mDeviceIdleController.setIdleStartTimeForTest(
2768                     now - (long) (mConstants.IDLE_TIMEOUT * 1.2));
2769             verifyStateConditions(STATE_IDLE_MAINTENANCE);
2770             mDeviceIdleController.resetPreIdleTimeoutMode();
2771         }
2772     }
2773 }
2774