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