• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.am;
18 
19 import static android.Manifest.permission.INTERACT_ACROSS_PROFILES;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
22 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
23 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
24 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
25 import static android.app.ActivityManagerInternal.ALLOW_PROFILES_OR_NON_FULL;
26 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
27 import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
28 
29 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
30 
31 import static com.android.server.am.UserController.CLEAR_USER_JOURNEY_SESSION_MSG;
32 import static com.android.server.am.UserController.COMPLETE_USER_SWITCH_MSG;
33 import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
34 import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
35 import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
36 import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
37 import static com.android.server.am.UserController.USER_COMPLETED_EVENT_MSG;
38 import static com.android.server.am.UserController.USER_CURRENT_MSG;
39 import static com.android.server.am.UserController.USER_START_MSG;
40 import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
41 
42 import static com.google.android.collect.Lists.newArrayList;
43 import static com.google.android.collect.Sets.newHashSet;
44 import static com.google.common.truth.Truth.assertThat;
45 import static com.google.common.truth.Truth.assertWithMessage;
46 
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertFalse;
49 import static org.junit.Assert.assertNotNull;
50 import static org.junit.Assert.assertNull;
51 import static org.junit.Assert.assertTrue;
52 import static org.mockito.ArgumentMatchers.anyString;
53 import static org.mockito.Matchers.any;
54 import static org.mockito.Matchers.anyBoolean;
55 import static org.mockito.Matchers.anyInt;
56 import static org.mockito.Matchers.eq;
57 import static org.mockito.Mockito.doAnswer;
58 import static org.mockito.Mockito.doNothing;
59 import static org.mockito.Mockito.doReturn;
60 import static org.mockito.Mockito.mock;
61 import static org.mockito.Mockito.never;
62 import static org.mockito.Mockito.spy;
63 import static org.mockito.Mockito.times;
64 import static org.mockito.Mockito.validateMockitoUsage;
65 import static org.mockito.Mockito.verify;
66 import static org.mockito.Mockito.when;
67 import static org.testng.Assert.assertThrows;
68 
69 import android.annotation.Nullable;
70 import android.annotation.UserIdInt;
71 import android.app.ActivityManager;
72 import android.app.IUserSwitchObserver;
73 import android.app.KeyguardManager;
74 import android.content.Context;
75 import android.content.IIntentReceiver;
76 import android.content.Intent;
77 import android.content.pm.PackageManager;
78 import android.content.pm.UserInfo;
79 import android.content.pm.UserInfo.UserInfoFlag;
80 import android.os.Binder;
81 import android.os.Bundle;
82 import android.os.Handler;
83 import android.os.HandlerThread;
84 import android.os.IRemoteCallback;
85 import android.os.Looper;
86 import android.os.Message;
87 import android.os.RemoteException;
88 import android.os.UserHandle;
89 import android.os.UserManager;
90 import android.os.storage.IStorageManager;
91 import android.platform.test.annotations.Presubmit;
92 import android.util.Log;
93 
94 import androidx.test.filters.SmallTest;
95 
96 import com.android.server.FgThread;
97 import com.android.server.SystemService;
98 import com.android.server.am.UserState.KeyEvictedCallback;
99 import com.android.server.pm.UserManagerInternal;
100 import com.android.server.pm.UserManagerService;
101 import com.android.server.wm.WindowManagerService;
102 
103 import org.junit.After;
104 import org.junit.Before;
105 import org.junit.Test;
106 
107 import java.util.ArrayList;
108 import java.util.Arrays;
109 import java.util.Collections;
110 import java.util.HashMap;
111 import java.util.LinkedHashSet;
112 import java.util.List;
113 import java.util.Set;
114 
115 /**
116  * Tests for {@link UserController}.
117  *
118  * Build/Install/Run:
119  *  atest FrameworksServicesTests:UserControllerTest
120  */
121 @SmallTest
122 @Presubmit
123 
124 public class UserControllerTest {
125     // Use big enough user id to avoid picking up already active user id.
126     private static final int TEST_USER_ID = 100;
127     private static final int TEST_USER_ID1 = 101;
128     private static final int TEST_USER_ID2 = 102;
129     private static final int TEST_USER_ID3 = 103;
130     private static final int NONEXIST_USER_ID = 2;
131     private static final int TEST_PRE_CREATED_USER_ID = 103;
132 
133     private static final int NO_USERINFO_FLAGS = 0;
134 
135     private static final String TAG = UserControllerTest.class.getSimpleName();
136 
137     private static final long HANDLER_WAIT_TIME_MS = 100;
138 
139     private UserController mUserController;
140     private TestInjector mInjector;
141     private final HashMap<Integer, UserState> mUserStates = new HashMap<>();
142 
143     private final KeyEvictedCallback mKeyEvictedCallback = (userId) -> { /* ignore */ };
144 
145     private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList(
146             Intent.ACTION_USER_STARTED,
147             Intent.ACTION_USER_SWITCHED,
148             Intent.ACTION_USER_STARTING);
149 
150     private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList(
151             Intent.ACTION_USER_STARTED,
152             Intent.ACTION_LOCKED_BOOT_COMPLETED,
153             Intent.ACTION_USER_STARTING);
154 
155     private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet(
156             REPORT_USER_SWITCH_MSG,
157             USER_SWITCH_TIMEOUT_MSG,
158             USER_START_MSG,
159             USER_CURRENT_MSG);
160 
161     private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
162             USER_START_MSG,
163             REPORT_LOCKED_BOOT_COMPLETE_MSG);
164 
165     @Before
setUp()166     public void setUp() throws Exception {
167         runWithDexmakerShareClassLoader(() -> {
168             mInjector = spy(new TestInjector(getInstrumentation().getTargetContext()));
169             doNothing().when(mInjector).clearAllLockedTasks(anyString());
170             doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
171             doReturn(false).when(mInjector).taskSupervisorSwitchUser(anyInt(), any());
172             doNothing().when(mInjector).taskSupervisorResumeFocusedStackTopActivity();
173             doNothing().when(mInjector).systemServiceManagerOnUserStopped(anyInt());
174             doNothing().when(mInjector).systemServiceManagerOnUserCompletedEvent(
175                     anyInt(), anyInt());
176             doNothing().when(mInjector).activityManagerForceStopPackage(anyInt(), anyString());
177             doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
178             doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
179             doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
180             // All UserController params are set to default.
181             mUserController = new UserController(mInjector);
182 
183             // TODO(b/232452368): need to explicitly call setAllowUserUnlocking(), otherwise most
184             // tests would fail. But we might need to disable it for the onBootComplete() test (i.e,
185             // to make sure the users are unlocked at the right time)
186             mUserController.setAllowUserUnlocking(true);
187             setUpUser(TEST_USER_ID, NO_USERINFO_FLAGS);
188             setUpUser(TEST_PRE_CREATED_USER_ID, NO_USERINFO_FLAGS, /* preCreated=*/ true, null);
189         });
190     }
191 
192     @After
tearDown()193     public void tearDown() throws Exception {
194         mInjector.mHandlerThread.quit();
195         validateMockitoUsage();
196     }
197 
198     @Test
testStartUser_foreground()199     public void testStartUser_foreground() {
200         mUserController.startUser(TEST_USER_ID, true /* foreground */);
201         verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
202         verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
203         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
204         verify(mInjector.getWindowManager()).setSwitchingUser(true);
205         verify(mInjector).clearAllLockedTasks(anyString());
206         startForegroundUserAssertions();
207     }
208 
209     @Test
testStartUser_background()210     public void testStartUser_background() {
211         mUserController.startUser(TEST_USER_ID, false /* foreground */);
212         verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
213         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
214         verify(mInjector, never()).clearAllLockedTasks(anyString());
215         startBackgroundUserAssertions();
216     }
217 
218     @Test
testStartUserUIDisabled()219     public void testStartUserUIDisabled() {
220         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false,
221                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
222 
223         mUserController.startUser(TEST_USER_ID, true /* foreground */);
224         verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
225         verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
226         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
227         startForegroundUserAssertions();
228     }
229 
230     @Test
testStartPreCreatedUser_foreground()231     public void testStartPreCreatedUser_foreground() {
232         assertFalse(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ true));
233         // Make sure no intents have been fired for pre-created users.
234         assertTrue(mInjector.mSentIntents.isEmpty());
235     }
236 
237     @Test
testStartPreCreatedUser_background()238     public void testStartPreCreatedUser_background() throws Exception {
239         assertTrue(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ false));
240         // Make sure no intents have been fired for pre-created users.
241         assertTrue(mInjector.mSentIntents.isEmpty());
242 
243         verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
244         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
245         verify(mInjector, never()).clearAllLockedTasks(anyString());
246 
247         assertWithMessage("should not have received intents")
248                 .that(getActions(mInjector.mSentIntents)).isEmpty();
249         // TODO(b/140868593): should have received a USER_UNLOCK_MSG message as well, but it doesn't
250         // because StorageManager.isUserKeyUnlocked(TEST_PRE_CREATED_USER_ID) returns false - to
251         // properly fix it, we'd need to move this class to FrameworksMockingServicesTests so we can
252         // mock static methods (but moving this class would involve changing the presubmit tests,
253         // and the cascade effect goes on...). In fact, a better approach would to not assert the
254         // binder calls, but their side effects (in this case, that the user is stopped right away)
255         assertWithMessage("wrong binder message calls").that(mInjector.mHandler.getMessageCodes())
256                 .containsExactly(USER_START_MSG);
257     }
258 
startUserAssertions( List<String> expectedActions, Set<Integer> expectedMessageCodes)259     private void startUserAssertions(
260             List<String> expectedActions, Set<Integer> expectedMessageCodes) {
261         assertEquals(expectedActions, getActions(mInjector.mSentIntents));
262         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
263         assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes);
264     }
265 
startBackgroundUserAssertions()266     private void startBackgroundUserAssertions() {
267         startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES);
268     }
269 
startForegroundUserAssertions()270     private void startForegroundUserAssertions() {
271         startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES);
272         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
273         assertNotNull(reportMsg);
274         UserState userState = (UserState) reportMsg.obj;
275         assertNotNull(userState);
276         assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
277         assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
278         assertEquals("Unexpected old user id", 0, reportMsg.arg1);
279         assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2);
280     }
281 
282     @Test
testFailedStartUserInForeground()283     public void testFailedStartUserInForeground() {
284         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false,
285                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
286 
287         mUserController.startUserInForeground(NONEXIST_USER_ID);
288         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
289         verify(mInjector.getWindowManager()).setSwitchingUser(false);
290     }
291 
292     @Test
testDispatchUserSwitch()293     public void testDispatchUserSwitch() throws RemoteException {
294         // Prepare mock observer and register it
295         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
296         when(observer.asBinder()).thenReturn(new Binder());
297         doAnswer(invocation -> {
298             IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
299             callback.sendResult(null);
300             return null;
301         }).when(observer).onUserSwitching(anyInt(), any());
302         mUserController.registerUserSwitchObserver(observer, "mock");
303         // Start user -- this will update state of mUserController
304         mUserController.startUser(TEST_USER_ID, true);
305         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
306         assertNotNull(reportMsg);
307         UserState userState = (UserState) reportMsg.obj;
308         int oldUserId = reportMsg.arg1;
309         int newUserId = reportMsg.arg2;
310         // Call dispatchUserSwitch and verify that observer was called only once
311         mInjector.mHandler.clearAllRecordedMessages();
312         mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
313         verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
314         Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG);
315         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
316         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
317         Message conMsg = mInjector.mHandler.getMessageForCode(CONTINUE_USER_SWITCH_MSG);
318         assertNotNull(conMsg);
319         userState = (UserState) conMsg.obj;
320         assertNotNull(userState);
321         assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
322         assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
323         assertEquals("Unexpected old user id", 0, conMsg.arg1);
324         assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2);
325     }
326 
327     @Test
testDispatchUserSwitchBadReceiver()328     public void testDispatchUserSwitchBadReceiver() throws RemoteException {
329         // Prepare mock observer which doesn't notify the callback and register it
330         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
331         when(observer.asBinder()).thenReturn(new Binder());
332         mUserController.registerUserSwitchObserver(observer, "mock");
333         // Start user -- this will update state of mUserController
334         mUserController.startUser(TEST_USER_ID, true);
335         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
336         assertNotNull(reportMsg);
337         UserState userState = (UserState) reportMsg.obj;
338         int oldUserId = reportMsg.arg1;
339         int newUserId = reportMsg.arg2;
340         // Call dispatchUserSwitch and verify that observer was called only once
341         mInjector.mHandler.clearAllRecordedMessages();
342         mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
343         verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
344         // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout)
345         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
346         assertWithMessage("No messages should be sent").that(actualCodes).isEmpty();
347     }
348 
continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId)349     private void continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId) {
350         mUserController.continueUserSwitch(userState, oldUserId, newUserId);
351         mInjector.mHandler.removeMessages(UserController.COMPLETE_USER_SWITCH_MSG);
352         mUserController.completeUserSwitch(newUserId);
353     }
354 
355     @Test
testContinueUserSwitch()356     public void testContinueUserSwitch() throws RemoteException {
357         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
358                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
359         // Start user -- this will update state of mUserController
360         mUserController.startUser(TEST_USER_ID, true);
361         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
362         assertNotNull(reportMsg);
363         UserState userState = (UserState) reportMsg.obj;
364         int oldUserId = reportMsg.arg1;
365         int newUserId = reportMsg.arg2;
366         mInjector.mHandler.clearAllRecordedMessages();
367         // Verify that continueUserSwitch worked as expected
368         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
369         verify(mInjector, times(0)).dismissKeyguard(any(), anyString());
370         verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
371         continueUserSwitchAssertions(TEST_USER_ID, false);
372     }
373 
374     @Test
testContinueUserSwitchDismissKeyguard()375     public void testContinueUserSwitchDismissKeyguard() throws RemoteException {
376         when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(false);
377         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
378                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
379         // Start user -- this will update state of mUserController
380         mUserController.startUser(TEST_USER_ID, true);
381         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
382         assertNotNull(reportMsg);
383         UserState userState = (UserState) reportMsg.obj;
384         int oldUserId = reportMsg.arg1;
385         int newUserId = reportMsg.arg2;
386         mInjector.mHandler.clearAllRecordedMessages();
387         // Verify that continueUserSwitch worked as expected
388         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
389         verify(mInjector, times(1)).dismissKeyguard(any(), anyString());
390         verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
391         continueUserSwitchAssertions(TEST_USER_ID, false);
392     }
393 
394     @Test
testContinueUserSwitchUIDisabled()395     public void testContinueUserSwitchUIDisabled() throws RemoteException {
396         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false,
397                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
398 
399         // Start user -- this will update state of mUserController
400         mUserController.startUser(TEST_USER_ID, true);
401         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
402         assertNotNull(reportMsg);
403         UserState userState = (UserState) reportMsg.obj;
404         int oldUserId = reportMsg.arg1;
405         int newUserId = reportMsg.arg2;
406         mInjector.mHandler.clearAllRecordedMessages();
407         // Verify that continueUserSwitch worked as expected
408         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
409         verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
410         continueUserSwitchAssertions(TEST_USER_ID, false);
411     }
412 
continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping)413     private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping)
414             throws RemoteException {
415         Set<Integer> expectedCodes = new LinkedHashSet<>();
416         expectedCodes.add(COMPLETE_USER_SWITCH_MSG);
417         expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG);
418         if (backgroundUserStopping) {
419             expectedCodes.add(CLEAR_USER_JOURNEY_SESSION_MSG);
420             expectedCodes.add(0); // this is for directly posting in stopping.
421         }
422         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
423         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
424         Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG);
425         assertNotNull(msg);
426         assertEquals("Unexpected userId", expectedUserId, msg.arg1);
427     }
428 
429     @Test
testDispatchUserSwitchComplete()430     public void testDispatchUserSwitchComplete() throws RemoteException {
431         // Prepare mock observer and register it
432         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
433         when(observer.asBinder()).thenReturn(new Binder());
434         mUserController.registerUserSwitchObserver(observer, "mock");
435         // Start user -- this will update state of mUserController
436         mUserController.startUser(TEST_USER_ID, true);
437         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
438         assertNotNull(reportMsg);
439         int newUserId = reportMsg.arg2;
440         mInjector.mHandler.clearAllRecordedMessages();
441         // Mockito can't reset only interactions, so just verify that this hasn't been
442         // called with 'false' until after dispatchUserSwitchComplete.
443         verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
444         // Call dispatchUserSwitchComplete
445         mUserController.dispatchUserSwitchComplete(newUserId);
446         verify(observer, times(1)).onUserSwitchComplete(anyInt());
447         verify(observer).onUserSwitchComplete(TEST_USER_ID);
448         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
449     }
450 
451     @Test
testExplicitSystemUserStartInBackground()452     public void testExplicitSystemUserStartInBackground() {
453         setUpUser(UserHandle.USER_SYSTEM, 0);
454         assertFalse(mUserController.isSystemUserStarted());
455         assertTrue(mUserController.startUser(UserHandle.USER_SYSTEM, false, null));
456         assertTrue(mUserController.isSystemUserStarted());
457     }
458 
459     /**
460      * Test stopping of user from max running users limit.
461      */
462     @Test
testUserLockingFromUserSwitchingForMultipleUsersNonDelayedLocking()463     public void testUserLockingFromUserSwitchingForMultipleUsersNonDelayedLocking()
464             throws InterruptedException, RemoteException {
465         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
466                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
467 
468         setUpUser(TEST_USER_ID1, 0);
469         setUpUser(TEST_USER_ID2, 0);
470         int numerOfUserSwitches = 1;
471         addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
472                 numerOfUserSwitches, false);
473         // running: user 0, USER_ID
474         assertTrue(mUserController.canStartMoreUsers());
475         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}),
476                 mUserController.getRunningUsersLU());
477 
478         numerOfUserSwitches++;
479         addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
480                 numerOfUserSwitches, false);
481         // running: user 0, USER_ID, USER_ID1
482         assertFalse(mUserController.canStartMoreUsers());
483         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID, TEST_USER_ID1}),
484                 mUserController.getRunningUsersLU());
485 
486         numerOfUserSwitches++;
487         addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1,
488                 numerOfUserSwitches, false);
489         UserState ussUser2 = mUserStates.get(TEST_USER_ID2);
490         // skip middle step and call this directly.
491         mUserController.finishUserSwitch(ussUser2);
492         waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
493         // running: user 0, USER_ID1, USER_ID2
494         // USER_ID should be stopped as it is least recently used non user0.
495         assertFalse(mUserController.canStartMoreUsers());
496         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1, TEST_USER_ID2}),
497                 mUserController.getRunningUsersLU());
498     }
499 
500     /**
501      * This test tests delayed locking mode using 4 users. As core logic of delayed locking is
502      * happening in finishUserStopped call, the test also calls finishUserStopped while skipping
503      * all middle steps which takes too much work to mock.
504      */
505     @Test
testUserLockingFromUserSwitchingForMultipleUsersDelayedLockingMode()506     public void testUserLockingFromUserSwitchingForMultipleUsersDelayedLockingMode()
507             throws InterruptedException, RemoteException {
508         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
509                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ true);
510 
511         setUpUser(TEST_USER_ID1, 0);
512         setUpUser(TEST_USER_ID2, 0);
513         int numerOfUserSwitches = 1;
514         addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
515                 numerOfUserSwitches, false);
516         // running: user 0, USER_ID
517         assertTrue(mUserController.canStartMoreUsers());
518         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}),
519                 mUserController.getRunningUsersLU());
520         numerOfUserSwitches++;
521 
522         addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
523                 numerOfUserSwitches, true);
524         // running: user 0, USER_ID1
525         // stopped + unlocked: USER_ID
526         numerOfUserSwitches++;
527         assertTrue(mUserController.canStartMoreUsers());
528         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1}),
529                 mUserController.getRunningUsersLU());
530         // Skip all other steps and test unlock delaying only
531         UserState uss = mUserStates.get(TEST_USER_ID);
532         uss.setState(UserState.STATE_SHUTDOWN); // necessary state change from skipped part
533         mUserController.finishUserStopped(uss, /* allowDelayedLocking= */ true);
534         // Cannot mock FgThread handler, so confirm that there is no posted message left before
535         // checking.
536         waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
537         verify(mInjector.mStorageManagerMock, times(0))
538                 .lockUserKey(anyInt());
539 
540         addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1,
541                 numerOfUserSwitches, true);
542         // running: user 0, USER_ID2
543         // stopped + unlocked: USER_ID1
544         // stopped + locked: USER_ID
545         assertTrue(mUserController.canStartMoreUsers());
546         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID2}),
547                 mUserController.getRunningUsersLU());
548         UserState ussUser1 = mUserStates.get(TEST_USER_ID1);
549         ussUser1.setState(UserState.STATE_SHUTDOWN);
550         mUserController.finishUserStopped(ussUser1, /* allowDelayedLocking= */ true);
551         waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
552         verify(mInjector.mStorageManagerMock, times(1))
553                 .lockUserKey(TEST_USER_ID);
554     }
555 
556     /**
557      * Test locking user with mDelayUserDataLocking false.
558      */
559     @Test
testUserLockingWithStopUserForNonDelayedLockingMode()560     public void testUserLockingWithStopUserForNonDelayedLockingMode() throws Exception {
561         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
562                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
563 
564         setUpAndStartUserInBackground(TEST_USER_ID);
565         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* delayedLocking= */ true,
566                 /* keyEvictedCallback= */ null, /* expectLocking= */ true);
567 
568         setUpAndStartUserInBackground(TEST_USER_ID1);
569         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true,
570                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
571 
572         setUpAndStartUserInBackground(TEST_USER_ID2);
573         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ false,
574                 /* keyEvictedCallback= */ null, /* expectLocking= */ true);
575 
576         setUpAndStartUserInBackground(TEST_USER_ID3);
577         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* delayedLocking= */ false,
578                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
579     }
580 
581     /**
582      * Test conditional delayed locking with mDelayUserDataLocking true.
583      */
584     @Test
testUserLockingForDelayedLockingMode()585     public void testUserLockingForDelayedLockingMode() throws Exception {
586         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
587                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ true);
588 
589         // delayedLocking set and no KeyEvictedCallback, so it should not lock.
590         setUpAndStartUserInBackground(TEST_USER_ID);
591         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* delayedLocking= */ true,
592                 /* keyEvictedCallback= */ null, /* expectLocking= */ false);
593 
594         setUpAndStartUserInBackground(TEST_USER_ID1);
595         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true,
596                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
597 
598         setUpAndStartUserInBackground(TEST_USER_ID2);
599         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ false,
600                 /* keyEvictedCallback= */ null, /* expectLocking= */ true);
601 
602         setUpAndStartUserInBackground(TEST_USER_ID3);
603         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* delayedLocking= */ false,
604                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
605     }
606 
607     @Test
testUserNotUnlockedBeforeAllowed()608     public void testUserNotUnlockedBeforeAllowed() throws Exception {
609         mUserController.setAllowUserUnlocking(false);
610 
611         mUserController.startUser(TEST_USER_ID, /* foreground= */ false);
612 
613         verify(mInjector.mStorageManagerMock, never())
614                 .unlockUserKey(eq(TEST_USER_ID), anyInt(), any());
615     }
616 
617     @Test
testStartProfile_fullUserFails()618     public void testStartProfile_fullUserFails() {
619         setUpUser(TEST_USER_ID1, 0);
620         assertThrows(IllegalArgumentException.class,
621                 () -> mUserController.startProfile(TEST_USER_ID1));
622     }
623 
624     @Test
testStopProfile_fullUserFails()625     public void testStopProfile_fullUserFails() throws Exception {
626         setUpAndStartUserInBackground(TEST_USER_ID1);
627         assertThrows(IllegalArgumentException.class,
628                 () -> mUserController.stopProfile(TEST_USER_ID1));
629     }
630 
631     @Test
testStartProfile_disabledProfileFails()632     public void testStartProfile_disabledProfileFails() {
633         setUpUser(TEST_USER_ID1, UserInfo.FLAG_PROFILE | UserInfo.FLAG_DISABLED, /* preCreated= */
634                 false, UserManager.USER_TYPE_PROFILE_MANAGED);
635         assertThat(mUserController.startProfile(TEST_USER_ID1)).isFalse();
636     }
637 
638     @Test
testStartProfile()639     public void testStartProfile() throws Exception {
640         setUpAndStartProfileInBackground(TEST_USER_ID1);
641         startBackgroundUserAssertions();
642     }
643 
644     @Test
testStopProfile()645     public void testStopProfile() throws Exception {
646         setUpAndStartProfileInBackground(TEST_USER_ID1);
647         assertProfileLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* expectLocking= */ true);
648     }
649 
650     /** Tests handleIncomingUser() for a variety of permissions and situations. */
651     @Test
testHandleIncomingUser()652     public void testHandleIncomingUser() throws Exception {
653         final UserInfo user1a = new UserInfo(111, "user1a", 0);
654         final UserInfo user1b = new UserInfo(112, "user1b", 0);
655         final UserInfo user2 = new UserInfo(113, "user2", 0);
656         // user1a and user2b are in the same profile group; user2 is in a different one.
657         user1a.profileGroupId = 5;
658         user1b.profileGroupId = 5;
659         user2.profileGroupId = 6;
660 
661         final List<UserInfo> users = Arrays.asList(user1a, user1b, user2);
662         when(mInjector.mUserManagerMock.getUsers(false)).thenReturn(users);
663         mUserController.onSystemReady(); // To set the profileGroupIds in UserController.
664 
665 
666         // Has INTERACT_ACROSS_USERS_FULL.
667         when(mInjector.checkComponentPermission(
668                 eq(INTERACT_ACROSS_USERS_FULL), anyInt(), anyInt(), anyInt(), anyBoolean()))
669                 .thenReturn(PackageManager.PERMISSION_GRANTED);
670         when(mInjector.checkComponentPermission(
671                 eq(INTERACT_ACROSS_USERS), anyInt(), anyInt(), anyInt(), anyBoolean()))
672                 .thenReturn(PackageManager.PERMISSION_DENIED);
673         when(mInjector.checkPermissionForPreflight(
674                 eq(INTERACT_ACROSS_PROFILES), anyInt(), anyInt(), any())).thenReturn(false);
675 
676         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL, true);
677         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL_IN_PROFILE, true);
678         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_FULL_ONLY, true);
679         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_PROFILES_OR_NON_FULL, true);
680 
681         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL, true);
682         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL_IN_PROFILE, true);
683         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_FULL_ONLY, true);
684         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_PROFILES_OR_NON_FULL, true);
685 
686 
687         // Has INTERACT_ACROSS_USERS.
688         when(mInjector.checkComponentPermission(
689                 eq(INTERACT_ACROSS_USERS_FULL), anyInt(), anyInt(), anyInt(), anyBoolean()))
690                 .thenReturn(PackageManager.PERMISSION_DENIED);
691         when(mInjector.checkComponentPermission(
692                 eq(INTERACT_ACROSS_USERS), anyInt(), anyInt(), anyInt(), anyBoolean()))
693                 .thenReturn(PackageManager.PERMISSION_GRANTED);
694         when(mInjector.checkPermissionForPreflight(
695                 eq(INTERACT_ACROSS_PROFILES), anyInt(), anyInt(), any())).thenReturn(false);
696 
697         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL, true);
698         checkHandleIncomingUser(user1a.id, user2.id,  ALLOW_NON_FULL_IN_PROFILE, false);
699         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_FULL_ONLY, false);
700         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_PROFILES_OR_NON_FULL, true);
701 
702         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL, true);
703         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL_IN_PROFILE, true);
704         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_FULL_ONLY, false);
705         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_PROFILES_OR_NON_FULL, true);
706 
707 
708         // Has INTERACT_ACROSS_PROFILES.
709         when(mInjector.checkComponentPermission(
710                 eq(INTERACT_ACROSS_USERS_FULL), anyInt(), anyInt(), anyInt(), anyBoolean()))
711                 .thenReturn(PackageManager.PERMISSION_DENIED);
712         when(mInjector.checkComponentPermission(
713                 eq(INTERACT_ACROSS_USERS), anyInt(), anyInt(), anyInt(), anyBoolean()))
714                 .thenReturn(PackageManager.PERMISSION_DENIED);
715         when(mInjector.checkPermissionForPreflight(
716                 eq(INTERACT_ACROSS_PROFILES), anyInt(), anyInt(), any())).thenReturn(true);
717 
718         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL, false);
719         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL_IN_PROFILE, false);
720         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_FULL_ONLY, false);
721         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_PROFILES_OR_NON_FULL, false);
722 
723         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL, false);
724         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL_IN_PROFILE, false);
725         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_FULL_ONLY, false);
726         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_PROFILES_OR_NON_FULL, true);
727     }
728 
checkHandleIncomingUser(int fromUser, int toUser, int allowMode, boolean pass)729     private void checkHandleIncomingUser(int fromUser, int toUser, int allowMode, boolean pass) {
730         final int pid = 100;
731         final int uid = fromUser * UserHandle.PER_USER_RANGE + 34567 + fromUser;
732         final String name = "whatever";
733         final String pkg = "some.package";
734         final boolean allowAll = false;
735 
736         if (pass) {
737             mUserController.handleIncomingUser(pid, uid, toUser, allowAll, allowMode, name, pkg);
738         } else {
739             assertThrows(SecurityException.class, () -> mUserController.handleIncomingUser(
740                     pid, uid, toUser, allowAll, allowMode, name, pkg));
741         }
742     }
743 
744     @Test
testScheduleOnUserCompletedEvent()745     public void testScheduleOnUserCompletedEvent() throws Exception {
746         // user1 is starting, switching, and unlocked, but not scheduled unlocked yet
747         // user2 is starting and had unlocked but isn't unlocked anymore for whatever reason
748 
749         final int user1 = 101;
750         final int user2 = 102;
751         setUpUser(user1, 0);
752         setUpUser(user2, 0);
753 
754         mUserController.startUser(user1, /* foreground= */ true);
755         mUserController.getStartedUserState(user1).setState(UserState.STATE_RUNNING_UNLOCKED);
756 
757         mUserController.startUser(user2, /* foreground= */ false);
758         mUserController.getStartedUserState(user2).setState(UserState.STATE_RUNNING_LOCKED);
759 
760         final int event1a = SystemService.UserCompletedEventType.EVENT_TYPE_USER_STARTING;
761         final int event1b = SystemService.UserCompletedEventType.EVENT_TYPE_USER_SWITCHING;
762 
763         final int event2a = SystemService.UserCompletedEventType.EVENT_TYPE_USER_STARTING;
764         final int event2b = SystemService.UserCompletedEventType.EVENT_TYPE_USER_UNLOCKED;
765 
766 
767         mUserController.scheduleOnUserCompletedEvent(user1, event1a, 2000);
768         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user1));
769         assertNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user2));
770 
771         mUserController.scheduleOnUserCompletedEvent(user2, event2a, 2000);
772         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user1));
773         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user2));
774 
775         mUserController.scheduleOnUserCompletedEvent(user2, event2b, 2000);
776         mUserController.scheduleOnUserCompletedEvent(user1, event1b, 2000);
777         mUserController.scheduleOnUserCompletedEvent(user1, 0, 2000);
778 
779         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user1));
780         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user2));
781 
782         mUserController.reportOnUserCompletedEvent(user1);
783         verify(mInjector, times(1))
784                 .systemServiceManagerOnUserCompletedEvent(eq(user1), eq(event1a | event1b));
785         verify(mInjector, never()).systemServiceManagerOnUserCompletedEvent(eq(user2), anyInt());
786 
787         mUserController.reportOnUserCompletedEvent(user2);
788         verify(mInjector, times(1))
789                 .systemServiceManagerOnUserCompletedEvent(eq(user2), eq(event2a));
790     }
791 
setUpAndStartUserInBackground(int userId)792     private void setUpAndStartUserInBackground(int userId) throws Exception {
793         setUpUser(userId, 0);
794         mUserController.startUser(userId, /* foreground= */ false);
795         verify(mInjector.mStorageManagerMock, times(1))
796                 .unlockUserKey(userId, /* serialNumber= */ 0, /* secret= */ null);
797         mUserStates.put(userId, mUserController.getStartedUserState(userId));
798     }
799 
setUpAndStartProfileInBackground(int userId)800     private void setUpAndStartProfileInBackground(int userId) throws Exception {
801         setUpUser(userId, UserInfo.FLAG_PROFILE, false, UserManager.USER_TYPE_PROFILE_MANAGED);
802         assertThat(mUserController.startProfile(userId)).isTrue();
803 
804         verify(mInjector.mStorageManagerMock, times(1))
805                 .unlockUserKey(userId, /* serialNumber= */ 0, /* secret= */ null);
806         mUserStates.put(userId, mUserController.getStartedUserState(userId));
807     }
808 
assertUserLockedOrUnlockedAfterStopping(int userId, boolean delayedLocking, KeyEvictedCallback keyEvictedCallback, boolean expectLocking)809     private void assertUserLockedOrUnlockedAfterStopping(int userId, boolean delayedLocking,
810             KeyEvictedCallback keyEvictedCallback, boolean expectLocking) throws Exception {
811         int r = mUserController.stopUser(userId, /* force= */ true, /* delayedLocking= */
812                 delayedLocking, null, keyEvictedCallback);
813         assertThat(r).isEqualTo(ActivityManager.USER_OP_SUCCESS);
814         assertUserLockedOrUnlockedState(userId, delayedLocking, expectLocking);
815     }
816 
assertProfileLockedOrUnlockedAfterStopping(int userId, boolean expectLocking)817     private void assertProfileLockedOrUnlockedAfterStopping(int userId, boolean expectLocking)
818             throws Exception {
819         boolean profileStopped = mUserController.stopProfile(userId);
820         assertThat(profileStopped).isTrue();
821         assertUserLockedOrUnlockedState(userId, /* delayedLocking= */ false, expectLocking);
822     }
823 
assertUserLockedOrUnlockedState(int userId, boolean delayedLocking, boolean expectLocking)824     private void assertUserLockedOrUnlockedState(int userId, boolean delayedLocking,
825             boolean expectLocking) throws InterruptedException, RemoteException {
826         // fake all interim steps
827         UserState ussUser = mUserStates.get(userId);
828         ussUser.setState(UserState.STATE_SHUTDOWN);
829         // Passing delayedLocking invalidates incorrect internal data passing but currently there is
830         // no easy way to get that information passed through lambda.
831         mUserController.finishUserStopped(ussUser, delayedLocking);
832         waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
833         verify(mInjector.mStorageManagerMock, times(expectLocking ? 1 : 0))
834                 .lockUserKey(userId);
835     }
836 
addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, int expectedNumberOfCalls, boolean expectOldUserStopping)837     private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId,
838             int expectedNumberOfCalls, boolean expectOldUserStopping)
839             throws RemoteException {
840         // Start user -- this will update state of mUserController
841         mUserController.startUser(newUserId, true);
842         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
843         assertNotNull(reportMsg);
844         UserState userState = (UserState) reportMsg.obj;
845         int oldUserId = reportMsg.arg1;
846         assertEquals(expectedOldUserId, oldUserId);
847         assertEquals(newUserId, reportMsg.arg2);
848         mUserStates.put(newUserId, userState);
849         mInjector.mHandler.clearAllRecordedMessages();
850         // Verify that continueUserSwitch worked as expected
851         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
852         verify(mInjector.getWindowManager(), times(expectedNumberOfCalls))
853                 .stopFreezingScreen();
854         continueUserSwitchAssertions(newUserId, expectOldUserStopping);
855     }
856 
setUpUser(@serIdInt int userId, @UserInfoFlag int flags)857     private void setUpUser(@UserIdInt int userId, @UserInfoFlag int flags) {
858         setUpUser(userId, flags, /* preCreated= */ false, /* userType */ null);
859     }
860 
setUpUser(@serIdInt int userId, @UserInfoFlag int flags, boolean preCreated, @Nullable String userType)861     private void setUpUser(@UserIdInt int userId, @UserInfoFlag int flags, boolean preCreated,
862             @Nullable String userType) {
863         if (userType == null) {
864             userType = UserInfo.getDefaultUserType(flags);
865         }
866         UserInfo userInfo = new UserInfo(userId, "User" + userId, /* iconPath= */ null, flags,
867                 userType);
868         userInfo.preCreated = preCreated;
869         when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo);
870         when(mInjector.mUserManagerMock.isPreCreated(userId)).thenReturn(preCreated);
871     }
872 
getActions(List<Intent> intents)873     private static List<String> getActions(List<Intent> intents) {
874         List<String> result = new ArrayList<>();
875         for (Intent intent : intents) {
876             result.add(intent.getAction());
877         }
878         return result;
879     }
880 
waitForHandlerToComplete(Handler handler, long waitTimeMs)881     private void waitForHandlerToComplete(Handler handler, long waitTimeMs)
882             throws InterruptedException {
883         final Object lock = new Object();
884         synchronized (lock) {
885             handler.post(() -> {
886                 synchronized (lock) {
887                     lock.notify();
888                 }
889             });
890             lock.wait(waitTimeMs);
891         }
892     }
893 
894     // Should be public to allow mocking
895     private static class TestInjector extends UserController.Injector {
896         public final TestHandler mHandler;
897         public final HandlerThread mHandlerThread;
898         public final UserManagerService mUserManagerMock;
899         public final List<Intent> mSentIntents = new ArrayList<>();
900 
901         private final TestHandler mUiHandler;
902 
903         private final IStorageManager mStorageManagerMock;
904         private final UserManagerInternal mUserManagerInternalMock;
905         private final WindowManagerService mWindowManagerMock;
906         private final KeyguardManager mKeyguardManagerMock;
907 
908         private final Context mCtx;
909 
TestInjector(Context ctx)910         TestInjector(Context ctx) {
911             super(null);
912             mCtx = ctx;
913             mHandlerThread = new HandlerThread(TAG);
914             mHandlerThread.start();
915             mHandler = new TestHandler(mHandlerThread.getLooper());
916             mUiHandler = new TestHandler(mHandlerThread.getLooper());
917             mUserManagerMock = mock(UserManagerService.class);
918             mUserManagerInternalMock = mock(UserManagerInternal.class);
919             mWindowManagerMock = mock(WindowManagerService.class);
920             mStorageManagerMock = mock(IStorageManager.class);
921             mKeyguardManagerMock = mock(KeyguardManager.class);
922             when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
923         }
924 
925         @Override
getHandler(Handler.Callback callback)926         protected Handler getHandler(Handler.Callback callback) {
927             return mHandler;
928         }
929 
930         @Override
getUiHandler(Handler.Callback callback)931         protected Handler getUiHandler(Handler.Callback callback) {
932             return mUiHandler;
933         }
934 
935         @Override
getUserManager()936         protected UserManagerService getUserManager() {
937             return mUserManagerMock;
938         }
939 
940         @Override
getUserManagerInternal()941         UserManagerInternal getUserManagerInternal() {
942             return mUserManagerInternalMock;
943         }
944 
945         @Override
getContext()946         protected Context getContext() {
947             return mCtx;
948         }
949 
950         @Override
checkCallingPermission(String permission)951         int checkCallingPermission(String permission) {
952             Log.i(TAG, "checkCallingPermission " + permission);
953             return PERMISSION_GRANTED;
954         }
955 
956         @Override
checkComponentPermission(String permission, int pid, int uid, int owner, boolean exp)957         int checkComponentPermission(String permission, int pid, int uid, int owner, boolean exp) {
958             Log.i(TAG, "checkComponentPermission " + permission);
959             return PERMISSION_GRANTED;
960         }
961 
962         @Override
checkPermissionForPreflight(String permission, int pid, int uid, String pkg)963         boolean checkPermissionForPreflight(String permission, int pid, int uid, String pkg) {
964             Log.i(TAG, "checkPermissionForPreflight " + permission);
965             return true;
966         }
967 
968         @Override
isCallerRecents(int uid)969         boolean isCallerRecents(int uid) {
970             return false;
971         }
972 
973         @Override
getWindowManager()974         WindowManagerService getWindowManager() {
975             return mWindowManagerMock;
976         }
977 
978         @Override
getKeyguardManager()979         KeyguardManager getKeyguardManager() {
980             return mKeyguardManagerMock;
981         }
982 
983         @Override
updateUserConfiguration()984         void updateUserConfiguration() {
985             Log.i(TAG, "updateUserConfiguration");
986         }
987 
988         @Override
broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId)989         protected int broadcastIntent(Intent intent, String resolvedType,
990                 IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras,
991                 String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered,
992                 boolean sticky, int callingPid, int callingUid, int realCallingUid,
993                 int realCallingPid, int userId) {
994             Log.i(TAG, "broadcastIntentLocked " + intent);
995             mSentIntents.add(intent);
996             return 0;
997         }
998 
999         @Override
reportGlobalUsageEvent(int event)1000         void reportGlobalUsageEvent(int event) {
1001         }
1002 
1003         @Override
reportCurWakefulnessUsageEvent()1004         void reportCurWakefulnessUsageEvent() {
1005         }
1006 
1007         @Override
isRuntimeRestarted()1008         boolean isRuntimeRestarted() {
1009             // to pass all metrics related calls
1010             return true;
1011         }
1012 
1013         @Override
getStorageManager()1014         protected IStorageManager getStorageManager() {
1015             return mStorageManagerMock;
1016         }
1017 
1018         @Override
dismissKeyguard(Runnable runnable, String reason)1019         protected void dismissKeyguard(Runnable runnable, String reason) {
1020             runnable.run();
1021         }
1022     }
1023 
1024     private static class TestHandler extends Handler {
1025         private final List<Message> mMessages = new ArrayList<>();
1026 
TestHandler(Looper looper)1027         TestHandler(Looper looper) {
1028             super(looper);
1029         }
1030 
getMessageCodes()1031         Set<Integer> getMessageCodes() {
1032             Set<Integer> result = new LinkedHashSet<>();
1033             for (Message msg : mMessages) {
1034                 result.add(msg.what);
1035             }
1036             return result;
1037         }
1038 
getMessageForCode(int what)1039         Message getMessageForCode(int what) {
1040             return getMessageForCode(what, null);
1041         }
1042 
getMessageForCode(int what, Object obj)1043         Message getMessageForCode(int what, Object obj) {
1044             for (Message msg : mMessages) {
1045                 if (msg.what == what && (obj == null || obj.equals(msg.obj))) {
1046                     return msg;
1047                 }
1048             }
1049             return null;
1050         }
1051 
clearAllRecordedMessages()1052         void clearAllRecordedMessages() {
1053             mMessages.clear();
1054         }
1055 
1056         @Override
sendMessageAtTime(Message msg, long uptimeMillis)1057         public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
1058             Message copy = new Message();
1059             copy.copyFrom(msg);
1060             mMessages.add(copy);
1061             return super.sendMessageAtTime(msg, uptimeMillis);
1062         }
1063     }
1064 }
1065