1 /*
2  * Copyright (C) 2020 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 
17 package com.android.server.devicestate;
18 
19 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.when;
25 import static org.testng.Assert.assertEquals;
26 import static org.testng.Assert.assertFalse;
27 import static org.testng.Assert.assertNotNull;
28 import static org.testng.Assert.assertNull;
29 import static org.testng.Assert.assertThrows;
30 
31 import android.hardware.devicestate.DeviceStateInfo;
32 import android.hardware.devicestate.DeviceStateRequest;
33 import android.hardware.devicestate.IDeviceStateManagerCallback;
34 import android.os.Binder;
35 import android.os.IBinder;
36 import android.os.RemoteException;
37 import android.platform.test.annotations.Presubmit;
38 
39 import androidx.test.InstrumentationRegistry;
40 import androidx.test.filters.FlakyTest;
41 import androidx.test.runner.AndroidJUnit4;
42 
43 import com.android.server.wm.ActivityTaskManagerInternal;
44 import com.android.server.wm.WindowProcessController;
45 
46 import junit.framework.Assert;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 
52 import java.util.Arrays;
53 import java.util.HashMap;
54 import java.util.Optional;
55 
56 import javax.annotation.Nullable;
57 
58 /**
59  * Unit tests for {@link DeviceStateManagerService}.
60  * <p/>
61  * Run with <code>atest DeviceStateManagerServiceTest</code>.
62  */
63 @Presubmit
64 @RunWith(AndroidJUnit4.class)
65 public final class DeviceStateManagerServiceTest {
66     private static final DeviceState DEFAULT_DEVICE_STATE =
67             new DeviceState(0, "DEFAULT", 0 /* flags */);
68     private static final DeviceState OTHER_DEVICE_STATE =
69             new DeviceState(1, "OTHER", 0 /* flags */);
70     private static final DeviceState DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP =
71             new DeviceState(2, "DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP",
72                     DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP /* flags */);
73     // A device state that is not reported as being supported for the default test provider.
74     private static final DeviceState UNSUPPORTED_DEVICE_STATE =
75             new DeviceState(255, "UNSUPPORTED", 0 /* flags */);
76 
77     private static final int[] SUPPORTED_DEVICE_STATE_IDENTIFIERS =
78             new int[]{DEFAULT_DEVICE_STATE.getIdentifier(), OTHER_DEVICE_STATE.getIdentifier(),
79                     DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP.getIdentifier()};
80 
81     private static final int FAKE_PROCESS_ID = 100;
82 
83     private TestDeviceStatePolicy mPolicy;
84     private TestDeviceStateProvider mProvider;
85     private DeviceStateManagerService mService;
86     private TestSystemPropertySetter mSysPropSetter;
87     private WindowProcessController mWindowProcessController;
88 
89     @Before
setup()90     public void setup() {
91         mProvider = new TestDeviceStateProvider();
92         mPolicy = new TestDeviceStatePolicy(mProvider);
93         mSysPropSetter = new TestSystemPropertySetter();
94         setupDeviceStateManagerService();
95         flushHandler(); // Flush the handler to ensure the initial values are committed.
96     }
97 
setupDeviceStateManagerService()98     private void setupDeviceStateManagerService() {
99         mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy,
100                 mSysPropSetter);
101 
102         // Necessary to allow us to check for top app process id in tests
103         mService.mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
104         mWindowProcessController = mock(WindowProcessController.class);
105         when(mService.mActivityTaskManagerInternal.getTopApp())
106                 .thenReturn(mWindowProcessController);
107         when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);
108     }
109 
flushHandler()110     private void flushHandler() {
111         flushHandler(1);
112     }
113 
flushHandler(int count)114     private void flushHandler(int count) {
115         for (int i = 0; i < count; i++) {
116             mService.getHandler().runWithScissors(() -> {}, 0);
117         }
118     }
119 
120     @Test
baseStateChanged()121     public void baseStateChanged() {
122         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
123         assertEquals(mService.getPendingState(), Optional.empty());
124         assertEquals(mSysPropSetter.getValue(),
125                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
126         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
127         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
128                 DEFAULT_DEVICE_STATE.getIdentifier());
129 
130         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
131         flushHandler();
132         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
133         assertEquals(mService.getPendingState(), Optional.empty());
134         assertEquals(mSysPropSetter.getValue(),
135                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
136         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
137         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
138                 OTHER_DEVICE_STATE.getIdentifier());
139     }
140 
141     @Test
baseStateChanged_withStatePendingPolicyCallback()142     public void baseStateChanged_withStatePendingPolicyCallback() {
143         mPolicy.blockConfigure();
144 
145         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
146         flushHandler();
147         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
148         assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE));
149         assertEquals(mSysPropSetter.getValue(),
150                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
151         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
152         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
153                 OTHER_DEVICE_STATE.getIdentifier());
154 
155         mProvider.setState(DEFAULT_DEVICE_STATE.getIdentifier());
156         flushHandler();
157         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
158         assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE));
159         assertEquals(mSysPropSetter.getValue(),
160                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
161         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
162         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
163                 OTHER_DEVICE_STATE.getIdentifier());
164 
165         mPolicy.resumeConfigure();
166         flushHandler();
167         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
168         assertEquals(mService.getPendingState(), Optional.empty());
169         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
170         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
171                 DEFAULT_DEVICE_STATE.getIdentifier());
172     }
173 
174     @Test
baseStateChanged_unsupportedState()175     public void baseStateChanged_unsupportedState() {
176         assertThrows(IllegalArgumentException.class, () -> {
177             mProvider.setState(UNSUPPORTED_DEVICE_STATE.getIdentifier());
178         });
179 
180         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
181         assertEquals(mService.getPendingState(), Optional.empty());
182         assertEquals(mSysPropSetter.getValue(),
183                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
184         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
185         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
186                 DEFAULT_DEVICE_STATE.getIdentifier());
187     }
188 
189     @Test
baseStateChanged_invalidState()190     public void baseStateChanged_invalidState() {
191         assertThrows(IllegalArgumentException.class, () -> {
192             mProvider.setState(INVALID_DEVICE_STATE);
193         });
194 
195         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
196         assertEquals(mService.getPendingState(), Optional.empty());
197         assertEquals(mSysPropSetter.getValue(),
198                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
199         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
200         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
201                 DEFAULT_DEVICE_STATE.getIdentifier());
202     }
203 
204     @Test
supportedStatesChanged()205     public void supportedStatesChanged() throws RemoteException {
206         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
207         mService.getBinderService().registerCallback(callback);
208 
209         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
210         assertEquals(mService.getPendingState(), Optional.empty());
211         assertEquals(mSysPropSetter.getValue(),
212                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
213         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
214         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE,
215                 OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP);
216 
217         mProvider.notifySupportedDeviceStates(new DeviceState[]{DEFAULT_DEVICE_STATE});
218         flushHandler();
219 
220         // The current committed and requests states do not change because the current state remains
221         // supported.
222         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
223         assertEquals(mService.getPendingState(), Optional.empty());
224         assertEquals(mSysPropSetter.getValue(),
225                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
226         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
227         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE);
228 
229         assertArrayEquals(callback.getLastNotifiedInfo().supportedStates,
230                 new int[]{DEFAULT_DEVICE_STATE.getIdentifier()});
231     }
232 
233     @Test
supportedStatesChanged_statesRemainSame()234     public void supportedStatesChanged_statesRemainSame() throws RemoteException {
235         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
236         mService.getBinderService().registerCallback(callback);
237 
238         // An initial callback will be triggered on registration, so we clear it here.
239         flushHandler();
240         callback.clearLastNotifiedInfo();
241 
242         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
243         assertEquals(mService.getPendingState(), Optional.empty());
244         assertEquals(mSysPropSetter.getValue(),
245                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
246         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
247         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE,
248                 OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP);
249 
250         mProvider.notifySupportedDeviceStates(new DeviceState[]{DEFAULT_DEVICE_STATE,
251                 OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP});
252         flushHandler();
253 
254         // The current committed and requests states do not change because the current state remains
255         // supported.
256         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
257         assertEquals(mService.getPendingState(), Optional.empty());
258         assertEquals(mSysPropSetter.getValue(),
259                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
260         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
261         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE,
262                 OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP);
263 
264         // The callback wasn't notified about a change in supported states as the states have not
265         // changed.
266         assertNull(callback.getLastNotifiedInfo());
267     }
268 
269     @Test
getDeviceStateInfo()270     public void getDeviceStateInfo() throws RemoteException {
271         DeviceStateInfo info = mService.getBinderService().getDeviceStateInfo();
272         assertNotNull(info);
273         assertArrayEquals(info.supportedStates, SUPPORTED_DEVICE_STATE_IDENTIFIERS);
274         assertEquals(info.baseState, DEFAULT_DEVICE_STATE.getIdentifier());
275         assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier());
276     }
277 
278     @Test
getDeviceStateInfo_baseStateAndCommittedStateNotSet()279     public void getDeviceStateInfo_baseStateAndCommittedStateNotSet() throws RemoteException {
280         // Create a provider and a service without an initial base state.
281         mProvider = new TestDeviceStateProvider(null /* initialState */);
282         mPolicy = new TestDeviceStatePolicy(mProvider);
283         setupDeviceStateManagerService();
284         flushHandler(); // Flush the handler to ensure the initial values are committed.
285 
286         DeviceStateInfo info = mService.getBinderService().getDeviceStateInfo();
287 
288         assertArrayEquals(info.supportedStates, SUPPORTED_DEVICE_STATE_IDENTIFIERS);
289         assertEquals(info.baseState, INVALID_DEVICE_STATE);
290         assertEquals(info.currentState, INVALID_DEVICE_STATE);
291     }
292 
293     @FlakyTest(bugId = 223153452)
294     @Test
registerCallback()295     public void registerCallback() throws RemoteException {
296         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
297         mService.getBinderService().registerCallback(callback);
298 
299         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
300         flushHandler();
301         assertEquals(callback.getLastNotifiedInfo().baseState,
302                 OTHER_DEVICE_STATE.getIdentifier());
303         assertEquals(callback.getLastNotifiedInfo().currentState,
304                 OTHER_DEVICE_STATE.getIdentifier());
305 
306         mProvider.setState(DEFAULT_DEVICE_STATE.getIdentifier());
307         flushHandler();
308         assertEquals(callback.getLastNotifiedInfo().baseState,
309                 DEFAULT_DEVICE_STATE.getIdentifier());
310         assertEquals(callback.getLastNotifiedInfo().currentState,
311                 DEFAULT_DEVICE_STATE.getIdentifier());
312 
313         mPolicy.blockConfigure();
314         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
315         flushHandler();
316         // The callback should not have been notified of the state change as the policy is still
317         // pending callback.
318         assertEquals(callback.getLastNotifiedInfo().baseState,
319                 DEFAULT_DEVICE_STATE.getIdentifier());
320         assertEquals(callback.getLastNotifiedInfo().currentState,
321                 DEFAULT_DEVICE_STATE.getIdentifier());
322 
323         mPolicy.resumeConfigure();
324         flushHandler();
325         // Now that the policy is finished processing the callback should be notified of the state
326         // change.
327         assertEquals(callback.getLastNotifiedInfo().baseState,
328                 OTHER_DEVICE_STATE.getIdentifier());
329         assertEquals(callback.getLastNotifiedInfo().currentState,
330                 OTHER_DEVICE_STATE.getIdentifier());
331     }
332 
333     @Test
registerCallback_emitsInitialValue()334     public void registerCallback_emitsInitialValue() throws RemoteException {
335         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
336         mService.getBinderService().registerCallback(callback);
337         flushHandler();
338         assertNotNull(callback.getLastNotifiedInfo());
339         assertEquals(callback.getLastNotifiedInfo().baseState,
340                 DEFAULT_DEVICE_STATE.getIdentifier());
341         assertEquals(callback.getLastNotifiedInfo().currentState,
342                 DEFAULT_DEVICE_STATE.getIdentifier());
343     }
344 
345     @Test
registerCallback_initialValueUnavailable()346     public void registerCallback_initialValueUnavailable() throws RemoteException {
347         // Create a provider and a service without an initial base state.
348         mProvider = new TestDeviceStateProvider(null /* initialState */);
349         mPolicy = new TestDeviceStatePolicy(mProvider);
350         setupDeviceStateManagerService();
351         flushHandler(); // Flush the handler to ensure the initial values are committed.
352 
353         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
354         mService.getBinderService().registerCallback(callback);
355         flushHandler();
356         // The callback should never be called when the base state is not set yet.
357         assertNull(callback.getLastNotifiedInfo());
358     }
359 
360     @Test
requestState()361     public void requestState() throws RemoteException {
362         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
363         mService.getBinderService().registerCallback(callback);
364         flushHandler();
365 
366         final IBinder token = new Binder();
367         assertEquals(callback.getLastNotifiedStatus(token),
368                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
369 
370         mService.getBinderService().requestState(token, OTHER_DEVICE_STATE.getIdentifier(),
371                 0 /* flags */);
372         // Flush the handler twice. The first flush ensures the request is added and the policy is
373         // notified, while the second flush ensures the callback is notified once the change is
374         // committed.
375         flushHandler(2 /* count */);
376 
377         assertEquals(callback.getLastNotifiedStatus(token),
378                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
379         // Committed state changes as there is a requested override.
380         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
381         assertEquals(mSysPropSetter.getValue(),
382                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
383         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
384         assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE);
385         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
386                 OTHER_DEVICE_STATE.getIdentifier());
387 
388         assertNotNull(callback.getLastNotifiedInfo());
389         assertEquals(callback.getLastNotifiedInfo().baseState,
390                 DEFAULT_DEVICE_STATE.getIdentifier());
391         assertEquals(callback.getLastNotifiedInfo().currentState,
392                 OTHER_DEVICE_STATE.getIdentifier());
393 
394         mService.getBinderService().cancelStateRequest();
395         flushHandler();
396 
397         assertEquals(callback.getLastNotifiedStatus(token),
398                 TestDeviceStateManagerCallback.STATUS_CANCELED);
399         // Committed state is set back to the requested state once the override is cleared.
400         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
401         assertEquals(mSysPropSetter.getValue(),
402                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
403         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
404         assertFalse(mService.getOverrideState().isPresent());
405         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
406                 DEFAULT_DEVICE_STATE.getIdentifier());
407 
408         assertEquals(callback.getLastNotifiedInfo().baseState,
409                 DEFAULT_DEVICE_STATE.getIdentifier());
410         assertEquals(callback.getLastNotifiedInfo().currentState,
411                 DEFAULT_DEVICE_STATE.getIdentifier());
412     }
413 
414     @FlakyTest(bugId = 200332057)
415     @Test
requestState_pendingStateAtRequest()416     public void requestState_pendingStateAtRequest() throws RemoteException {
417         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
418         mService.getBinderService().registerCallback(callback);
419         flushHandler();
420 
421         mPolicy.blockConfigure();
422 
423         final IBinder firstRequestToken = new Binder();
424         final IBinder secondRequestToken = new Binder();
425         assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
426                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
427         assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
428                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
429 
430         mService.getBinderService().requestState(firstRequestToken,
431                 OTHER_DEVICE_STATE.getIdentifier(), 0 /* flags */);
432         // Flush the handler twice. The first flush ensures the request is added and the policy is
433         // notified, while the second flush ensures the callback is notified once the change is
434         // committed.
435         flushHandler(2 /* count */);
436 
437         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
438         assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE));
439         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
440         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
441                 OTHER_DEVICE_STATE.getIdentifier());
442 
443         mService.getBinderService().requestState(secondRequestToken,
444                 DEFAULT_DEVICE_STATE.getIdentifier(), 0 /* flags */);
445         mPolicy.resumeConfigureOnce();
446         flushHandler();
447 
448         // First request status is now canceled as there is another pending request.
449         assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
450                 TestDeviceStateManagerCallback.STATUS_CANCELED);
451         // Second request status still unknown because the service is still awaiting policy
452         // callback.
453         assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
454                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
455         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
456         assertEquals(mService.getPendingState(), Optional.of(DEFAULT_DEVICE_STATE));
457         assertEquals(mSysPropSetter.getValue(),
458                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
459         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
460         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
461                 DEFAULT_DEVICE_STATE.getIdentifier());
462 
463         mPolicy.resumeConfigure();
464         flushHandler();
465 
466         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
467         assertEquals(mService.getPendingState(), Optional.empty());
468         assertEquals(mSysPropSetter.getValue(),
469                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
470         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
471         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
472                 DEFAULT_DEVICE_STATE.getIdentifier());
473 
474         // Now cancel the second request to make the first request active.
475         mService.getBinderService().cancelStateRequest();
476         flushHandler();
477 
478         assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
479                 TestDeviceStateManagerCallback.STATUS_CANCELED);
480         assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
481                 TestDeviceStateManagerCallback.STATUS_CANCELED);
482 
483         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
484         assertEquals(mService.getPendingState(), Optional.empty());
485         assertEquals(mSysPropSetter.getValue(),
486                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
487         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
488         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
489                 DEFAULT_DEVICE_STATE.getIdentifier());
490     }
491 
492     @Test
requestState_sameAsBaseState()493     public void requestState_sameAsBaseState() throws RemoteException {
494         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
495         mService.getBinderService().registerCallback(callback);
496         flushHandler();
497 
498         final IBinder token = new Binder();
499         assertEquals(callback.getLastNotifiedStatus(token),
500                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
501 
502         mService.getBinderService().requestState(token, DEFAULT_DEVICE_STATE.getIdentifier(),
503                 0 /* flags */);
504         flushHandler();
505 
506         assertEquals(callback.getLastNotifiedStatus(token),
507                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
508     }
509 
510     @Test
requestState_flagCancelWhenBaseChanges()511     public void requestState_flagCancelWhenBaseChanges() throws RemoteException {
512         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
513         mService.getBinderService().registerCallback(callback);
514         flushHandler();
515 
516         final IBinder token = new Binder();
517         assertEquals(callback.getLastNotifiedStatus(token),
518                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
519 
520         mService.getBinderService().requestState(token, OTHER_DEVICE_STATE.getIdentifier(),
521                 DeviceStateRequest.FLAG_CANCEL_WHEN_BASE_CHANGES);
522         // Flush the handler twice. The first flush ensures the request is added and the policy is
523         // notified, while the second flush ensures the callback is notified once the change is
524         // committed.
525         flushHandler(2 /* count */);
526 
527         assertEquals(callback.getLastNotifiedStatus(token),
528                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
529 
530         // Committed state changes as there is a requested override.
531         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
532         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
533         assertEquals(mSysPropSetter.getValue(),
534                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
535         assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE);
536         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
537                 OTHER_DEVICE_STATE.getIdentifier());
538 
539         mProvider.setState(OTHER_DEVICE_STATE.getIdentifier());
540         flushHandler();
541 
542         // Request is canceled because the base state changed.
543         assertEquals(callback.getLastNotifiedStatus(token),
544                 TestDeviceStateManagerCallback.STATUS_CANCELED);
545         // Committed state is set back to the requested state once the override is cleared.
546         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
547         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
548         assertEquals(mSysPropSetter.getValue(),
549                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
550         assertFalse(mService.getOverrideState().isPresent());
551         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
552                 OTHER_DEVICE_STATE.getIdentifier());
553     }
554 
555     @Test
requestState_flagCancelWhenRequesterNotOnTop_onDeviceSleep()556     public void requestState_flagCancelWhenRequesterNotOnTop_onDeviceSleep()
557             throws RemoteException {
558         requestState_flagCancelWhenRequesterNotOnTop_common(
559                 // When the device is awake, the state should not change
560                 () -> mService.mOverrideRequestScreenObserver.onAwakeStateChanged(true),
561                 // When the device is in sleep mode, the state should be canceled
562                 () -> mService.mOverrideRequestScreenObserver.onAwakeStateChanged(false)
563         );
564     }
565 
566     @Test
requestState_flagCancelWhenRequesterNotOnTop_onKeyguardShow()567     public void requestState_flagCancelWhenRequesterNotOnTop_onKeyguardShow()
568             throws RemoteException {
569         requestState_flagCancelWhenRequesterNotOnTop_common(
570                 // When the keyguard is not showing, the state should not change
571                 () -> mService.mOverrideRequestScreenObserver.onKeyguardStateChanged(false),
572                 // When the keyguard is showing, the state should be canceled
573                 () -> mService.mOverrideRequestScreenObserver.onKeyguardStateChanged(true)
574         );
575     }
576 
577     @Test
requestState_flagCancelWhenRequesterNotOnTop_onTaskMovedToFront()578     public void requestState_flagCancelWhenRequesterNotOnTop_onTaskMovedToFront()
579             throws RemoteException {
580         requestState_flagCancelWhenRequesterNotOnTop_common(
581                 // When the app is foreground, the state should not change
582                 () -> {
583                     int pid = Binder.getCallingPid();
584                     int uid = Binder.getCallingUid();
585                     try {
586                         mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid,
587                                 true /* foregroundActivities */);
588                     } catch (RemoteException e) {
589                         throw new RuntimeException(e);
590                     }
591                 },
592                 // When the app is not foreground, the state should change
593                 () -> {
594                     when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);
595                     try {
596                         int pid = Binder.getCallingPid();
597                         int uid = Binder.getCallingUid();
598                         mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid,
599                                 false /* foregroundActivities */);
600 
601                     } catch (RemoteException e) {
602                         throw new RuntimeException(e);
603                     }
604                 }
605         );
606     }
607 
608     @FlakyTest(bugId = 200332057)
609     @Test
requestState_becomesUnsupported()610     public void requestState_becomesUnsupported() throws RemoteException {
611         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
612         mService.getBinderService().registerCallback(callback);
613         flushHandler();
614 
615         final IBinder token = new Binder();
616         assertEquals(callback.getLastNotifiedStatus(token),
617                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
618 
619         mService.getBinderService().requestState(token, OTHER_DEVICE_STATE.getIdentifier(),
620                 0 /* flags */);
621         flushHandler();
622 
623         assertEquals(callback.getLastNotifiedStatus(token),
624                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
625         // Committed state changes as there is a requested override.
626         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
627         assertEquals(mSysPropSetter.getValue(),
628                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
629         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
630         assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE);
631         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
632                 OTHER_DEVICE_STATE.getIdentifier());
633 
634         mProvider.notifySupportedDeviceStates(new DeviceState[]{ DEFAULT_DEVICE_STATE });
635         flushHandler();
636 
637         // Request is canceled because the state is no longer supported.
638         assertEquals(callback.getLastNotifiedStatus(token),
639                 TestDeviceStateManagerCallback.STATUS_CANCELED);
640         // Committed state is set back to the requested state as the override state is no longer
641         // supported.
642         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
643         assertEquals(mSysPropSetter.getValue(),
644                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
645         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
646         assertFalse(mService.getOverrideState().isPresent());
647         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
648                 DEFAULT_DEVICE_STATE.getIdentifier());
649     }
650 
651     @Test
requestState_unsupportedState()652     public void requestState_unsupportedState() throws RemoteException {
653         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
654         mService.getBinderService().registerCallback(callback);
655 
656         assertThrows(IllegalArgumentException.class, () -> {
657             final IBinder token = new Binder();
658             mService.getBinderService().requestState(token,
659                     UNSUPPORTED_DEVICE_STATE.getIdentifier(), 0 /* flags */);
660         });
661     }
662 
663     @Test
requestState_invalidState()664     public void requestState_invalidState() throws RemoteException {
665         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
666         mService.getBinderService().registerCallback(callback);
667 
668         assertThrows(IllegalArgumentException.class, () -> {
669             final IBinder token = new Binder();
670             mService.getBinderService().requestState(token, INVALID_DEVICE_STATE, 0 /* flags */);
671         });
672     }
673 
674     @Test
requestState_beforeRegisteringCallback()675     public void requestState_beforeRegisteringCallback() {
676         assertThrows(IllegalStateException.class, () -> {
677             final IBinder token = new Binder();
678             mService.getBinderService().requestState(token, DEFAULT_DEVICE_STATE.getIdentifier(),
679                     0 /* flags */);
680         });
681     }
682 
683     @Test
requestBaseStateOverride()684     public void requestBaseStateOverride() throws RemoteException {
685         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
686         mService.getBinderService().registerCallback(callback);
687         flushHandler();
688 
689         final IBinder token = new Binder();
690         assertEquals(callback.getLastNotifiedStatus(token),
691                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
692 
693         mService.getBinderService().requestBaseStateOverride(token,
694                 OTHER_DEVICE_STATE.getIdentifier(),
695                 0 /* flags */);
696         // Flush the handler twice. The first flush ensures the request is added and the policy is
697         // notified, while the second flush ensures the callback is notified once the change is
698         // committed.
699         flushHandler(2 /* count */);
700 
701         assertEquals(callback.getLastNotifiedStatus(token),
702                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
703         // Committed state changes as there is a requested override.
704         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
705         assertEquals(mSysPropSetter.getValue(),
706                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
707         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
708         assertEquals(mService.getOverrideBaseState().get(), OTHER_DEVICE_STATE);
709         assertFalse(mService.getOverrideState().isPresent());
710         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
711                 OTHER_DEVICE_STATE.getIdentifier());
712 
713         assertNotNull(callback.getLastNotifiedInfo());
714         assertEquals(callback.getLastNotifiedInfo().baseState,
715                 OTHER_DEVICE_STATE.getIdentifier());
716         assertEquals(callback.getLastNotifiedInfo().currentState,
717                 OTHER_DEVICE_STATE.getIdentifier());
718 
719         mService.getBinderService().cancelBaseStateOverride();
720         flushHandler();
721 
722         assertEquals(callback.getLastNotifiedStatus(token),
723                 TestDeviceStateManagerCallback.STATUS_CANCELED);
724         // Committed state is set back to the requested state once the override is cleared.
725         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
726         assertEquals(mSysPropSetter.getValue(),
727                 DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
728         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
729         assertFalse(mService.getOverrideBaseState().isPresent());
730         assertFalse(mService.getOverrideState().isPresent());
731         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
732                 DEFAULT_DEVICE_STATE.getIdentifier());
733 
734         assertEquals(callback.getLastNotifiedInfo().baseState,
735                 DEFAULT_DEVICE_STATE.getIdentifier());
736         assertEquals(callback.getLastNotifiedInfo().currentState,
737                 DEFAULT_DEVICE_STATE.getIdentifier());
738     }
739 
740     @Test
requestBaseStateOverride_cancelledByBaseStateUpdate()741     public void requestBaseStateOverride_cancelledByBaseStateUpdate() throws RemoteException {
742         final DeviceState testDeviceState = new DeviceState(2, "TEST", 0);
743         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
744         mService.getBinderService().registerCallback(callback);
745         mProvider.notifySupportedDeviceStates(
746                 new DeviceState[]{DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, testDeviceState });
747         flushHandler();
748 
749         final IBinder token = new Binder();
750         assertEquals(callback.getLastNotifiedStatus(token),
751                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
752 
753         mService.getBinderService().requestBaseStateOverride(token,
754                 OTHER_DEVICE_STATE.getIdentifier(),
755                 0 /* flags */);
756         // Flush the handler twice. The first flush ensures the request is added and the policy is
757         // notified, while the second flush ensures the callback is notified once the change is
758         // committed.
759         flushHandler(2 /* count */);
760 
761         assertEquals(callback.getLastNotifiedStatus(token),
762                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
763         // Committed state changes as there is a requested override.
764         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
765         assertEquals(mSysPropSetter.getValue(),
766                 OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
767         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
768         assertEquals(mService.getOverrideBaseState().get(), OTHER_DEVICE_STATE);
769         assertFalse(mService.getOverrideState().isPresent());
770         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
771                 OTHER_DEVICE_STATE.getIdentifier());
772 
773         assertNotNull(callback.getLastNotifiedInfo());
774         assertEquals(callback.getLastNotifiedInfo().baseState,
775                 OTHER_DEVICE_STATE.getIdentifier());
776         assertEquals(callback.getLastNotifiedInfo().currentState,
777                 OTHER_DEVICE_STATE.getIdentifier());
778 
779         mProvider.setState(testDeviceState.getIdentifier());
780         flushHandler();
781 
782         assertEquals(callback.getLastNotifiedStatus(token),
783                 TestDeviceStateManagerCallback.STATUS_CANCELED);
784         // Committed state is set to the new base state once the override is cleared.
785         assertEquals(mService.getCommittedState(), Optional.of(testDeviceState));
786         assertEquals(mSysPropSetter.getValue(),
787                 testDeviceState.getIdentifier() + ":" + testDeviceState.getName());
788         assertEquals(mService.getBaseState(), Optional.of(testDeviceState));
789         assertFalse(mService.getOverrideBaseState().isPresent());
790         assertFalse(mService.getOverrideState().isPresent());
791         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
792                 testDeviceState.getIdentifier());
793 
794         assertEquals(callback.getLastNotifiedInfo().baseState,
795                 testDeviceState.getIdentifier());
796         assertEquals(callback.getLastNotifiedInfo().currentState,
797                 testDeviceState.getIdentifier());
798     }
799 
800     @Test
requestBaseState_unsupportedState()801     public void requestBaseState_unsupportedState() throws RemoteException {
802         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
803         mService.getBinderService().registerCallback(callback);
804 
805         assertThrows(IllegalArgumentException.class, () -> {
806             final IBinder token = new Binder();
807             mService.getBinderService().requestBaseStateOverride(token,
808                     UNSUPPORTED_DEVICE_STATE.getIdentifier(), 0 /* flags */);
809         });
810     }
811 
812     @Test
requestBaseState_invalidState()813     public void requestBaseState_invalidState() throws RemoteException {
814         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
815         mService.getBinderService().registerCallback(callback);
816 
817         assertThrows(IllegalArgumentException.class, () -> {
818             final IBinder token = new Binder();
819             mService.getBinderService().requestBaseStateOverride(token, INVALID_DEVICE_STATE,
820                     0 /* flags */);
821         });
822     }
823 
824     @Test
requestBaseState_beforeRegisteringCallback()825     public void requestBaseState_beforeRegisteringCallback() {
826         assertThrows(IllegalStateException.class, () -> {
827             final IBinder token = new Binder();
828             mService.getBinderService().requestBaseStateOverride(token,
829                     DEFAULT_DEVICE_STATE.getIdentifier(),
830                     0 /* flags */);
831         });
832     }
833 
assertArrayEquals(int[] expected, int[] actual)834     private static void assertArrayEquals(int[] expected, int[] actual) {
835         Assert.assertTrue(Arrays.equals(expected, actual));
836     }
837 
838     /**
839      * Common code to verify the handling of FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag.
840      *
841      * The device state with FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP should be automatically canceled
842      * when certain events happen, e.g. when the top activity belongs to another app or when the
843      * device goes into the sleep mode.
844      *
845      * @param noChangeEvent an event that should not trigger auto cancellation of the state.
846      * @param autoCancelEvent an event that should trigger auto cancellation of the state.
847      * @throws RemoteException when the service throws exceptions.
848      */
requestState_flagCancelWhenRequesterNotOnTop_common( Runnable noChangeEvent, Runnable autoCancelEvent )849     private void requestState_flagCancelWhenRequesterNotOnTop_common(
850             Runnable noChangeEvent,
851             Runnable autoCancelEvent
852     ) throws RemoteException {
853         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
854         mService.getBinderService().registerCallback(callback);
855         flushHandler();
856 
857         final IBinder token = new Binder();
858         assertEquals(callback.getLastNotifiedStatus(token),
859                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
860 
861         mService.getBinderService().requestState(token,
862                 DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP.getIdentifier(),
863                 0 /* flags */);
864         flushHandler(2 /* count */);
865 
866         assertEquals(callback.getLastNotifiedStatus(token),
867                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
868 
869         // Committed state changes as there is a requested override.
870         assertDeviceStateConditions(
871                 DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP,
872                 DEFAULT_DEVICE_STATE, /* base state */
873                 true /* isOverrideState */);
874 
875         noChangeEvent.run();
876         flushHandler();
877         assertEquals(callback.getLastNotifiedStatus(token),
878                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
879         assertDeviceStateConditions(
880                 DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP,
881                 DEFAULT_DEVICE_STATE, /* base state */
882                 true /* isOverrideState */);
883 
884         autoCancelEvent.run();
885         flushHandler();
886         assertEquals(callback.getLastNotifiedStatus(token),
887                 TestDeviceStateManagerCallback.STATUS_CANCELED);
888         assertDeviceStateConditions(DEFAULT_DEVICE_STATE, DEFAULT_DEVICE_STATE,
889                 false /* isOverrideState */);
890     }
891 
892     /**
893      * Verify that the current device state and base state match the expected values.
894      *
895      * @param state the expected committed state.
896      * @param baseState the expected base state.
897      * @param isOverrideState whether a state override is active.
898      */
assertDeviceStateConditions( DeviceState state, DeviceState baseState, boolean isOverrideState)899     private void assertDeviceStateConditions(
900             DeviceState state, DeviceState baseState, boolean isOverrideState) {
901         assertEquals(mService.getCommittedState(), Optional.of(state));
902         assertEquals(mService.getBaseState(), Optional.of(baseState));
903         assertEquals(mSysPropSetter.getValue(),
904                 state.getIdentifier() + ":" + state.getName());
905         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
906                 state.getIdentifier());
907         if (isOverrideState) {
908             // When a state override is active, the committed state should batch the override state.
909             assertEquals(mService.getOverrideState().get(), state);
910         } else {
911             // When there is no state override, the override state should be empty.
912             assertFalse(mService.getOverrideState().isPresent());
913         }
914     }
915 
916     private static final class TestDeviceStatePolicy extends DeviceStatePolicy {
917         private final DeviceStateProvider mProvider;
918         private int mLastDeviceStateRequestedToConfigure = INVALID_DEVICE_STATE;
919         private boolean mConfigureBlocked = false;
920         private Runnable mPendingConfigureCompleteRunnable;
921 
TestDeviceStatePolicy(DeviceStateProvider provider)922         TestDeviceStatePolicy(DeviceStateProvider provider) {
923             super(InstrumentationRegistry.getContext());
924             mProvider = provider;
925         }
926 
927         @Override
getDeviceStateProvider()928         public DeviceStateProvider getDeviceStateProvider() {
929             return mProvider;
930         }
931 
blockConfigure()932         public void blockConfigure() {
933             mConfigureBlocked = true;
934         }
935 
resumeConfigure()936         public void resumeConfigure() {
937             mConfigureBlocked = false;
938             if (mPendingConfigureCompleteRunnable != null) {
939                 Runnable onComplete = mPendingConfigureCompleteRunnable;
940                 mPendingConfigureCompleteRunnable = null;
941                 onComplete.run();
942             }
943         }
944 
resumeConfigureOnce()945         public void resumeConfigureOnce() {
946             if (mPendingConfigureCompleteRunnable != null) {
947                 Runnable onComplete = mPendingConfigureCompleteRunnable;
948                 mPendingConfigureCompleteRunnable = null;
949                 onComplete.run();
950             }
951         }
952 
getMostRecentRequestedStateToConfigure()953         public int getMostRecentRequestedStateToConfigure() {
954             return mLastDeviceStateRequestedToConfigure;
955         }
956 
957         @Override
configureDeviceForState(int state, Runnable onComplete)958         public void configureDeviceForState(int state, Runnable onComplete) {
959             if (mPendingConfigureCompleteRunnable != null) {
960                 throw new IllegalStateException("configureDeviceForState() called while configure"
961                         + " is pending");
962             }
963 
964             mLastDeviceStateRequestedToConfigure = state;
965             if (mConfigureBlocked) {
966                 mPendingConfigureCompleteRunnable = onComplete;
967                 return;
968             }
969             onComplete.run();
970         }
971     }
972 
973     private static final class TestDeviceStateProvider implements DeviceStateProvider {
974         private DeviceState[] mSupportedDeviceStates = new DeviceState[]{
975                 DEFAULT_DEVICE_STATE,
976                 OTHER_DEVICE_STATE,
977                 DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP};
978 
979         @Nullable private final DeviceState mInitialState;
980         private Listener mListener;
981 
TestDeviceStateProvider()982         private TestDeviceStateProvider() {
983             this(DEFAULT_DEVICE_STATE);
984         }
985 
TestDeviceStateProvider(@ullable DeviceState initialState)986         private TestDeviceStateProvider(@Nullable DeviceState initialState) {
987             mInitialState = initialState;
988         }
989 
990         @Override
setListener(Listener listener)991         public void setListener(Listener listener) {
992             if (mListener != null) {
993                 throw new IllegalArgumentException("Provider already has listener set.");
994             }
995 
996             mListener = listener;
997             mListener.onSupportedDeviceStatesChanged(mSupportedDeviceStates,
998                     SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED);
999             if (mInitialState != null) {
1000                 mListener.onStateChanged(mInitialState.getIdentifier());
1001             }
1002         }
1003 
notifySupportedDeviceStates(DeviceState[] supportedDeviceStates)1004         public void notifySupportedDeviceStates(DeviceState[] supportedDeviceStates) {
1005             mSupportedDeviceStates = supportedDeviceStates;
1006             mListener.onSupportedDeviceStatesChanged(supportedDeviceStates,
1007                     SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED);
1008         }
1009 
setState(int identifier)1010         public void setState(int identifier) {
1011             mListener.onStateChanged(identifier);
1012         }
1013     }
1014 
1015     private static final class TestDeviceStateManagerCallback extends
1016             IDeviceStateManagerCallback.Stub {
1017         public static final int STATUS_UNKNOWN = 0;
1018         public static final int STATUS_ACTIVE = 1;
1019         public static final int STATUS_SUSPENDED = 2;
1020         public static final int STATUS_CANCELED = 3;
1021 
1022         @Nullable
1023         private DeviceStateInfo mLastNotifiedInfo;
1024         private final HashMap<IBinder, Integer> mLastNotifiedStatus = new HashMap<>();
1025 
1026         @Override
onDeviceStateInfoChanged(DeviceStateInfo info)1027         public void onDeviceStateInfoChanged(DeviceStateInfo info) {
1028             mLastNotifiedInfo = info;
1029         }
1030 
1031         @Override
onRequestActive(IBinder token)1032         public void onRequestActive(IBinder token) {
1033             mLastNotifiedStatus.put(token, STATUS_ACTIVE);
1034         }
1035 
1036         @Override
onRequestCanceled(IBinder token)1037         public void onRequestCanceled(IBinder token) {
1038             mLastNotifiedStatus.put(token, STATUS_CANCELED);
1039         }
1040 
1041         @Nullable
getLastNotifiedInfo()1042         DeviceStateInfo getLastNotifiedInfo() {
1043             return mLastNotifiedInfo;
1044         }
1045 
clearLastNotifiedInfo()1046         void clearLastNotifiedInfo() {
1047             mLastNotifiedInfo = null;
1048         }
1049 
getLastNotifiedStatus(IBinder requestToken)1050         int getLastNotifiedStatus(IBinder requestToken) {
1051             return mLastNotifiedStatus.getOrDefault(requestToken, STATUS_UNKNOWN);
1052         }
1053     }
1054 
1055     private static final class TestSystemPropertySetter implements
1056             DeviceStateManagerService.SystemPropertySetter {
1057         private String mValue;
1058 
1059         @Override
setDebugTracingDeviceStateProperty(String value)1060         public void setDebugTracingDeviceStateProperty(String value) {
1061             mValue = value;
1062         }
1063 
getValue()1064         public String getValue() {
1065             return mValue;
1066         }
1067     }
1068 }
1069