• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 android.hardware.devicestate.cts;
18 
19 import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
20 import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
21 import static android.server.wm.DeviceStateUtils.assertValidState;
22 import static android.server.wm.DeviceStateUtils.runWithControlDeviceStatePermission;
23 import static android.view.Display.DEFAULT_DISPLAY;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assume.assumeFalse;
29 import static org.junit.Assume.assumeTrue;
30 import static org.mockito.Mockito.atLeastOnce;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.timeout;
33 import static org.mockito.Mockito.verify;
34 
35 import android.content.Context;
36 import android.content.res.Resources;
37 import android.hardware.devicestate.DeviceStateManager;
38 import android.hardware.devicestate.DeviceStateRequest;
39 import android.server.wm.jetpack.utils.ExtensionUtil;
40 import android.server.wm.jetpack.utils.Version;
41 
42 import androidx.test.ext.junit.runners.AndroidJUnit4;
43 import androidx.test.platform.app.InstrumentationRegistry;
44 
45 import com.android.compatibility.common.util.ApiTest;
46 import com.android.compatibility.common.util.PollingCheck;
47 
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.ArgumentCaptor;
51 
52 import java.util.HashSet;
53 import java.util.Set;
54 import java.util.concurrent.Executor;
55 
56 /** CTS tests for {@link DeviceStateManager} API(s). */
57 @RunWith(AndroidJUnit4.class)
58 public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
59 
60     public static final int TIMEOUT = 2000;
61 
62     private static final int INVALID_DEVICE_STATE = -1;
63 
64     /** Vendor extension version. Some API behaviors are only available in newer version. */
65     private static final Version WM_EXTENSION_VERSION = ExtensionUtil.getExtensionVersion();
66 
67     /**
68      * Tests that {@link DeviceStateManager#getSupportedStates()} returns at least one state and
69      * that none of the returned states are in the range
70      * [{@link #MINIMUM_DEVICE_STATE}, {@link #MAXIMUM_DEVICE_STATE}].
71      */
72     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#getSupportedStates"})
73     @Test
testValidSupportedStates()74     public void testValidSupportedStates() throws Exception {
75         final int[] supportedStates = getDeviceStateManager().getSupportedStates();
76         assertTrue(supportedStates.length > 0);
77 
78         for (int i = 0; i < supportedStates.length; i++) {
79             final int state = supportedStates[i];
80             assertValidState(state);
81         }
82     }
83 
84     /**
85      * Tests that calling {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
86      * DeviceStateRequest.Callback)} is successful and results in a registered callback being
87      * triggered with a value equal to the requested state.
88      */
89     @ApiTest(apis = {
90             "android.hardware.devicestate.DeviceStateManager#getSupportedStates",
91             "android.hardware.devicestate.DeviceStateManager#requestState"})
92     @Test
testRequestAllSupportedStates()93     public void testRequestAllSupportedStates() throws Throwable {
94         final ArgumentCaptor<Integer> intAgumentCaptor = ArgumentCaptor.forClass(Integer.class);
95         final DeviceStateManager.DeviceStateCallback callback
96                 = mock(DeviceStateManager.DeviceStateCallback.class);
97         final DeviceStateManager manager = getDeviceStateManager();
98         manager.registerCallback(Runnable::run, callback);
99 
100         final int[] supportedStates = manager.getSupportedStates();
101         for (int i = 0; i < supportedStates.length; i++) {
102             final DeviceStateRequest request
103                     = DeviceStateRequest.newBuilder(supportedStates[i]).build();
104 
105             runWithRequestActive(request, false, () -> {
106                 verify(callback, atLeastOnce()).onStateChanged(intAgumentCaptor.capture());
107                 assertEquals(intAgumentCaptor.getValue().intValue(), request.getState());
108             });
109         }
110     }
111 
112     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestBaseStateOverride"})
113     @Test
testRequestBaseState()114     public void testRequestBaseState() throws Throwable {
115         final ArgumentCaptor<Integer> intAgumentCaptor = ArgumentCaptor.forClass(Integer.class);
116         final DeviceStateManager.DeviceStateCallback callback =
117                 mock(DeviceStateManager.DeviceStateCallback.class);
118         final DeviceStateManager manager = getDeviceStateManager();
119 
120         manager.registerCallback(Runnable::run, callback);
121 
122         DeviceStateRequest request = DeviceStateRequest.newBuilder(0).build();
123         runWithRequestActive(request, true, () -> {
124             verify(callback, atLeastOnce()).onStateChanged(intAgumentCaptor.capture());
125             assertEquals(intAgumentCaptor.getValue().intValue(), request.getState());
126         });
127     }
128 
129     /**
130      * Tests that calling {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
131      * DeviceStateRequest.Callback)} throws an {@link java.lang.IllegalArgumentException} if
132      * supplied with a state above {@link MAXIMUM_DEVICE_STATE}.
133      */
134     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestState"})
135     @Test(expected = IllegalArgumentException.class)
testRequestStateTooLarge()136     public void testRequestStateTooLarge() throws Throwable {
137         final DeviceStateManager manager = getDeviceStateManager();
138         final DeviceStateRequest request
139                 = DeviceStateRequest.newBuilder(MAXIMUM_DEVICE_STATE + 1).build();
140         runWithControlDeviceStatePermission(() -> manager.requestState(request, null, null));
141     }
142 
143     /**
144      * Tests that calling {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
145      * DeviceStateRequest.Callback)} throws an {@link java.lang.IllegalArgumentException} if
146      * supplied with a state below {@link MINIMUM_DEVICE_STATE}.
147      */
148     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestState"})
149     @Test(expected = IllegalArgumentException.class)
testRequestStateTooSmall()150     public void testRequestStateTooSmall() throws Throwable {
151         final DeviceStateManager manager = getDeviceStateManager();
152         final DeviceStateRequest request
153                 = DeviceStateRequest.newBuilder(MINIMUM_DEVICE_STATE - 1).build();
154         runWithControlDeviceStatePermission(() -> manager.requestState(request, null, null));
155     }
156 
157     /**
158      * Tests that calling {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
159      * DeviceStateRequest.Callback)} is not successful and results in a failure to change the
160      * state of the device due to the state requested not being available for apps to request.
161      */
162     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestState"})
163     @Test
testRequestStateFailsAsTopApp_ifStateNotDefinedAsAvailableForAppsToRequest()164     public void testRequestStateFailsAsTopApp_ifStateNotDefinedAsAvailableForAppsToRequest()
165             throws IllegalArgumentException {
166         final DeviceStateManager manager = getDeviceStateManager();
167         final int[] supportedStates = manager.getSupportedStates();
168         // We want to verify that the app can change device state
169         // So we only attempt if there are more than 1 possible state.
170         assumeTrue(supportedStates.length > 1);
171         Set<Integer> statesAvailableToRequest = getAvailableStatesToRequest(
172                 InstrumentationRegistry.getInstrumentation().getTargetContext(), supportedStates);
173         // checks that not every state is available for an app to request
174         assumeTrue(statesAvailableToRequest.size() < supportedStates.length);
175 
176         Set<Integer> availableDeviceStates = generateDeviceStateSet(supportedStates);
177 
178         final StateTrackingCallback callback = new StateTrackingCallback();
179         manager.registerCallback(Runnable::run, callback);
180         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState != INVALID_DEVICE_STATE);
181         final TestActivitySession<DeviceStateTestActivity> activitySession =
182                 createManagedTestActivitySession();
183 
184         activitySession.launchTestActivityOnDisplaySync(
185                 DeviceStateTestActivity.class,
186                 DEFAULT_DISPLAY
187         );
188 
189         DeviceStateTestActivity activity = activitySession.getActivity();
190 
191         Set<Integer> possibleStates = possibleStates(false /* shouldSucceed */,
192                 availableDeviceStates,
193                 statesAvailableToRequest);
194         int nextState = calculateDifferentState(callback.mCurrentState, possibleStates);
195         // checks that we were able to find a valid state to request.
196         assumeTrue(nextState != INVALID_DEVICE_STATE);
197 
198         activity.requestDeviceStateChange(nextState);
199 
200         assertTrue(activity.requestStateFailed);
201     }
202 
203     /**
204      * Tests that calling {@link DeviceStateManager#requestState(DeviceStateRequest, Executor,
205      * DeviceStateRequest.Callback)} is successful and results in a registered callback being
206      * triggered with a value equal to the requested state.
207      */
208     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestState"})
209     @Test
testRequestStateSucceedsAsTopApp_ifStateDefinedAsAvailableForAppsToRequest()210     public void testRequestStateSucceedsAsTopApp_ifStateDefinedAsAvailableForAppsToRequest()
211             throws Throwable {
212         final DeviceStateManager manager = getDeviceStateManager();
213         final int[] supportedStates = manager.getSupportedStates();
214 
215         // We want to verify that the app can change device state
216         // So we only attempt if there are more than 1 possible state.
217         assumeTrue(supportedStates.length > 1);
218         Set<Integer> statesAvailableToRequest = getAvailableStatesToRequest(
219                 InstrumentationRegistry.getInstrumentation().getTargetContext(), supportedStates);
220         assumeTrue(statesAvailableToRequest.size() > 0);
221 
222         Set<Integer> availableDeviceStates = generateDeviceStateSet(supportedStates);
223 
224         final StateTrackingCallback callback = new StateTrackingCallback();
225         manager.registerCallback(Runnable::run, callback);
226         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState != INVALID_DEVICE_STATE);
227         final TestActivitySession<DeviceStateTestActivity> activitySession =
228                 createManagedTestActivitySession();
229 
230         activitySession.launchTestActivityOnDisplaySync(
231                 DeviceStateTestActivity.class,
232                 DEFAULT_DISPLAY
233         );
234 
235         DeviceStateTestActivity activity = activitySession.getActivity();
236 
237         Set<Integer> possibleStates = possibleStates(true /* shouldSucceed */,
238                 availableDeviceStates,
239                 statesAvailableToRequest);
240         int nextState = calculateDifferentState(callback.mCurrentState, possibleStates);
241         // checks that we were able to find a valid state to request.
242         assumeTrue(nextState != INVALID_DEVICE_STATE);
243 
244         runWithControlDeviceStatePermission(() -> activity.requestDeviceStateChange(nextState));
245 
246         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState == nextState);
247 
248         assertEquals(nextState, callback.mCurrentState);
249         assertFalse(activity.requestStateFailed);
250 
251         manager.cancelStateRequest(); // reset device state after successful request
252     }
253 
254     /**
255      * Tests that calling {@link DeviceStateManager#requestState} is unsuccessful and results in a
256      * failure to update the state of the device as expected since the activity is backgrounded.
257      */
258     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestState"})
259     @Test
testRequestStateFailsAsBackgroundApp()260     public void testRequestStateFailsAsBackgroundApp() throws IllegalArgumentException {
261         final DeviceStateManager manager = getDeviceStateManager();
262         final int[] supportedStates = manager.getSupportedStates();
263         // We want to verify that the app can change device state
264         // So we only attempt if there are more than 1 possible state.
265         assumeTrue(supportedStates.length > 1);
266         Set<Integer> statesAvailableToRequest = getAvailableStatesToRequest(
267                 InstrumentationRegistry.getInstrumentation().getTargetContext(), supportedStates);
268         assumeTrue(statesAvailableToRequest.size() > 0);
269 
270         Set<Integer> availableDeviceStates = generateDeviceStateSet(supportedStates);
271 
272         final StateTrackingCallback callback = new StateTrackingCallback();
273         manager.registerCallback(Runnable::run, callback);
274         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState != INVALID_DEVICE_STATE);
275 
276         final TestActivitySession<DeviceStateTestActivity> activitySession =
277                 createManagedTestActivitySession();
278         activitySession.launchTestActivityOnDisplaySync(
279                 DeviceStateTestActivity.class,
280                 DEFAULT_DISPLAY
281         );
282 
283         DeviceStateTestActivity activity = activitySession.getActivity();
284         assertFalse(activity.requestStateFailed);
285 
286         launchHomeActivity(); // places our test activity in the background
287 
288         Set<Integer> possibleStates = possibleStates(true /* shouldSucceed */,
289                 availableDeviceStates,
290                 statesAvailableToRequest);
291         int nextState = calculateDifferentState(callback.mCurrentState, possibleStates);
292         // checks that we were able to find a valid state to request.
293         assumeTrue(nextState != INVALID_DEVICE_STATE);
294 
295         activity.requestDeviceStateChange(nextState);
296 
297         assertTrue(activity.requestStateFailed);
298     }
299 
300     /**
301      * Tests that calling {@link DeviceStateManager#cancelStateRequest} is successful and results
302      * in a registered callback being triggered with a value equal to the base state.
303      */
304     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#cancelStateRequest"})
305     @Test
testCancelStateRequestFromNewActivity()306     public void testCancelStateRequestFromNewActivity() throws Throwable {
307         final DeviceStateManager manager = getDeviceStateManager();
308         final int[] supportedStates = manager.getSupportedStates();
309         // We want to verify that the app can change device state
310         // So we only attempt if there are more than 1 possible state.
311         assumeTrue(supportedStates.length > 1);
312         Set<Integer> statesAvailableToRequest = getAvailableStatesToRequest(
313                 InstrumentationRegistry.getInstrumentation().getTargetContext(), supportedStates);
314         assumeFalse(statesAvailableToRequest.isEmpty());
315 
316         Set<Integer> availableDeviceStates = generateDeviceStateSet(supportedStates);
317 
318         final StateTrackingCallback callback = new StateTrackingCallback();
319         manager.registerCallback(Runnable::run, callback);
320         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState != INVALID_DEVICE_STATE);
321         final TestActivitySession<DeviceStateTestActivity> activitySession =
322                 createManagedTestActivitySession();
323 
324         activitySession.launchTestActivityOnDisplaySync(
325                 DeviceStateTestActivity.class,
326                 DEFAULT_DISPLAY
327         );
328 
329         final DeviceStateTestActivity activity = activitySession.getActivity();
330 
331         int originalState = callback.mCurrentState;
332 
333         Set<Integer> possibleStates = possibleStates(true /* shouldSucceed */,
334                 availableDeviceStates,
335                 statesAvailableToRequest);
336         int nextState = calculateDifferentState(callback.mCurrentState, possibleStates);
337         // checks that we were able to find a valid state to request.
338         assumeTrue(nextState != INVALID_DEVICE_STATE);
339 
340         runWithControlDeviceStatePermission(() -> activity.requestDeviceStateChange(nextState));
341 
342         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState == nextState);
343 
344         assertEquals(nextState, callback.mCurrentState);
345         assertFalse(activity.requestStateFailed);
346 
347         activity.finish();
348 
349         final TestActivitySession<DeviceStateTestActivity> secondActivitySession =
350                 createManagedTestActivitySession();
351         secondActivitySession.launchTestActivityOnDisplaySync(
352                 DeviceStateTestActivity.class,
353                 DEFAULT_DISPLAY
354         );
355         // Assumes that the overridden state is still active after finishing
356         // and launching the second activity. This due to some states may be cancelled
357         // if they have the FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag on them.
358         // TODO(b/305107721): Update this call when we can verify we're moving to a state
359         // that does not have the FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag.
360         assumeTrue(nextState == callback.mCurrentState);
361 
362         final DeviceStateTestActivity activity2 = secondActivitySession.getActivity();
363         activity2.cancelOverriddenState();
364 
365         PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState == originalState);
366 
367         assertEquals(originalState, callback.mCurrentState);
368     }
369 
370 
371     /**
372      * Reads in the states that are available to be requested by apps from the configuration file
373      * and returns a set of all valid states that are read in.
374      *
375      * @param context The context used to get the configuration values from {@link Resources}
376      * @param supportedStates The device states that are supported on that device.
377      * @return {@link Set} of valid device states that are read in.
378      */
getAvailableStatesToRequest(Context context, int[] supportedStates)379     private static Set<Integer> getAvailableStatesToRequest(Context context,
380             int[] supportedStates) {
381         Set<Integer> availableStatesToRequest = new HashSet<>();
382         String[] availableStateIdentifiers = context.getResources().getStringArray(
383                 Resources.getSystem().getIdentifier("config_deviceStatesAvailableForAppRequests",
384                         "array",
385                         "android"));
386         for (String identifier : availableStateIdentifiers) {
387             int stateIdentifier = context.getResources()
388                     .getIdentifier(identifier, "integer", "android");
389             int state = context.getResources().getInteger(stateIdentifier);
390             if (isValidState(state, supportedStates)) {
391                 availableStatesToRequest.add(context.getResources().getInteger(stateIdentifier));
392             }
393         }
394         return availableStatesToRequest;
395     }
396 
isValidState(int state, int[] supportedStates)397     private static boolean isValidState(int state, int[] supportedStates) {
398         for (int i = 0; i < supportedStates.length; i++) {
399             if (state == supportedStates[i]) {
400                 return true;
401             }
402         }
403         return false;
404     }
405 
406     /**
407      * Generates a set of possible device states based on a {@link Set} of valid device states,
408      * {@code supportedDeviceStates}, and the set of device states available to be requested
409      * {@code availableStatesToRequest}, as well as if the request should succeed or not, given by
410      * {@code shouldSucceed}.
411      *
412      * If {@code shouldSucceed} is {@code true}, we only return device states that are available,
413      * and if it is {@code false}, we only return non available device states.
414      *
415      * @param availableStatesToRequest The states that are available to be requested from an app
416      * @param shouldSucceed Should the request succeed or not, to determine what states we return
417      * @param supportedDeviceStates All states supported on the device.
418      * {@throws} an {@link IllegalArgumentException} if {@code availableStatesToRequest} includes
419      * non-valid device states.
420      */
possibleStates(boolean shouldSucceed, Set<Integer> supportedDeviceStates, Set<Integer> availableStatesToRequest)421     private static Set<Integer> possibleStates(boolean shouldSucceed,
422             Set<Integer> supportedDeviceStates,
423             Set<Integer> availableStatesToRequest) {
424 
425         if (!supportedDeviceStates.containsAll(availableStatesToRequest)) {
426             throw new IllegalArgumentException("Available states include invalid device states");
427         }
428 
429         Set<Integer> availableStates = new HashSet<>(supportedDeviceStates);
430 
431         if (shouldSucceed) {
432             availableStates.retainAll(availableStatesToRequest);
433         } else {
434             availableStates.removeAll(availableStatesToRequest);
435         }
436 
437         return availableStates;
438     }
439 
440     /**
441      * Determines what state we should request that isn't the current state, and is included
442      * in {@code possibleStates}. If there is no state that fits these requirements, we return
443      * {@link INVALID_DEVICE_STATE}.
444      *
445      * @param currentState The current state of the device
446      * @param possibleStates States that we can request
447      */
calculateDifferentState(int currentState, Set<Integer> possibleStates)448     private static int calculateDifferentState(int currentState, Set<Integer> possibleStates) {
449         if (possibleStates.isEmpty()) {
450             return INVALID_DEVICE_STATE;
451         }
452         if (possibleStates.size() == 1 && possibleStates.contains(currentState)) {
453             return INVALID_DEVICE_STATE;
454         }
455         for (int state: possibleStates) {
456             if (state != currentState) {
457                 return state;
458             }
459         }
460         return INVALID_DEVICE_STATE;
461     }
462 
463     /**
464      * Creates a {@link Set} of values that are in the {@code states} array.
465      *
466      * Used to create a {@link Set} from the available device states that {@link DeviceStateManager}
467      * returns as an array.
468      *
469      * @param states Device states that are supported on the device
470      */
generateDeviceStateSet(int[] states)471     private static Set<Integer> generateDeviceStateSet(int[] states) {
472         Set<Integer> supportedStates = new HashSet<>();
473         for (int i = 0; i < states.length; i++) {
474             supportedStates.add(states[i]);
475         }
476         return supportedStates;
477     }
478 
479     /**
480      * Tests that calling {@link DeviceStateManager#requestState()} throws a
481      * {@link java.lang.SecurityException} without the
482      * {@link android.Manifest.permission.CONTROL_DEVICE_STATE} permission held.
483      */
484     @Test(expected = SecurityException.class)
485     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#requestState"})
testRequestStateWithoutPermission()486     public void testRequestStateWithoutPermission() {
487         final DeviceStateManager manager = getDeviceStateManager();
488         final int[] states = manager.getSupportedStates();
489         final DeviceStateRequest request = DeviceStateRequest.newBuilder(states[0]).build();
490         manager.requestState(request, null, null);
491     }
492 
493     /**
494      * Tests that calling {@link DeviceStateManager#cancelStateRequest} throws a
495      * {@link java.lang.SecurityException} without the
496      * {@link android.Manifest.permission.CONTROL_DEVICE_STATE} permission held.
497      */
498     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#cancelStateRequest"})
499     @Test(expected = SecurityException.class)
testCancelOverrideRequestWithoutPermission()500     public void testCancelOverrideRequestWithoutPermission() throws Throwable {
501         final DeviceStateManager manager = getDeviceStateManager();
502         final int[] states = manager.getSupportedStates();
503         final DeviceStateRequest request = DeviceStateRequest.newBuilder(states[0]).build();
504         runWithRequestActive(request, false, manager::cancelStateRequest);
505     }
506 
507     /**
508      * Tests that callbacks added with {@link DeviceStateManager#registerDeviceStateCallback()} are
509      * supplied with an initial callback that contains the state at the time of registration.
510      */
511     @ApiTest(apis = {"android.hardware.devicestate.DeviceStateManager#registerCallback"})
512     @Test
testRegisterCallbackSuppliesInitialValue()513     public void testRegisterCallbackSuppliesInitialValue() throws InterruptedException {
514         final ArgumentCaptor<int[]> intArrayAgumentCaptor = ArgumentCaptor.forClass(int[].class);
515         final ArgumentCaptor<Integer> intAgumentCaptor = ArgumentCaptor.forClass(Integer.class);
516 
517         final DeviceStateManager.DeviceStateCallback callback
518                 = mock(DeviceStateManager.DeviceStateCallback.class);
519         final DeviceStateManager manager = getDeviceStateManager();
520         manager.registerCallback(Runnable::run, callback);
521 
522         verify(callback, timeout(CALLBACK_TIMEOUT_MS)).onStateChanged(intAgumentCaptor.capture());
523         assertValidState(intAgumentCaptor.getValue().intValue());
524 
525         verify(callback, timeout(CALLBACK_TIMEOUT_MS))
526                 .onBaseStateChanged(intAgumentCaptor.capture());
527         assertValidState(intAgumentCaptor.getValue().intValue());
528 
529         verify(callback, timeout(CALLBACK_TIMEOUT_MS))
530                 .onSupportedStatesChanged(intArrayAgumentCaptor.capture());
531         final int[] supportedStates = intArrayAgumentCaptor.getValue();
532         assertTrue(supportedStates.length > 0);
533         for (int i = 0; i < supportedStates.length; i++) {
534             final int state = supportedStates[i];
535             assertValidState(state);
536         }
537     }
538 
539     private class StateTrackingCallback implements  DeviceStateManager.DeviceStateCallback {
540         private int mCurrentState = - 1;
541 
542         @Override
onStateChanged(int state)543         public void onStateChanged(int state) {
544             mCurrentState = state;
545         }
546     }
547 }
548