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