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.SCHEDULED_STOP_BACKGROUND_USER_MSG;
38 import static com.android.server.am.UserController.USER_COMPLETED_EVENT_MSG;
39 import static com.android.server.am.UserController.USER_CURRENT_MSG;
40 import static com.android.server.am.UserController.USER_START_MSG;
41 import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
42 import static com.android.server.pm.UserManagerInternal.USER_START_MODE_BACKGROUND;
43 import static com.android.server.pm.UserManagerInternal.USER_START_MODE_FOREGROUND;
44 
45 import static com.google.android.collect.Lists.newArrayList;
46 import static com.google.android.collect.Sets.newHashSet;
47 import static com.google.common.truth.Truth.assertThat;
48 import static com.google.common.truth.Truth.assertWithMessage;
49 
50 import static org.junit.Assert.assertEquals;
51 import static org.junit.Assert.assertFalse;
52 import static org.junit.Assert.assertNotNull;
53 import static org.junit.Assert.assertNull;
54 import static org.junit.Assert.assertThrows;
55 import static org.junit.Assert.assertTrue;
56 import static org.mockito.ArgumentMatchers.anyString;
57 import static org.mockito.Matchers.any;
58 import static org.mockito.Matchers.anyBoolean;
59 import static org.mockito.Matchers.anyInt;
60 import static org.mockito.Matchers.eq;
61 import static org.mockito.Mockito.atLeastOnce;
62 import static org.mockito.Mockito.doAnswer;
63 import static org.mockito.Mockito.doCallRealMethod;
64 import static org.mockito.Mockito.doNothing;
65 import static org.mockito.Mockito.doReturn;
66 import static org.mockito.Mockito.mock;
67 import static org.mockito.Mockito.never;
68 import static org.mockito.Mockito.spy;
69 import static org.mockito.Mockito.times;
70 import static org.mockito.Mockito.validateMockitoUsage;
71 import static org.mockito.Mockito.verify;
72 import static org.mockito.Mockito.when;
73 
74 import android.annotation.Nullable;
75 import android.annotation.UserIdInt;
76 import android.app.ActivityManager;
77 import android.app.IUserSwitchObserver;
78 import android.app.KeyguardManager;
79 import android.content.Context;
80 import android.content.IIntentReceiver;
81 import android.content.Intent;
82 import android.content.pm.PackageManager;
83 import android.content.pm.UserInfo;
84 import android.content.pm.UserInfo.UserInfoFlag;
85 import android.os.Binder;
86 import android.os.Bundle;
87 import android.os.Handler;
88 import android.os.HandlerThread;
89 import android.os.IRemoteCallback;
90 import android.os.Looper;
91 import android.os.Message;
92 import android.os.PowerManagerInternal;
93 import android.os.RemoteException;
94 import android.os.SystemClock;
95 import android.os.UserHandle;
96 import android.os.UserManager;
97 import android.os.storage.IStorageManager;
98 import android.platform.test.annotations.Presubmit;
99 import android.platform.test.flag.junit.SetFlagsRule;
100 import android.util.Log;
101 import android.view.Display;
102 
103 import androidx.test.filters.SmallTest;
104 
105 import com.android.internal.widget.LockPatternUtils;
106 import com.android.server.FgThread;
107 import com.android.server.SystemService;
108 import com.android.server.am.UserState.KeyEvictedCallback;
109 import com.android.server.pm.UserJourneyLogger;
110 import com.android.server.pm.UserManagerInternal;
111 import com.android.server.pm.UserManagerService;
112 import com.android.server.pm.UserTypeDetails;
113 import com.android.server.pm.UserTypeFactory;
114 import com.android.server.wm.ActivityTaskManagerInternal;
115 import com.android.server.wm.WindowManagerService;
116 
117 import com.google.common.collect.Range;
118 
119 import org.junit.After;
120 import org.junit.Before;
121 import org.junit.Rule;
122 import org.junit.Test;
123 import org.mockito.ArgumentCaptor;
124 
125 import java.util.ArrayList;
126 import java.util.Arrays;
127 import java.util.Collections;
128 import java.util.HashMap;
129 import java.util.HashSet;
130 import java.util.LinkedHashSet;
131 import java.util.List;
132 import java.util.Set;
133 import java.util.stream.Collectors;
134 import java.util.stream.Stream;
135 
136 /**
137  * Tests for {@link UserController}.
138  *
139  * Build/Install/Run:
140  *  atest FrameworksServicesTests:UserControllerTest
141  */
142 @SmallTest
143 @Presubmit
144 
145 public class UserControllerTest {
146     // Use big enough user id to avoid picking up already active user id.
147     private static final int TEST_USER_ID = 100;
148     private static final int TEST_USER_ID1 = 101;
149     private static final int TEST_USER_ID2 = 102;
150     private static final int TEST_USER_ID3 = 103;
151     private static final int SYSTEM_USER_ID = UserHandle.SYSTEM.getIdentifier();
152     private static final int NONEXIST_USER_ID = 2;
153     private static final int TEST_PRE_CREATED_USER_ID = 103;
154 
155     private static final int NO_USERINFO_FLAGS = 0;
156 
157     private static final String TAG = UserControllerTest.class.getSimpleName();
158 
159     private static final long HANDLER_WAIT_TIME_MS = 100;
160 
161     private UserController mUserController;
162     private TestInjector mInjector;
163     private final HashMap<Integer, UserState> mUserStates = new HashMap<>();
164     private final HashMap<Integer, UserInfo> mUserInfos = new HashMap<>();
165 
166     private final KeyEvictedCallback mKeyEvictedCallback = (userId) -> { /* ignore */ };
167 
168     private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList(
169             Intent.ACTION_USER_STARTED,
170             Intent.ACTION_USER_STARTING);
171 
172     private static final List<String> START_FOREGROUND_USER_DEFERRED_ACTIONS = newArrayList(
173             Intent.ACTION_USER_SWITCHED);
174 
175     private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList(
176             Intent.ACTION_USER_STARTED,
177             Intent.ACTION_LOCKED_BOOT_COMPLETED,
178             Intent.ACTION_USER_STARTING);
179 
180     private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet(
181             REPORT_USER_SWITCH_MSG,
182             USER_SWITCH_TIMEOUT_MSG,
183             USER_START_MSG,
184             USER_CURRENT_MSG);
185 
186     private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
187             USER_START_MSG,
188             REPORT_LOCKED_BOOT_COMPLETE_MSG);
189 
190     @Rule
191     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
192 
193     @Before
setUp()194     public void setUp() throws Exception {
195         runWithDexmakerShareClassLoader(() -> {
196             mInjector = spy(new TestInjector(getInstrumentation().getTargetContext()));
197             doNothing().when(mInjector).clearAllLockedTasks(anyString());
198             doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
199             doReturn(false).when(mInjector).taskSupervisorSwitchUser(anyInt(), any());
200             doNothing().when(mInjector).taskSupervisorResumeFocusedStackTopActivity();
201             doNothing().when(mInjector).systemServiceManagerOnUserStopped(anyInt());
202             doNothing().when(mInjector).systemServiceManagerOnUserCompletedEvent(
203                     anyInt(), anyInt());
204             doNothing().when(mInjector).activityManagerForceStopPackage(anyInt(), anyString());
205             doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
206             doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
207             doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
208             doAnswer(invocation -> {
209                 ((Runnable) invocation.getArgument(0)).run();
210                 return null;
211             }).when(mInjector).showKeyguard(any());
212             mockIsUsersOnSecondaryDisplaysEnabled(false);
213             // All UserController params are set to default.
214 
215             // Starts with a generic assumption that the user starts visible, but on tests where
216             // that's not the case, the test should call mockAssignUserToMainDisplay()
217             doReturn(UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE)
218                     .when(mInjector.mUserManagerInternalMock)
219                     .assignUserToDisplayOnStart(anyInt(), anyInt(), anyInt(), anyInt());
220 
221             mUserController = new UserController(mInjector);
222             mUserController.setAllowUserUnlocking(true);
223             setUpUser(TEST_USER_ID, NO_USERINFO_FLAGS);
224             setUpUser(TEST_PRE_CREATED_USER_ID, NO_USERINFO_FLAGS, /* preCreated= */ true, null);
225             mInjector.mRelevantUser = null;
226         });
227     }
228 
229     @After
tearDown()230     public void tearDown() throws Exception {
231         mInjector.mHandlerThread.quit();
232         validateMockitoUsage();
233     }
234 
235     @Test
testStartUser_foreground()236     public void testStartUser_foreground() {
237         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
238         verify(mInjector, never()).dismissUserSwitchingDialog(any());
239         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
240         verify(mInjector.getWindowManager()).setSwitchingUser(true);
241         verify(mInjector).clearAllLockedTasks(anyString());
242         startForegroundUserAssertions();
243         verifyUserAssignedToDisplay(TEST_USER_ID, Display.DEFAULT_DISPLAY);
244     }
245 
246     @Test
testStartUser_background()247     public void testStartUser_background() {
248         boolean started = mUserController.startUser(TEST_USER_ID, USER_START_MODE_BACKGROUND);
249         assertWithMessage("startUser(%s, foreground=false)", TEST_USER_ID).that(started).isTrue();
250         verify(mInjector, never()).showUserSwitchingDialog(
251                 any(), any(), anyString(), anyString(), any());
252         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
253         verify(mInjector, never()).clearAllLockedTasks(anyString());
254         startBackgroundUserAssertions();
255         verifyUserAssignedToDisplay(TEST_USER_ID, Display.DEFAULT_DISPLAY);
256     }
257 
258     @Test
testStartUser_background_duringBootHsum()259     public void testStartUser_background_duringBootHsum() {
260         mockIsHeadlessSystemUserMode(true);
261         mUserController.setAllowUserUnlocking(false);
262         mInjector.mRelevantUser = TEST_USER_ID;
263         boolean started = mUserController.startUser(TEST_USER_ID, USER_START_MODE_BACKGROUND);
264         assertWithMessage("startUser(%s, foreground=false)", TEST_USER_ID).that(started).isTrue();
265 
266         // ACTION_LOCKED_BOOT_COMPLETED not sent yet
267         startUserAssertions(newArrayList(Intent.ACTION_USER_STARTED, Intent.ACTION_USER_STARTING),
268                 START_BACKGROUND_USER_MESSAGE_CODES);
269 
270         mUserController.onBootComplete(null);
271 
272         startUserAssertions(newArrayList(Intent.ACTION_USER_STARTED, Intent.ACTION_USER_STARTING,
273                         Intent.ACTION_LOCKED_BOOT_COMPLETED),
274                 START_BACKGROUND_USER_MESSAGE_CODES);
275     }
276 
277     @Test
testStartUser_sendsNoBroadcastsForSystemUserInNonHeadlessMode()278     public void testStartUser_sendsNoBroadcastsForSystemUserInNonHeadlessMode() {
279         setUpUser(SYSTEM_USER_ID, UserInfo.FLAG_SYSTEM, /* preCreated= */ false,
280                 UserManager.USER_TYPE_FULL_SYSTEM);
281         mockIsHeadlessSystemUserMode(false);
282 
283         mUserController.startUser(SYSTEM_USER_ID, USER_START_MODE_FOREGROUND);
284 
285         assertWithMessage("Broadcasts for starting the system user in non-headless mode")
286                 .that(mInjector.mSentIntents).isEmpty();
287     }
288 
289     @Test
testStartUser_sendsBroadcastsForSystemUserInHeadlessMode()290     public void testStartUser_sendsBroadcastsForSystemUserInHeadlessMode() {
291         setUpUser(SYSTEM_USER_ID, UserInfo.FLAG_SYSTEM, /* preCreated= */ false,
292                 UserManager.USER_TYPE_SYSTEM_HEADLESS);
293         mockIsHeadlessSystemUserMode(true);
294 
295         mUserController.startUser(SYSTEM_USER_ID, USER_START_MODE_FOREGROUND);
296 
297         assertWithMessage("Broadcasts for starting the system user in headless mode")
298                 .that(getActions(mInjector.mSentIntents)).containsExactly(
299                         Intent.ACTION_USER_STARTED, Intent.ACTION_USER_STARTING);
300     }
301 
302     @Test
testStartUser_displayAssignmentFailed()303     public void testStartUser_displayAssignmentFailed() {
304         doReturn(UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE)
305                 .when(mInjector.mUserManagerInternalMock)
306                 .assignUserToDisplayOnStart(eq(TEST_USER_ID), anyInt(),
307                         eq(USER_START_MODE_FOREGROUND), anyInt());
308 
309         boolean started = mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
310 
311         assertWithMessage("startUser(%s, foreground=true)", TEST_USER_ID).that(started).isFalse();
312     }
313 
314     @Test
testStartUserVisibleOnDisplay()315     public void testStartUserVisibleOnDisplay() {
316         boolean started = mUserController.startUserVisibleOnDisplay(TEST_USER_ID, 42,
317                 /* unlockProgressListener= */ null);
318 
319         assertWithMessage("startUserOnDisplay(%s, %s)", TEST_USER_ID, 42).that(started).isTrue();
320         verifyUserAssignedToDisplay(TEST_USER_ID, 42);
321 
322         verify(mInjector, never()).showUserSwitchingDialog(
323                 any(), any(), anyString(), anyString(), any());
324         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
325         verify(mInjector, never()).clearAllLockedTasks(anyString());
326         startBackgroundUserAssertions();
327     }
328 
329     @Test
testStartUserUIDisabled()330     public void testStartUserUIDisabled() {
331         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false,
332                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
333                 /* backgroundUserScheduledStopTimeSecs= */ -1);
334 
335         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
336         verify(mInjector, never()).showUserSwitchingDialog(
337                 any(), any(), anyString(), anyString(), any());
338         verify(mInjector, never()).dismissUserSwitchingDialog(any());
339         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
340         startForegroundUserAssertions();
341     }
342 
343     @Test
testStartPreCreatedUser_foreground()344     public void testStartPreCreatedUser_foreground() {
345         assertFalse(
346                 mUserController.startUser(TEST_PRE_CREATED_USER_ID, USER_START_MODE_FOREGROUND));
347         // Make sure no intents have been fired for pre-created users.
348         assertTrue(mInjector.mSentIntents.isEmpty());
349 
350         verifyUserNeverAssignedToDisplay();
351     }
352 
353     @Test
testStartPreCreatedUser_background()354     public void testStartPreCreatedUser_background() throws Exception {
355         assertTrue(mUserController.startUser(TEST_PRE_CREATED_USER_ID, USER_START_MODE_BACKGROUND));
356         // Make sure no intents have been fired for pre-created users.
357         assertTrue(mInjector.mSentIntents.isEmpty());
358 
359         verify(mInjector, never()).showUserSwitchingDialog(
360                 any(), any(), anyString(), anyString(), any());
361         verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
362         verify(mInjector, never()).clearAllLockedTasks(anyString());
363 
364         assertWithMessage("should not have received intents")
365                 .that(getActions(mInjector.mSentIntents)).isEmpty();
366         // TODO(b/140868593): should have received a USER_UNLOCK_MSG message as well, but it doesn't
367         // because StorageManager.isCeStorageUnlocked(TEST_PRE_CREATED_USER_ID) returns false - to
368         // properly fix it, we'd need to move this class to FrameworksMockingServicesTests so we can
369         // mock static methods (but moving this class would involve changing the presubmit tests,
370         // and the cascade effect goes on...). In fact, a better approach would to not assert the
371         // binder calls, but their side effects (in this case, that the user is stopped right away)
372         assertWithMessage("wrong binder message calls").that(mInjector.mHandler.getMessageCodes())
373                 .containsExactly(USER_START_MSG);
374     }
375 
startUserAssertions( List<String> expectedActions, Set<Integer> expectedMessageCodes)376     private void startUserAssertions(
377             List<String> expectedActions, Set<Integer> expectedMessageCodes) {
378         assertEquals(expectedActions, getActions(mInjector.mSentIntents));
379         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
380         assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes);
381     }
382 
startBackgroundUserAssertions()383     private void startBackgroundUserAssertions() {
384         startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES);
385     }
386 
startForegroundUserAssertions()387     private void startForegroundUserAssertions() {
388         startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES);
389         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
390         assertNotNull(reportMsg);
391         UserState userState = (UserState) reportMsg.obj;
392         assertNotNull(userState);
393         assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
394         assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
395         assertEquals("Unexpected old user id", 0, reportMsg.arg1);
396         assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2);
397         verifyUserAssignedToDisplay(TEST_USER_ID, Display.DEFAULT_DISPLAY);
398     }
399 
400     @Test
testFailedStartUserInForeground()401     public void testFailedStartUserInForeground() {
402         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false,
403                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
404                 /* backgroundUserScheduledStopTimeSecs= */ -1);
405 
406         mUserController.startUserInForeground(NONEXIST_USER_ID);
407         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
408         verify(mInjector.getWindowManager()).setSwitchingUser(false);
409 
410         verifyUserNeverAssignedToDisplay();
411     }
412 
413     @Test
testDispatchUserSwitch()414     public void testDispatchUserSwitch() throws RemoteException {
415         // Prepare mock observer and register it
416         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
417         when(observer.asBinder()).thenReturn(new Binder());
418         doAnswer(invocation -> {
419             IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
420             callback.sendResult(null);
421             return null;
422         }).when(observer).onUserSwitching(anyInt(), any());
423         mUserController.registerUserSwitchObserver(observer, "mock");
424         // Start user -- this will update state of mUserController
425         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
426         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
427         assertNotNull(reportMsg);
428         UserState userState = (UserState) reportMsg.obj;
429         int oldUserId = reportMsg.arg1;
430         int newUserId = reportMsg.arg2;
431         // Call dispatchUserSwitch and verify that observer was called only once
432         mInjector.mHandler.clearAllRecordedMessages();
433         mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
434         verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID));
435         verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
436         Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG);
437         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
438         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
439         Message conMsg = mInjector.mHandler.getMessageForCode(CONTINUE_USER_SWITCH_MSG);
440         assertNotNull(conMsg);
441         userState = (UserState) conMsg.obj;
442         assertNotNull(userState);
443         assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
444         assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
445         assertEquals("Unexpected old user id", 0, conMsg.arg1);
446         assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2);
447     }
448 
449     @Test
testDispatchUserSwitchBadReceiver()450     public void testDispatchUserSwitchBadReceiver() throws RemoteException {
451         // Prepare mock observer which doesn't notify the callback and register it
452         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
453         when(observer.asBinder()).thenReturn(new Binder());
454         mUserController.registerUserSwitchObserver(observer, "mock");
455         // Start user -- this will update state of mUserController
456         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
457         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
458         assertNotNull(reportMsg);
459         UserState userState = (UserState) reportMsg.obj;
460         int oldUserId = reportMsg.arg1;
461         int newUserId = reportMsg.arg2;
462         // Call dispatchUserSwitch and verify that observer was called only once
463         mInjector.mHandler.clearAllRecordedMessages();
464         mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
465         verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID));
466         verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
467         // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout)
468         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
469         assertWithMessage("No messages should be sent").that(actualCodes).isEmpty();
470     }
471 
continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId)472     private void continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId) {
473         mUserController.continueUserSwitch(userState, oldUserId, newUserId);
474         mInjector.mHandler.removeMessages(UserController.COMPLETE_USER_SWITCH_MSG);
475         mUserController.completeUserSwitch(oldUserId, newUserId);
476     }
477 
478     @Test
testContinueUserSwitch()479     public void testContinueUserSwitch() {
480         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
481                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
482                 /* backgroundUserScheduledStopTimeSecs= */ -1);
483         // Start user -- this will update state of mUserController
484         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
485         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
486         assertNotNull(reportMsg);
487         UserState userState = (UserState) reportMsg.obj;
488         int oldUserId = reportMsg.arg1;
489         int newUserId = reportMsg.arg2;
490         mInjector.mHandler.clearAllRecordedMessages();
491         // Verify that continueUserSwitch worked as expected
492         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
493         verify(mInjector, times(0)).dismissKeyguard(any());
494         verify(mInjector, times(1)).dismissUserSwitchingDialog(any());
495         continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false, false);
496         verifySystemUserVisibilityChangesNeverNotified();
497     }
498 
499     @Test
testContinueUserSwitchDismissKeyguard()500     public void testContinueUserSwitchDismissKeyguard() {
501         when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(false);
502         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
503                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
504                 /* backgroundUserScheduledStopTimeSecs= */ -1);
505         // Start user -- this will update state of mUserController
506         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
507         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
508         assertNotNull(reportMsg);
509         UserState userState = (UserState) reportMsg.obj;
510         int oldUserId = reportMsg.arg1;
511         int newUserId = reportMsg.arg2;
512         mInjector.mHandler.clearAllRecordedMessages();
513         // Verify that continueUserSwitch worked as expected
514         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
515         verify(mInjector, times(1)).dismissKeyguard(any());
516         verify(mInjector, times(1)).dismissUserSwitchingDialog(any());
517         continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false, false);
518         verifySystemUserVisibilityChangesNeverNotified();
519     }
520 
521     @Test
testContinueUserSwitchUIDisabled()522     public void testContinueUserSwitchUIDisabled() {
523         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false,
524                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
525                 /* backgroundUserScheduledStopTimeSecs= */ -1);
526 
527         // Start user -- this will update state of mUserController
528         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
529         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
530         assertNotNull(reportMsg);
531         UserState userState = (UserState) reportMsg.obj;
532         int oldUserId = reportMsg.arg1;
533         int newUserId = reportMsg.arg2;
534         mInjector.mHandler.clearAllRecordedMessages();
535         // Verify that continueUserSwitch worked as expected
536         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
537         verify(mInjector, never()).dismissUserSwitchingDialog(any());
538         continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false, false);
539     }
540 
continueUserSwitchAssertions(int expectedOldUserId, int expectedNewUserId, boolean backgroundUserStopping, boolean expectScheduleBackgroundUserStopping)541     private void continueUserSwitchAssertions(int expectedOldUserId, int expectedNewUserId,
542             boolean backgroundUserStopping, boolean expectScheduleBackgroundUserStopping) {
543         Set<Integer> expectedCodes = new LinkedHashSet<>();
544         expectedCodes.add(COMPLETE_USER_SWITCH_MSG);
545         expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG);
546         if (backgroundUserStopping) {
547             expectedCodes.add(CLEAR_USER_JOURNEY_SESSION_MSG);
548         }
549         if (expectScheduleBackgroundUserStopping) {
550             expectedCodes.add(SCHEDULED_STOP_BACKGROUND_USER_MSG);
551         }
552         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
553         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
554         Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG);
555         assertNotNull(msg);
556         assertEquals("Unexpected oldUserId", expectedOldUserId, msg.arg1);
557         assertEquals("Unexpected newUserId", expectedNewUserId, msg.arg2);
558     }
559 
560     @Test
testDispatchUserSwitchComplete()561     public void testDispatchUserSwitchComplete() throws RemoteException {
562         // Prepare mock observer and register it
563         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
564         when(observer.asBinder()).thenReturn(new Binder());
565         mUserController.registerUserSwitchObserver(observer, "mock");
566         // Start user -- this will update state of mUserController
567         mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
568         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
569         assertNotNull(reportMsg);
570         int oldUserId = reportMsg.arg1;
571         int newUserId = reportMsg.arg2;
572         mInjector.mHandler.clearAllRecordedMessages();
573         // Mockito can't reset only interactions, so just verify that this hasn't been
574         // called with 'false' until after dispatchUserSwitchComplete.
575         verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
576         // Call dispatchUserSwitchComplete
577         mUserController.dispatchUserSwitchComplete(oldUserId, newUserId);
578         verify(observer, times(1)).onUserSwitchComplete(anyInt());
579         verify(observer).onUserSwitchComplete(TEST_USER_ID);
580         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
581         startUserAssertions(Stream.concat(
582                         START_FOREGROUND_USER_ACTIONS.stream(),
583                         START_FOREGROUND_USER_DEFERRED_ACTIONS.stream()
584                 ).collect(Collectors.toList()), Collections.emptySet());
585     }
586 
587     /** Test scheduling stopping of background users after a user-switch. */
588     @Test
testScheduleStopOfBackgroundUser_switch()589     public void testScheduleStopOfBackgroundUser_switch() {
590         mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_SCHEDULE_STOP_OF_BACKGROUND_USER);
591 
592         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
593                 /* maxRunningUsers= */ 10, /* delayUserDataLocking= */ false,
594                 /* backgroundUserScheduledStopTimeSecs= */ 2);
595 
596         setUpUser(TEST_USER_ID1, NO_USERINFO_FLAGS);
597 
598         // Switch to TEST_USER_ID from user 0
599         int numberOfUserSwitches = 0;
600         addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
601                 ++numberOfUserSwitches,
602                 /* expectOldUserStopping= */false,
603                 /* expectScheduleBackgroundUserStopping= */ false);
604         assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID),
605                 mUserController.getRunningUsersLU());
606 
607         // Allow the post-switch processing to complete (there should be no scheduled stopping).
608         assertAndProcessScheduledStopBackgroundUser(false, null);
609         assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID),
610                 mUserController.getRunningUsersLU());
611 
612         // Switch to TEST_USER_ID1 from TEST_USER_ID
613         addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
614                 ++numberOfUserSwitches,
615                 /* expectOldUserStopping= */false,
616                 /* expectScheduleBackgroundUserStopping= */ true);
617         assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID, TEST_USER_ID1),
618                 mUserController.getRunningUsersLU());
619 
620         // Switch back to TEST_USER_ID from TEST_USER_ID1
621         addForegroundUserAndContinueUserSwitch(TEST_USER_ID, TEST_USER_ID1,
622                 ++numberOfUserSwitches,
623                 /* expectOldUserStopping= */false,
624                 /* expectScheduleBackgroundUserStopping= */ true);
625         assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID1, TEST_USER_ID),
626                 mUserController.getRunningUsersLU());
627 
628         // Allow the post-switch processing to complete.
629         assertAndProcessScheduledStopBackgroundUser(false, TEST_USER_ID);
630         assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID1);
631         assertAndProcessScheduledStopBackgroundUser(false, null);
632         assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID),
633                 mUserController.getRunningUsersLU());
634     }
635 
636     /** Test scheduling stopping of background users that were started in the background. */
637     @Test
testScheduleStopOfBackgroundUser_startInBackground()638     public void testScheduleStopOfBackgroundUser_startInBackground() throws Exception {
639         mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_SCHEDULE_STOP_OF_BACKGROUND_USER);
640 
641         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
642                 /* maxRunningUsers= */ 10, /* delayUserDataLocking= */ false,
643                 /* backgroundUserScheduledStopTimeSecs= */ 2);
644 
645         // Start two full background users (which should both get scheduled for stopping)
646         // and one profile (which should not).
647         setUpAndStartUserInBackground(TEST_USER_ID);
648         setUpAndStartUserInBackground(TEST_USER_ID1);
649         setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_MANAGED);
650 
651         assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID, TEST_USER_ID1, TEST_USER_ID2),
652                 new HashSet<>(mUserController.getRunningUsersLU()));
653 
654         assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID);
655         assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID1, TEST_USER_ID2),
656                 new HashSet<>(mUserController.getRunningUsersLU()));
657 
658         assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID1);
659         assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID2),
660                 new HashSet<>(mUserController.getRunningUsersLU()));
661 
662         assertAndProcessScheduledStopBackgroundUser(false, TEST_USER_ID2);
663         assertAndProcessScheduledStopBackgroundUser(false, null);
664 
665         // Now that we've processed the stops, let's make sure that a subsequent one will work too.
666         setUpAndStartUserInBackground(TEST_USER_ID3);
667         assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID2, TEST_USER_ID3),
668                 new HashSet<>(mUserController.getRunningUsersLU()));
669         assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID3);
670         assertAndProcessScheduledStopBackgroundUser(false, null);
671         assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID2),
672                 new HashSet<>(mUserController.getRunningUsersLU()));
673     }
674 
675     /**
676      * Process queued SCHEDULED_STOP_BACKGROUND_USER_MSG message, if expected.
677      * @param userId the user we are checking to see whether it is scheduled.
678      *               Can be null, when expectScheduled is false, to indicate no user should be
679      *               scheduled.
680      */
assertAndProcessScheduledStopBackgroundUser( boolean expectScheduled, @Nullable Integer userId)681     private void assertAndProcessScheduledStopBackgroundUser(
682             boolean expectScheduled, @Nullable Integer userId) {
683         TestHandler handler = mInjector.mHandler;
684         if (expectScheduled) {
685             assertTrue(handler.hasMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId));
686             handler.removeMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId);
687             mUserController.processScheduledStopOfBackgroundUser(userId);
688         } else {
689             assertFalse(handler.hasMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId));
690         }
691     }
692 
693     @Test
testExplicitSystemUserStartInBackground()694     public void testExplicitSystemUserStartInBackground() {
695         setUpUser(UserHandle.USER_SYSTEM, 0);
696         assertFalse(mUserController.isSystemUserStarted());
697         assertTrue(mUserController.startUser(UserHandle.USER_SYSTEM, USER_START_MODE_BACKGROUND,
698                 null));
699         assertTrue(mUserController.isSystemUserStarted());
700     }
701 
702     /**
703      * Test stopping of user from max running users limit.
704      */
705     @Test
testUserLockingFromUserSwitchingForMultipleUsersNonDelayedLocking()706     public void testUserLockingFromUserSwitchingForMultipleUsersNonDelayedLocking()
707             throws InterruptedException, RemoteException {
708         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
709                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
710                 /* backgroundUserScheduledStopTimeSecs= */ -1);
711 
712         setUpUser(TEST_USER_ID1, 0);
713         setUpUser(TEST_USER_ID2, 0);
714         int numberOfUserSwitches = 1;
715         addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
716                 numberOfUserSwitches, false, false);
717         // running: user 0, USER_ID
718         assertTrue(mUserController.canStartMoreUsers());
719         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}),
720                 mUserController.getRunningUsersLU());
721 
722         numberOfUserSwitches++;
723         addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
724                 numberOfUserSwitches, false, false);
725         // running: user 0, USER_ID, USER_ID1
726         assertFalse(mUserController.canStartMoreUsers());
727         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID, TEST_USER_ID1}),
728                 mUserController.getRunningUsersLU());
729 
730         numberOfUserSwitches++;
731         addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1,
732                 numberOfUserSwitches, false, false);
733         UserState ussUser2 = mUserStates.get(TEST_USER_ID2);
734         // skip middle step and call this directly.
735         mUserController.finishUserSwitch(ussUser2);
736         waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
737         // running: user 0, USER_ID1, USER_ID2
738         // USER_ID should be stopped as it is least recently used non user0.
739         assertFalse(mUserController.canStartMoreUsers());
740         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1, TEST_USER_ID2}),
741                 mUserController.getRunningUsersLU());
742         verifySystemUserVisibilityChangesNeverNotified();
743     }
744 
745     /**
746      * This test tests delayed locking mode using 4 users. As core logic of delayed locking is
747      * happening in finishUserStopped call, the test also calls finishUserStopped while skipping
748      * all middle steps which takes too much work to mock.
749      */
750     @Test
testUserLockingFromUserSwitchingForMultipleUsersDelayedLockingMode()751     public void testUserLockingFromUserSwitchingForMultipleUsersDelayedLockingMode()
752             throws Exception {
753         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
754                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ true,
755                 /* backgroundUserScheduledStopTimeSecs= */ -1);
756 
757         setUpUser(TEST_USER_ID1, 0);
758         setUpUser(TEST_USER_ID2, 0);
759         int numberOfUserSwitches = 1;
760         addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
761                 numberOfUserSwitches, false, false);
762         // running: user 0, USER_ID
763         assertTrue(mUserController.canStartMoreUsers());
764         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}),
765                 mUserController.getRunningUsersLU());
766         numberOfUserSwitches++;
767 
768         addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
769                 numberOfUserSwitches, true, false);
770         // running: user 0, USER_ID1
771         // stopped + unlocked: USER_ID
772         numberOfUserSwitches++;
773         assertTrue(mUserController.canStartMoreUsers());
774         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1}),
775                 mUserController.getRunningUsersLU());
776         // Skip all other steps and test unlock delaying only
777         UserState uss = mUserStates.get(TEST_USER_ID);
778         uss.setState(UserState.STATE_SHUTDOWN); // necessary state change from skipped part
779         mUserController.finishUserStopped(uss, /* allowDelayedLocking= */ true);
780         // Cannot mock FgThread handler, so confirm that there is no posted message left before
781         // checking.
782         waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
783         verify(mInjector.mStorageManagerMock, times(0))
784                 .lockCeStorage(anyInt());
785 
786         addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1,
787                 numberOfUserSwitches, true, false);
788         // running: user 0, USER_ID2
789         // stopped + unlocked: USER_ID1
790         // stopped + locked: USER_ID
791         assertTrue(mUserController.canStartMoreUsers());
792         assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID2}),
793                 mUserController.getRunningUsersLU());
794         UserState ussUser1 = mUserStates.get(TEST_USER_ID1);
795         ussUser1.setState(UserState.STATE_SHUTDOWN);
796         mUserController.finishUserStopped(ussUser1, /* allowDelayedLocking= */ true);
797         waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
798         verify(mInjector.mStorageManagerMock, times(1))
799                 .lockCeStorage(TEST_USER_ID);
800     }
801 
802     /**
803      * Test that, when exceeding the maximum number of running users, a profile of the current user
804      * is not stopped.
805      */
806     @Test
testStoppingExcessRunningUsersAfterSwitch_currentProfileNotStopped()807     public void testStoppingExcessRunningUsersAfterSwitch_currentProfileNotStopped()
808             throws Exception {
809         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
810                 /* maxRunningUsers= */ 5, /* delayUserDataLocking= */ false,
811                 /* backgroundUserScheduledStopTimeSecs= */ -1);
812 
813         final int PARENT_ID = 200;
814         final int PROFILE1_ID = 201;
815         final int PROFILE2_ID = 202;
816         final int FG_USER_ID = 300;
817         final int BG_USER_ID = 400;
818 
819         setUpUser(PARENT_ID, 0).profileGroupId = PARENT_ID;
820         setUpUser(PROFILE1_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
821         setUpUser(PROFILE2_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
822         setUpUser(FG_USER_ID, 0).profileGroupId = FG_USER_ID;
823         setUpUser(BG_USER_ID, 0).profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
824         mUserController.onSystemReady(); // To set the profileGroupIds in UserController.
825 
826         assertEquals(newHashSet(
827                 SYSTEM_USER_ID),
828                 new HashSet<>(mUserController.getRunningUsersLU()));
829 
830         int numberOfUserSwitches = 1;
831         addForegroundUserAndContinueUserSwitch(PARENT_ID, UserHandle.USER_SYSTEM,
832                 numberOfUserSwitches, false, false);
833         mUserController.finishUserSwitch(mUserStates.get(PARENT_ID));
834         waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
835         assertTrue(mUserController.canStartMoreUsers());
836         assertEquals(newHashSet(
837                 SYSTEM_USER_ID, PARENT_ID),
838                 new HashSet<>(mUserController.getRunningUsersLU()));
839 
840         assertThat(mUserController.startProfile(PROFILE1_ID, true, null)).isTrue();
841         assertEquals(newHashSet(
842                 SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID),
843                 new HashSet<>(mUserController.getRunningUsersLU()));
844 
845         numberOfUserSwitches++;
846         addForegroundUserAndContinueUserSwitch(FG_USER_ID, PARENT_ID,
847                 numberOfUserSwitches, false, false);
848         mUserController.finishUserSwitch(mUserStates.get(FG_USER_ID));
849         waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
850         assertTrue(mUserController.canStartMoreUsers());
851         assertEquals(newHashSet(
852                 SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID, FG_USER_ID),
853                 new HashSet<>(mUserController.getRunningUsersLU()));
854 
855         mUserController.startUser(BG_USER_ID, USER_START_MODE_BACKGROUND);
856         assertEquals(newHashSet(
857                 SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID, BG_USER_ID, FG_USER_ID),
858                 new HashSet<>(mUserController.getRunningUsersLU()));
859 
860         // Now we exceed the maxRunningUsers parameter (of 5):
861         assertThat(mUserController.startProfile(PROFILE2_ID, true, null)).isTrue();
862         // Currently, starting a profile doesn't trigger evaluating whether we've exceeded max, so
863         // we expect no users to be stopped. This policy may change in the future. Log but no fail.
864         if (!newHashSet(SYSTEM_USER_ID, PROFILE1_ID, BG_USER_ID, PROFILE2_ID, PARENT_ID, FG_USER_ID)
865                 .equals(new HashSet<>(mUserController.getRunningUsersLU()))) {
866             Log.w(TAG, "Starting a profile that exceeded max running users didn't lead to "
867                     + "expectations: " + mUserController.getRunningUsersLU());
868         }
869 
870         numberOfUserSwitches++;
871         addForegroundUserAndContinueUserSwitch(PARENT_ID, FG_USER_ID,
872                 numberOfUserSwitches, false, false);
873         mUserController.finishUserSwitch(mUserStates.get(PARENT_ID));
874         waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
875         // We've now done a user switch and should notice that we've exceeded the maximum number of
876         // users. The oldest background user should be stopped (BG_USER); even though PROFILE1 was
877         // older, it should not be stopped since it's a profile of the (new) current user.
878         assertFalse(mUserController.canStartMoreUsers());
879         assertEquals(newHashSet(
880                 SYSTEM_USER_ID, PROFILE1_ID, PROFILE2_ID, FG_USER_ID, PARENT_ID),
881                 new HashSet<>(mUserController.getRunningUsersLU()));
882     }
883 
884     /**
885      * Test that, in getRunningUsersLU, parents come after their profile, even if the profile was
886      * started afterwards.
887      */
888     @Test
testRunningUsersListOrder_parentAfterProfile()889     public void testRunningUsersListOrder_parentAfterProfile() {
890         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
891                 /* maxRunningUsers= */ 7, /* delayUserDataLocking= */ false,
892                 /* backgroundUserScheduledStopTimeSecs= */ -1);
893 
894         final int PARENT_ID = 200;
895         final int PROFILE1_ID = 201;
896         final int PROFILE2_ID = 202;
897         final int FG_USER_ID = 300;
898         final int BG_USER_ID = 400;
899 
900         setUpUser(PARENT_ID, 0).profileGroupId = PARENT_ID;
901         setUpUser(PROFILE1_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
902         setUpUser(PROFILE2_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
903         setUpUser(FG_USER_ID, 0).profileGroupId = FG_USER_ID;
904         setUpUser(BG_USER_ID, 0).profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
905         mUserController.onSystemReady(); // To set the profileGroupIds in UserController.
906 
907         assertEquals(Arrays.asList(
908                 new Integer[] {SYSTEM_USER_ID}),
909                 mUserController.getRunningUsersLU());
910 
911         int numberOfUserSwitches = 1;
912         addForegroundUserAndContinueUserSwitch(PARENT_ID, UserHandle.USER_SYSTEM,
913                 numberOfUserSwitches, false, false);
914         assertEquals(Arrays.asList(
915                 new Integer[] {SYSTEM_USER_ID, PARENT_ID}),
916                 mUserController.getRunningUsersLU());
917 
918         assertThat(mUserController.startProfile(PROFILE1_ID, true, null)).isTrue();
919         assertEquals(Arrays.asList(
920                 new Integer[] {SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID}),
921                 mUserController.getRunningUsersLU());
922 
923         numberOfUserSwitches++;
924         addForegroundUserAndContinueUserSwitch(FG_USER_ID, PARENT_ID,
925                 numberOfUserSwitches, false, false);
926         assertEquals(Arrays.asList(
927                 new Integer[] {SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID, FG_USER_ID}),
928                 mUserController.getRunningUsersLU());
929 
930         mUserController.startUser(BG_USER_ID, USER_START_MODE_BACKGROUND);
931         assertEquals(Arrays.asList(
932                 new Integer[] {SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID, BG_USER_ID, FG_USER_ID}),
933                 mUserController.getRunningUsersLU());
934 
935         assertThat(mUserController.startProfile(PROFILE2_ID, true, null)).isTrue();
936         // Note for the future:
937         // It is not absolutely essential that PROFILE1 come before PROFILE2,
938         // nor that PROFILE1 come before BG_USER. We can change that policy later if we'd like.
939         // The important thing is that PROFILE1 and PROFILE2 precede PARENT,
940         // and that everything precedes OTHER.
941         assertEquals(Arrays.asList(new Integer[] {
942                 SYSTEM_USER_ID, PROFILE1_ID, BG_USER_ID, PROFILE2_ID, PARENT_ID, FG_USER_ID}),
943                 mUserController.getRunningUsersLU());
944     }
945 
946     /**
947      * Test that, in getRunningUsersLU, the current user is always at the end, even if background
948      * users were started subsequently.
949      */
950     @Test
testRunningUsersListOrder_currentAtEnd()951     public void testRunningUsersListOrder_currentAtEnd() {
952         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
953                 /* maxRunningUsers= */ 7, /* delayUserDataLocking= */ false,
954                 /* backgroundUserScheduledStopTimeSecs= */ -1);
955 
956         final int CURRENT_ID = 200;
957         final int PROFILE_ID = 201;
958         final int BG_USER_ID = 400;
959 
960         setUpUser(CURRENT_ID, 0).profileGroupId = CURRENT_ID;
961         setUpUser(PROFILE_ID, UserInfo.FLAG_PROFILE).profileGroupId = CURRENT_ID;
962         setUpUser(BG_USER_ID, 0).profileGroupId = BG_USER_ID;
963         mUserController.onSystemReady(); // To set the profileGroupIds in UserController.
964 
965         assertEquals(Arrays.asList(
966                 new Integer[] {SYSTEM_USER_ID}),
967                 mUserController.getRunningUsersLU());
968 
969         addForegroundUserAndContinueUserSwitch(CURRENT_ID, UserHandle.USER_SYSTEM, 1, false, false);
970         assertEquals(Arrays.asList(
971                 new Integer[] {SYSTEM_USER_ID, CURRENT_ID}),
972                 mUserController.getRunningUsersLU());
973 
974         mUserController.startUser(BG_USER_ID, USER_START_MODE_BACKGROUND);
975         assertEquals(Arrays.asList(
976                 new Integer[] {SYSTEM_USER_ID, BG_USER_ID, CURRENT_ID}),
977                 mUserController.getRunningUsersLU());
978 
979         assertThat(mUserController.startProfile(PROFILE_ID, true, null)).isTrue();
980         assertEquals(Arrays.asList(
981                 new Integer[] {SYSTEM_USER_ID, BG_USER_ID, PROFILE_ID, CURRENT_ID}),
982                 mUserController.getRunningUsersLU());
983     }
984 
985     /**
986      * Test locking user with mDelayUserDataLocking false.
987      */
988     @Test
testUserLockingWithStopUserForNonDelayedLockingMode()989     public void testUserLockingWithStopUserForNonDelayedLockingMode() throws Exception {
990         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
991                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
992                 /* backgroundUserScheduledStopTimeSecs= */ -1);
993 
994         setUpAndStartUserInBackground(TEST_USER_ID);
995         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* allowDelayedLocking= */ true,
996                 /* keyEvictedCallback= */ null, /* expectLocking= */ true);
997 
998         setUpAndStartUserInBackground(TEST_USER_ID1);
999         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true,
1000                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
1001 
1002         setUpAndStartUserInBackground(TEST_USER_ID2);
1003         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ false,
1004                 /* keyEvictedCallback= */ null, /* expectLocking= */ true);
1005 
1006         setUpAndStartUserInBackground(TEST_USER_ID3);
1007         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* allowDelayedLocking= */ false,
1008                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
1009     }
1010 
1011     @Test
testStopUser_invalidUser()1012     public void testStopUser_invalidUser() {
1013         int userId = -1;
1014 
1015         assertThrows(IllegalArgumentException.class,
1016                 () -> mUserController.stopUser(userId,
1017                         /* allowDelayedLocking= */ true, /* stopUserCallback= */ null,
1018                         /* keyEvictedCallback= */ null));
1019     }
1020 
1021     @Test
testStopUser_systemUser()1022     public void testStopUser_systemUser() {
1023         int userId = UserHandle.USER_SYSTEM;
1024 
1025         int r = mUserController.stopUser(userId,
1026                 /* allowDelayedLocking= */ true, /* stopUserCallback= */ null,
1027                 /* keyEvictedCallback= */ null);
1028 
1029         assertThat(r).isEqualTo(ActivityManager.USER_OP_ERROR_IS_SYSTEM);
1030     }
1031 
1032     @Test
testStopUser_currentUser()1033     public void testStopUser_currentUser() {
1034         setUpUser(TEST_USER_ID1, /* flags= */ 0);
1035         mUserController.startUser(TEST_USER_ID1, USER_START_MODE_FOREGROUND);
1036 
1037         int r = mUserController.stopUser(TEST_USER_ID1,
1038                 /* allowDelayedLocking= */ true, /* stopUserCallback= */ null,
1039                 /* keyEvictedCallback= */ null);
1040 
1041         assertThat(r).isEqualTo(ActivityManager.USER_OP_IS_CURRENT);
1042     }
1043 
1044     /**
1045      * Test conditional delayed locking with mDelayUserDataLocking true.
1046      */
1047     @Test
testUserLockingForDelayedLockingMode()1048     public void testUserLockingForDelayedLockingMode() throws Exception {
1049         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
1050                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ true,
1051                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1052 
1053         // allowDelayedLocking set and no KeyEvictedCallback, so it should not lock.
1054         setUpAndStartUserInBackground(TEST_USER_ID);
1055         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* allowDelayedLocking= */ true,
1056                 /* keyEvictedCallback= */ null, /* expectLocking= */ false);
1057 
1058         setUpAndStartUserInBackground(TEST_USER_ID1);
1059         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true,
1060                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
1061 
1062         setUpAndStartUserInBackground(TEST_USER_ID2);
1063         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ false,
1064                 /* keyEvictedCallback= */ null, /* expectLocking= */ true);
1065 
1066         setUpAndStartUserInBackground(TEST_USER_ID3);
1067         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* allowDelayedLocking= */ false,
1068                 /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true);
1069     }
1070 
1071     @Test
testUserNotUnlockedBeforeAllowed()1072     public void testUserNotUnlockedBeforeAllowed() throws Exception {
1073         mUserController.setAllowUserUnlocking(false);
1074 
1075         mUserController.startUser(TEST_USER_ID, USER_START_MODE_BACKGROUND);
1076 
1077         verify(mInjector.mStorageManagerMock, never()).unlockCeStorage(eq(TEST_USER_ID), any());
1078     }
1079 
1080     @Test
testStartProfile_fullUserFails()1081     public void testStartProfile_fullUserFails() {
1082         setUpUser(TEST_USER_ID1, 0);
1083         assertThrows(IllegalArgumentException.class,
1084                 () -> mUserController.startProfile(TEST_USER_ID1, /* evenWhenDisabled= */ false,
1085                         /* unlockListener= */ null));
1086 
1087         verifyUserNeverAssignedToDisplay();
1088     }
1089 
1090     @Test
testStopProfile_fullUserFails()1091     public void testStopProfile_fullUserFails() throws Exception {
1092         setUpAndStartUserInBackground(TEST_USER_ID1);
1093         assertThrows(IllegalArgumentException.class,
1094                 () -> mUserController.stopProfile(TEST_USER_ID1));
1095         verifyUserUnassignedFromDisplayNeverCalled(TEST_USER_ID);
1096     }
1097 
1098     /** Test that stopping a profile doesn't also stop its parent, even if it's in background. */
1099     @Test
testStopProfile_doesNotStopItsParent()1100     public void testStopProfile_doesNotStopItsParent() throws Exception {
1101         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
1102                 /* maxRunningUsers= */ 5, /* delayUserDataLocking= */ false,
1103                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1104 
1105         final Range<Integer> RUNNING_RANGE =
1106                 Range.closed(UserState.STATE_BOOTING, UserState.STATE_RUNNING_UNLOCKED);
1107 
1108         final int PARENT_ID = TEST_USER_ID1;
1109         final int PROFILE_ID = TEST_USER_ID2;
1110         final int OTHER_ID = TEST_USER_ID3;
1111 
1112         setUpUser(PARENT_ID, 0).profileGroupId = PARENT_ID;
1113         setUpUser(PROFILE_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
1114         setUpUser(OTHER_ID, 0).profileGroupId = OTHER_ID;
1115         mUserController.onSystemReady(); // To set the profileGroupIds in UserController.
1116 
1117         // Start the parent in the background
1118         boolean started = mUserController.startUser(PARENT_ID, USER_START_MODE_BACKGROUND);
1119         assertWithMessage("startUser(%s)", PARENT_ID).that(started).isTrue();
1120         assertThat(mUserController.getStartedUserState(PARENT_ID).state).isIn(RUNNING_RANGE);
1121 
1122         // Start the profile
1123         started = mUserController.startProfile(PROFILE_ID, true, null);
1124         assertWithMessage("startProfile(%s)", PROFILE_ID).that(started).isTrue();
1125         assertThat(mUserController.getStartedUserState(PARENT_ID).state).isIn(RUNNING_RANGE);
1126         assertThat(mUserController.getStartedUserState(PROFILE_ID).state).isIn(RUNNING_RANGE);
1127 
1128         // Start an unrelated user
1129         started = mUserController.startUser(OTHER_ID, USER_START_MODE_FOREGROUND);
1130         assertWithMessage("startUser(%s)", OTHER_ID).that(started).isTrue();
1131         assertThat(mUserController.getStartedUserState(PARENT_ID).state).isIn(RUNNING_RANGE);
1132         assertThat(mUserController.getStartedUserState(PROFILE_ID).state).isIn(RUNNING_RANGE);
1133         assertThat(mUserController.getStartedUserState(OTHER_ID).state).isIn(RUNNING_RANGE);
1134 
1135         // Stop the profile and assert that its (background) parent didn't stop too
1136         boolean stopped = mUserController.stopProfile(PROFILE_ID);
1137         assertWithMessage("stopProfile(%s)", PROFILE_ID).that(stopped).isTrue();
1138         if (mUserController.getStartedUserState(PROFILE_ID) != null) {
1139             assertThat(mUserController.getStartedUserState(PROFILE_ID).state)
1140                     .isNotIn(RUNNING_RANGE);
1141         }
1142         assertThat(mUserController.getStartedUserState(PARENT_ID).state).isIn(RUNNING_RANGE);
1143     }
1144 
1145     @Test
testStartProfile_disabledProfileFails()1146     public void testStartProfile_disabledProfileFails() {
1147         setUpUser(TEST_USER_ID1, UserInfo.FLAG_PROFILE | UserInfo.FLAG_DISABLED, /* preCreated= */
1148                 false, UserManager.USER_TYPE_PROFILE_MANAGED);
1149         assertThat(mUserController.startProfile(TEST_USER_ID1, /* evenWhenDisabled=*/ false,
1150                 /* unlockListener= */ null)).isFalse();
1151 
1152         verifyUserNeverAssignedToDisplay();
1153     }
1154 
1155     @Test
testStartManagedProfile()1156     public void testStartManagedProfile() throws Exception {
1157         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_MANAGED);
1158 
1159         startBackgroundUserAssertions();
1160         verifyUserAssignedToDisplay(TEST_USER_ID1, Display.DEFAULT_DISPLAY);
1161     }
1162 
1163     @Test
testStartManagedProfile_whenUsersOnSecondaryDisplaysIsEnabled()1164     public void testStartManagedProfile_whenUsersOnSecondaryDisplaysIsEnabled() throws Exception {
1165         mockIsUsersOnSecondaryDisplaysEnabled(true);
1166 
1167         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_MANAGED);
1168 
1169         startBackgroundUserAssertions();
1170         verifyUserAssignedToDisplay(TEST_USER_ID1, Display.DEFAULT_DISPLAY);
1171     }
1172 
1173     @Test
testStopManagedProfile()1174     public void testStopManagedProfile() throws Exception {
1175         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_MANAGED);
1176         assertProfileLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* expectLocking= */ true);
1177         verifyUserUnassignedFromDisplay(TEST_USER_ID1);
1178     }
1179 
1180     @Test
testStopPrivateProfile()1181     public void testStopPrivateProfile() throws Exception {
1182         mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true,
1183                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
1184                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1185         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1186                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE,
1187                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1188         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE);
1189         assertProfileLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* expectLocking= */ true);
1190         verifyUserUnassignedFromDisplay(TEST_USER_ID1);
1191 
1192         mSetFlagsRule.disableFlags(
1193                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE);
1194         setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_PRIVATE);
1195         assertProfileLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* expectLocking= */ true);
1196         verifyUserUnassignedFromDisplay(TEST_USER_ID2);
1197     }
1198 
1199     @Test
testStopPrivateProfileWithDelayedLocking()1200     public void testStopPrivateProfileWithDelayedLocking() throws Exception {
1201         mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true,
1202                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
1203                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1204         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1205                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE,
1206                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1207         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE);
1208         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true,
1209                 /* keyEvictedCallback */ null, /* expectLocking= */ false);
1210     }
1211 
1212     @Test
testStopPrivateProfileWithDelayedLocking_flagDisabled()1213     public void testStopPrivateProfileWithDelayedLocking_flagDisabled() throws Exception {
1214         mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true,
1215                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
1216                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1217         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1218                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1219         mSetFlagsRule.disableFlags(
1220                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE);
1221         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE);
1222         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true,
1223                 /* keyEvictedCallback */ null, /* expectLocking= */ true);
1224 
1225         mSetFlagsRule.disableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1226                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1227         mSetFlagsRule.enableFlags(
1228                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE);
1229         setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_PRIVATE);
1230         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ true,
1231                 /* keyEvictedCallback */ null, /* expectLocking= */ true);
1232 
1233         mSetFlagsRule.disableFlags(android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1234         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1235                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE);
1236         setUpAndStartProfileInBackground(TEST_USER_ID3, UserManager.USER_TYPE_PROFILE_PRIVATE);
1237         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ true,
1238                 /* keyEvictedCallback */ null, /* expectLocking= */ true);
1239     }
1240 
1241     /** Delayed-locking users (as opposed to devices) have no limits on how many can be unlocked. */
1242     @Test
testStopPrivateProfileWithDelayedLocking_imperviousToNumberOfRunningUsers()1243     public void testStopPrivateProfileWithDelayedLocking_imperviousToNumberOfRunningUsers()
1244             throws Exception {
1245         mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true,
1246                 /* maxRunningUsers= */ 1, /* delayUserDataLocking= */ false,
1247                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1248         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1249                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE,
1250                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1251         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE);
1252         setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_MANAGED);
1253         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true,
1254                 /* keyEvictedCallback */ null, /* expectLocking= */ false);
1255     }
1256 
1257     /**
1258         * Tests that when a device/user (managed profile) does not permit delayed locking, then
1259         * even if allowDelayedLocking is true, the user will still be locked.
1260     */
1261     @Test
testStopManagedProfileWithDelayedLocking()1262     public void testStopManagedProfileWithDelayedLocking() throws Exception {
1263         mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true,
1264                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
1265                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1266         mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
1267                 android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE,
1268                 android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
1269         setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_MANAGED);
1270         assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true,
1271                 /* keyEvictedCallback */ null, /* expectLocking= */ true);
1272     }
1273 
1274     /** Tests handleIncomingUser() for a variety of permissions and situations. */
1275     @Test
testHandleIncomingUser()1276     public void testHandleIncomingUser() throws Exception {
1277         final UserInfo user1a = new UserInfo(111, "user1a", 0);
1278         final UserInfo user1b = new UserInfo(112, "user1b", 0);
1279         final UserInfo user2 = new UserInfo(113, "user2", 0);
1280         // user1a and user2b are in the same profile group; user2 is in a different one.
1281         user1a.profileGroupId = 5;
1282         user1b.profileGroupId = 5;
1283         user2.profileGroupId = 6;
1284 
1285         final List<UserInfo> users = Arrays.asList(user1a, user1b, user2);
1286         when(mInjector.mUserManagerMock.getUsers(false)).thenReturn(users);
1287         mUserController.onSystemReady(); // To set the profileGroupIds in UserController.
1288 
1289 
1290         // Has INTERACT_ACROSS_USERS_FULL.
1291         when(mInjector.checkComponentPermission(
1292                 eq(INTERACT_ACROSS_USERS_FULL), anyInt(), anyInt(), anyInt(), anyBoolean()))
1293                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1294         when(mInjector.checkComponentPermission(
1295                 eq(INTERACT_ACROSS_USERS), anyInt(), anyInt(), anyInt(), anyBoolean()))
1296                 .thenReturn(PackageManager.PERMISSION_DENIED);
1297         when(mInjector.checkPermissionForPreflight(
1298                 eq(INTERACT_ACROSS_PROFILES), anyInt(), anyInt(), any())).thenReturn(false);
1299 
1300         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL, true);
1301         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL_IN_PROFILE, true);
1302         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_FULL_ONLY, true);
1303         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_PROFILES_OR_NON_FULL, true);
1304 
1305         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL, true);
1306         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL_IN_PROFILE, true);
1307         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_FULL_ONLY, true);
1308         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_PROFILES_OR_NON_FULL, true);
1309 
1310 
1311         // Has INTERACT_ACROSS_USERS.
1312         when(mInjector.checkComponentPermission(
1313                 eq(INTERACT_ACROSS_USERS_FULL), anyInt(), anyInt(), anyInt(), anyBoolean()))
1314                 .thenReturn(PackageManager.PERMISSION_DENIED);
1315         when(mInjector.checkComponentPermission(
1316                 eq(INTERACT_ACROSS_USERS), anyInt(), anyInt(), anyInt(), anyBoolean()))
1317                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1318         when(mInjector.checkPermissionForPreflight(
1319                 eq(INTERACT_ACROSS_PROFILES), anyInt(), anyInt(), any())).thenReturn(false);
1320 
1321         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL, true);
1322         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL_IN_PROFILE, false);
1323         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_FULL_ONLY, false);
1324         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_PROFILES_OR_NON_FULL, true);
1325 
1326         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL, true);
1327         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL_IN_PROFILE, true);
1328         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_FULL_ONLY, false);
1329         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_PROFILES_OR_NON_FULL, true);
1330 
1331 
1332         // Has INTERACT_ACROSS_PROFILES.
1333         when(mInjector.checkComponentPermission(
1334                 eq(INTERACT_ACROSS_USERS_FULL), anyInt(), anyInt(), anyInt(), anyBoolean()))
1335                 .thenReturn(PackageManager.PERMISSION_DENIED);
1336         when(mInjector.checkComponentPermission(
1337                 eq(INTERACT_ACROSS_USERS), anyInt(), anyInt(), anyInt(), anyBoolean()))
1338                 .thenReturn(PackageManager.PERMISSION_DENIED);
1339         when(mInjector.checkPermissionForPreflight(
1340                 eq(INTERACT_ACROSS_PROFILES), anyInt(), anyInt(), any())).thenReturn(true);
1341 
1342         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL, false);
1343         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_NON_FULL_IN_PROFILE, false);
1344         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_FULL_ONLY, false);
1345         checkHandleIncomingUser(user1a.id, user2.id, ALLOW_PROFILES_OR_NON_FULL, false);
1346 
1347         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL, false);
1348         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_NON_FULL_IN_PROFILE, false);
1349         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_FULL_ONLY, false);
1350         checkHandleIncomingUser(user1a.id, user1b.id, ALLOW_PROFILES_OR_NON_FULL, true);
1351     }
1352 
checkHandleIncomingUser(int fromUser, int toUser, int allowMode, boolean pass)1353     private void checkHandleIncomingUser(int fromUser, int toUser, int allowMode, boolean pass) {
1354         final int pid = 100;
1355         final int uid = fromUser * UserHandle.PER_USER_RANGE + 34567 + fromUser;
1356         final String name = "whatever";
1357         final String pkg = "some.package";
1358         final boolean allowAll = false;
1359 
1360         if (pass) {
1361             mUserController.handleIncomingUser(pid, uid, toUser, allowAll, allowMode, name, pkg);
1362         } else {
1363             assertThrows(SecurityException.class, () -> mUserController.handleIncomingUser(
1364                     pid, uid, toUser, allowAll, allowMode, name, pkg));
1365         }
1366     }
1367 
1368     @Test
testScheduleOnUserCompletedEvent()1369     public void testScheduleOnUserCompletedEvent() throws Exception {
1370         // user1 is starting, switching, and unlocked, but not scheduled unlocked yet
1371         // user2 is starting and had unlocked but isn't unlocked anymore for whatever reason
1372 
1373         final int user1 = 101;
1374         final int user2 = 102;
1375         setUpUser(user1, 0);
1376         setUpUser(user2, 0);
1377 
1378         mUserController.startUser(user1, USER_START_MODE_FOREGROUND);
1379         mUserController.getStartedUserState(user1).setState(UserState.STATE_RUNNING_UNLOCKED);
1380 
1381         mUserController.startUser(user2, USER_START_MODE_BACKGROUND);
1382         mUserController.getStartedUserState(user2).setState(UserState.STATE_RUNNING_LOCKED);
1383 
1384         final int event1a = SystemService.UserCompletedEventType.EVENT_TYPE_USER_STARTING;
1385         final int event1b = SystemService.UserCompletedEventType.EVENT_TYPE_USER_SWITCHING;
1386 
1387         final int event2a = SystemService.UserCompletedEventType.EVENT_TYPE_USER_STARTING;
1388         final int event2b = SystemService.UserCompletedEventType.EVENT_TYPE_USER_UNLOCKED;
1389 
1390 
1391         mUserController.scheduleOnUserCompletedEvent(user1, event1a, 2000);
1392         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user1));
1393         assertNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user2));
1394 
1395         mUserController.scheduleOnUserCompletedEvent(user2, event2a, 2000);
1396         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user1));
1397         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user2));
1398 
1399         mUserController.scheduleOnUserCompletedEvent(user2, event2b, 2000);
1400         mUserController.scheduleOnUserCompletedEvent(user1, event1b, 2000);
1401         mUserController.scheduleOnUserCompletedEvent(user1, 0, 2000);
1402 
1403         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user1));
1404         assertNotNull(mInjector.mHandler.getMessageForCode(USER_COMPLETED_EVENT_MSG, user2));
1405 
1406         mUserController.reportOnUserCompletedEvent(user1);
1407         verify(mInjector, times(1))
1408                 .systemServiceManagerOnUserCompletedEvent(eq(user1), eq(event1a | event1b));
1409         verify(mInjector, never()).systemServiceManagerOnUserCompletedEvent(eq(user2), anyInt());
1410 
1411         mUserController.reportOnUserCompletedEvent(user2);
1412         verify(mInjector, times(1))
1413                 .systemServiceManagerOnUserCompletedEvent(eq(user2), eq(event2a));
1414     }
1415 
1416     @Test
testStallUserSwitchUntilTheKeyguardIsShown()1417     public void testStallUserSwitchUntilTheKeyguardIsShown() throws Exception {
1418         // enable user switch ui, because keyguard is only shown then
1419         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
1420                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
1421                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1422 
1423         // mock the device to be secure in order to expect the keyguard to be shown
1424         when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
1425 
1426         // call real showKeyguard method for this test
1427         doCallRealMethod().when(mInjector).showKeyguard(any());
1428 
1429         mUserController.completeUserSwitch(TEST_USER_ID1, TEST_USER_ID2);
1430 
1431         // make sure the switch is stalled by checking the UserSwitchingDialog is not dismissed yet
1432         verify(mInjector, never()).dismissUserSwitchingDialog(any());
1433 
1434         // mock send the keyguard shown event
1435         ArgumentCaptor<ActivityTaskManagerInternal.ScreenObserver> captor = ArgumentCaptor.forClass(
1436                 ActivityTaskManagerInternal.ScreenObserver.class);
1437         verify(mInjector.mActivityTaskManagerInternal).registerScreenObserver(captor.capture());
1438         captor.getValue().onKeyguardStateChanged(true);
1439 
1440         // verify the switch now moves on by checking the UserSwitchingDialog is dismissed
1441         verify(mInjector, atLeastOnce()).dismissUserSwitchingDialog(any());
1442 
1443         // verify that SHOW_KEYGUARD_TIMEOUT is ignored and does not crash the system
1444         try {
1445             mInjector.mHandler.processPostDelayedCallbacksWithin(
1446                     UserController.SHOW_KEYGUARD_TIMEOUT_MS);
1447         } catch (RuntimeException e) {
1448             throw new AssertionError(
1449                     "SHOW_KEYGUARD_TIMEOUT is not ignored and crashed the system", e);
1450         }
1451     }
1452 
1453     @Test
testRuntimeExceptionIsThrownIfTheKeyguardIsNotShown()1454     public void testRuntimeExceptionIsThrownIfTheKeyguardIsNotShown() throws Exception {
1455         // enable user switch ui, because keyguard is only shown then
1456         mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
1457                 /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false,
1458                 /* backgroundUserScheduledStopTimeSecs= */ -1);
1459 
1460         // mock the device to be secure in order to expect the keyguard to be shown
1461         when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
1462 
1463         // suppress showKeyguard method for this test
1464         doNothing().when(mInjector).showKeyguard(any());
1465 
1466         mUserController.completeUserSwitch(TEST_USER_ID1, TEST_USER_ID2);
1467 
1468         // verify that the system has crashed
1469         assertThrows("Should have thrown RuntimeException", RuntimeException.class, () -> {
1470             mInjector.mHandler.processPostDelayedCallbacksWithin(
1471                     UserController.SHOW_KEYGUARD_TIMEOUT_MS);
1472         });
1473 
1474         // make sure the UserSwitchingDialog is not dismissed
1475         verify(mInjector, never()).dismissUserSwitchingDialog(any());
1476     }
1477 
setUpAndStartUserInBackground(int userId)1478     private void setUpAndStartUserInBackground(int userId) throws Exception {
1479         setUpUser(userId, 0);
1480         mUserController.startUser(userId, USER_START_MODE_BACKGROUND);
1481         verify(mInjector.mLockPatternUtilsMock, times(1)).unlockUserKeyIfUnsecured(userId);
1482         mUserStates.put(userId, mUserController.getStartedUserState(userId));
1483     }
1484 
setUpAndStartProfileInBackground(int userId, String userType)1485     private void setUpAndStartProfileInBackground(int userId, String userType) throws Exception {
1486         setUpUser(userId, UserInfo.FLAG_PROFILE, false, userType);
1487         assertThat(mUserController.startProfile(userId, /* evenWhenDisabled=*/ false,
1488                 /* unlockListener= */ null)).isTrue();
1489 
1490         verify(mInjector.mLockPatternUtilsMock, times(1)).unlockUserKeyIfUnsecured(userId);
1491         mUserStates.put(userId, mUserController.getStartedUserState(userId));
1492     }
1493 
assertUserLockedOrUnlockedAfterStopping(int userId, boolean allowDelayedLocking, KeyEvictedCallback keyEvictedCallback, boolean expectLocking)1494     private void assertUserLockedOrUnlockedAfterStopping(int userId, boolean allowDelayedLocking,
1495             KeyEvictedCallback keyEvictedCallback, boolean expectLocking) throws Exception {
1496         int r = mUserController.stopUser(userId, /* allowDelayedLocking= */
1497                 allowDelayedLocking, null, keyEvictedCallback);
1498         assertThat(r).isEqualTo(ActivityManager.USER_OP_SUCCESS);
1499         assertUserLockedOrUnlockedState(userId, allowDelayedLocking, expectLocking);
1500     }
1501 
assertProfileLockedOrUnlockedAfterStopping(int userId, boolean expectLocking)1502     private void assertProfileLockedOrUnlockedAfterStopping(int userId, boolean expectLocking)
1503             throws Exception {
1504         boolean profileStopped = mUserController.stopProfile(userId);
1505         assertThat(profileStopped).isTrue();
1506         assertUserLockedOrUnlockedState(userId, /* allowDelayedLocking= */ false, expectLocking);
1507     }
1508 
assertUserLockedOrUnlockedState(int userId, boolean allowDelayedLocking, boolean expectLocking)1509     private void assertUserLockedOrUnlockedState(int userId, boolean allowDelayedLocking,
1510             boolean expectLocking) throws InterruptedException, RemoteException {
1511         // fake all interim steps
1512         UserState ussUser = mUserStates.get(userId);
1513         ussUser.setState(UserState.STATE_SHUTDOWN);
1514         // Passing delayedLocking invalidates incorrect internal data passing but currently there is
1515         // no easy way to get that information passed through lambda.
1516         mUserController.finishUserStopped(ussUser, allowDelayedLocking);
1517         waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
1518         verify(mInjector.mStorageManagerMock, times(expectLocking ? 1 : 0))
1519                 .lockCeStorage(userId);
1520     }
1521 
addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, int expectedNumberOfCalls, boolean expectOldUserStopping, boolean expectScheduleBackgroundUserStopping)1522     private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId,
1523             int expectedNumberOfCalls, boolean expectOldUserStopping,
1524             boolean expectScheduleBackgroundUserStopping) {
1525         // Start user -- this will update state of mUserController
1526         mUserController.startUser(newUserId, USER_START_MODE_FOREGROUND);
1527         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
1528         assertNotNull(reportMsg);
1529         UserState userState = (UserState) reportMsg.obj;
1530         int oldUserId = reportMsg.arg1;
1531         assertEquals(expectedOldUserId, oldUserId);
1532         assertEquals(newUserId, reportMsg.arg2);
1533         mUserStates.put(newUserId, userState);
1534         mInjector.mHandler.clearAllRecordedMessages();
1535         // Verify that continueUserSwitch worked as expected
1536         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
1537         assertEquals(mInjector.mHandler
1538                         .hasMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, expectedOldUserId),
1539                 expectScheduleBackgroundUserStopping);
1540         verify(mInjector, times(expectedNumberOfCalls)).dismissUserSwitchingDialog(any());
1541         continueUserSwitchAssertions(oldUserId, newUserId, expectOldUserStopping,
1542                 expectScheduleBackgroundUserStopping);
1543     }
1544 
setUpUser(@serIdInt int userId, @UserInfoFlag int flags)1545     private UserInfo setUpUser(@UserIdInt int userId, @UserInfoFlag int flags) {
1546         return setUpUser(userId, flags, /* preCreated= */ false, /* userType */ null);
1547     }
1548 
setUpUser(@serIdInt int userId, @UserInfoFlag int flags, boolean preCreated, @Nullable String userType)1549     private UserInfo setUpUser(@UserIdInt int userId, @UserInfoFlag int flags, boolean preCreated,
1550             @Nullable String userType) {
1551         if (userType == null) {
1552             userType = UserInfo.getDefaultUserType(flags);
1553         }
1554         UserInfo userInfo = new UserInfo(userId, "User" + userId, /* iconPath= */ null, flags,
1555                 userType);
1556         userInfo.preCreated = preCreated;
1557         when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo);
1558         when(mInjector.mUserManagerMock.isPreCreated(userId)).thenReturn(preCreated);
1559 
1560         UserTypeDetails userTypeDetails = UserTypeFactory.getUserTypes().get(userType);
1561         assertThat(userTypeDetails).isNotNull();
1562         when(mInjector.mUserManagerInternalMock.getUserProperties(eq(userId)))
1563                 .thenReturn(userTypeDetails.getDefaultUserPropertiesReference());
1564 
1565         mUserInfos.put(userId, userInfo);
1566         when(mInjector.mUserManagerMock.getUsers(anyBoolean()))
1567                 .thenReturn(mUserInfos.values().stream().toList());
1568 
1569         return userInfo;
1570     }
1571 
getActions(List<Intent> intents)1572     private static List<String> getActions(List<Intent> intents) {
1573         List<String> result = new ArrayList<>();
1574         for (Intent intent : intents) {
1575             result.add(intent.getAction());
1576         }
1577         return result;
1578     }
1579 
waitForHandlerToComplete(Handler handler, long waitTimeMs)1580     private void waitForHandlerToComplete(Handler handler, long waitTimeMs)
1581             throws InterruptedException {
1582         final Object lock = new Object();
1583         synchronized (lock) {
1584             handler.post(() -> {
1585                 synchronized (lock) {
1586                     lock.notify();
1587                 }
1588             });
1589             lock.wait(waitTimeMs);
1590         }
1591     }
1592 
mockIsHeadlessSystemUserMode(boolean value)1593     private void mockIsHeadlessSystemUserMode(boolean value) {
1594         when(mInjector.isHeadlessSystemUserMode()).thenReturn(value);
1595     }
1596 
mockIsUsersOnSecondaryDisplaysEnabled(boolean value)1597     private void mockIsUsersOnSecondaryDisplaysEnabled(boolean value) {
1598         when(mInjector.isUsersOnSecondaryDisplaysEnabled()).thenReturn(value);
1599     }
1600 
verifyUserAssignedToDisplay(@serIdInt int userId, int displayId)1601     private void verifyUserAssignedToDisplay(@UserIdInt int userId, int displayId) {
1602         verify(mInjector.getUserManagerInternal()).assignUserToDisplayOnStart(eq(userId), anyInt(),
1603                 anyInt(), eq(displayId));
1604     }
1605 
verifyUserNeverAssignedToDisplay()1606     private void verifyUserNeverAssignedToDisplay() {
1607         verify(mInjector.getUserManagerInternal(), never()).assignUserToDisplayOnStart(anyInt(),
1608                 anyInt(), anyInt(), anyInt());
1609     }
1610 
verifyUserUnassignedFromDisplay(@serIdInt int userId)1611     private void verifyUserUnassignedFromDisplay(@UserIdInt int userId) {
1612         verify(mInjector.getUserManagerInternal()).unassignUserFromDisplayOnStop(userId);
1613     }
1614 
verifyUserUnassignedFromDisplayNeverCalled(@serIdInt int userId)1615     private void verifyUserUnassignedFromDisplayNeverCalled(@UserIdInt int userId) {
1616         verify(mInjector.getUserManagerInternal(), never()).unassignUserFromDisplayOnStop(userId);
1617     }
1618 
verifySystemUserVisibilityChangesNeverNotified()1619     private void verifySystemUserVisibilityChangesNeverNotified() {
1620         verify(mInjector, never()).onSystemUserVisibilityChanged(anyBoolean());
1621     }
1622 
1623     // Should be public to allow mocking
1624     private static class TestInjector extends UserController.Injector {
1625         public final TestHandler mHandler;
1626         public final HandlerThread mHandlerThread;
1627         public final UserManagerService mUserManagerMock;
1628         public final List<Intent> mSentIntents = new ArrayList<>();
1629 
1630         private final TestHandler mUiHandler;
1631 
1632         private final IStorageManager mStorageManagerMock;
1633         private final UserManagerInternal mUserManagerInternalMock;
1634         private final WindowManagerService mWindowManagerMock;
1635         private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
1636         private final PowerManagerInternal mPowerManagerInternal;
1637         private final KeyguardManager mKeyguardManagerMock;
1638         private final LockPatternUtils mLockPatternUtilsMock;
1639 
1640         private final UserJourneyLogger mUserJourneyLoggerMock;
1641 
1642         private final Context mCtx;
1643 
1644         private Integer mRelevantUser;
1645 
TestInjector(Context ctx)1646         TestInjector(Context ctx) {
1647             super(null);
1648             mCtx = ctx;
1649             mHandlerThread = new HandlerThread(TAG);
1650             mHandlerThread.start();
1651             mHandler = new TestHandler(mHandlerThread.getLooper());
1652             mUiHandler = new TestHandler(mHandlerThread.getLooper());
1653             mUserManagerMock = mock(UserManagerService.class);
1654             mUserManagerInternalMock = mock(UserManagerInternal.class);
1655             mWindowManagerMock = mock(WindowManagerService.class);
1656             mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
1657             mStorageManagerMock = mock(IStorageManager.class);
1658             mPowerManagerInternal = mock(PowerManagerInternal.class);
1659             mKeyguardManagerMock = mock(KeyguardManager.class);
1660             when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
1661             mLockPatternUtilsMock = mock(LockPatternUtils.class);
1662             mUserJourneyLoggerMock = mock(UserJourneyLogger.class);
1663         }
1664 
1665         @Override
getHandler(Handler.Callback callback)1666         protected Handler getHandler(Handler.Callback callback) {
1667             return mHandler;
1668         }
1669 
1670         @Override
getUiHandler(Handler.Callback callback)1671         protected Handler getUiHandler(Handler.Callback callback) {
1672             return mUiHandler;
1673         }
1674 
1675         @Override
getUserManager()1676         protected UserManagerService getUserManager() {
1677             return mUserManagerMock;
1678         }
1679 
1680         @Override
getUserManagerInternal()1681         UserManagerInternal getUserManagerInternal() {
1682             return mUserManagerInternalMock;
1683         }
1684 
1685         @Override
getContext()1686         protected Context getContext() {
1687             return mCtx;
1688         }
1689 
1690         @Override
checkCallingPermission(String permission)1691         int checkCallingPermission(String permission) {
1692             Log.i(TAG, "checkCallingPermission " + permission);
1693             return PERMISSION_GRANTED;
1694         }
1695 
1696         @Override
checkComponentPermission(String permission, int pid, int uid, int owner, boolean exp)1697         int checkComponentPermission(String permission, int pid, int uid, int owner, boolean exp) {
1698             Log.i(TAG, "checkComponentPermission " + permission);
1699             return PERMISSION_GRANTED;
1700         }
1701 
1702         @Override
checkPermissionForPreflight(String permission, int pid, int uid, String pkg)1703         boolean checkPermissionForPreflight(String permission, int pid, int uid, String pkg) {
1704             Log.i(TAG, "checkPermissionForPreflight " + permission);
1705             return true;
1706         }
1707 
1708         @Override
isCallerRecents(int uid)1709         boolean isCallerRecents(int uid) {
1710             return false;
1711         }
1712 
1713         @Override
getWindowManager()1714         WindowManagerService getWindowManager() {
1715             return mWindowManagerMock;
1716         }
1717 
1718         @Override
getActivityTaskManagerInternal()1719         ActivityTaskManagerInternal getActivityTaskManagerInternal() {
1720             return mActivityTaskManagerInternal;
1721         }
1722 
1723         @Override
getPowerManagerInternal()1724         PowerManagerInternal getPowerManagerInternal() {
1725             return mPowerManagerInternal;
1726         }
1727 
1728         @Override
getKeyguardManager()1729         KeyguardManager getKeyguardManager() {
1730             return mKeyguardManagerMock;
1731         }
1732 
1733         @Override
updateUserConfiguration()1734         void updateUserConfiguration() {
1735             Log.i(TAG, "updateUserConfiguration");
1736         }
1737 
1738         @Override
broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId)1739         protected int broadcastIntent(Intent intent, String resolvedType,
1740                 IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras,
1741                 String[] requiredPermissions, int appOp, Bundle bOptions,
1742                 boolean sticky, int callingPid, int callingUid, int realCallingUid,
1743                 int realCallingPid, int userId) {
1744             Log.i(TAG, "broadcastIntentLocked " + intent);
1745             if (mRelevantUser == null || mRelevantUser == userId || userId == UserHandle.USER_ALL) {
1746                 mSentIntents.add(intent);
1747             }
1748             return 0;
1749         }
1750 
1751         @Override
reportGlobalUsageEvent(int event)1752         void reportGlobalUsageEvent(int event) {
1753         }
1754 
1755         @Override
reportCurWakefulnessUsageEvent()1756         void reportCurWakefulnessUsageEvent() {
1757         }
1758 
1759         @Override
isRuntimeRestarted()1760         boolean isRuntimeRestarted() {
1761             // to pass all metrics related calls
1762             return true;
1763         }
1764 
1765         @Override
getStorageManager()1766         protected IStorageManager getStorageManager() {
1767             return mStorageManagerMock;
1768         }
1769 
1770         @Override
dismissKeyguard(Runnable runnable)1771         protected void dismissKeyguard(Runnable runnable) {
1772             runnable.run();
1773         }
1774 
1775         @Override
showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser, String switchingFromSystemUserMessage, String switchingToSystemUserMessage, Runnable onShown)1776         void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
1777                 String switchingFromSystemUserMessage, String switchingToSystemUserMessage,
1778                 Runnable onShown) {
1779             if (onShown != null) {
1780                 onShown.run();
1781             }
1782         }
1783 
1784         @Override
dismissUserSwitchingDialog(Runnable onDismissed)1785         void dismissUserSwitchingDialog(Runnable onDismissed) {
1786             if (onDismissed != null) {
1787                 onDismissed.run();
1788             }
1789         }
1790 
1791         @Override
getLockPatternUtils()1792         protected LockPatternUtils getLockPatternUtils() {
1793             return mLockPatternUtilsMock;
1794         }
1795 
1796         @Override
onUserStarting(@serIdInt int userId)1797         void onUserStarting(@UserIdInt int userId) {
1798             Log.i(TAG, "onUserStarting(" + userId + ")");
1799         }
1800 
1801         @Override
onSystemUserVisibilityChanged(boolean visible)1802         void onSystemUserVisibilityChanged(boolean visible) {
1803             Log.i(TAG, "onSystemUserVisibilityChanged(" + visible + ")");
1804         }
1805 
1806         @Override
getUserJourneyLogger()1807         protected UserJourneyLogger getUserJourneyLogger() {
1808             return mUserJourneyLoggerMock;
1809         }
1810     }
1811 
1812     private static class TestHandler extends Handler {
1813         private final List<Message> mMessages = new ArrayList<>();
1814 
TestHandler(Looper looper)1815         TestHandler(Looper looper) {
1816             super(looper);
1817         }
1818 
getMessageCodes()1819         Set<Integer> getMessageCodes() {
1820             Set<Integer> result = new LinkedHashSet<>();
1821             for (Message msg : mMessages) {
1822                 if (msg.what != 0) { // ignore mHandle.post and mHandler.postDelayed messages
1823                     result.add(msg.what);
1824                 }
1825             }
1826             return result;
1827         }
1828 
getMessageForCode(int what)1829         Message getMessageForCode(int what) {
1830             return getMessageForCode(what, null);
1831         }
1832 
getMessageForCode(int what, Object obj)1833         Message getMessageForCode(int what, Object obj) {
1834             for (Message msg : mMessages) {
1835                 if (msg.what == what && (obj == null || obj.equals(msg.obj))) {
1836                     return msg;
1837                 }
1838             }
1839             return null;
1840         }
1841 
clearAllRecordedMessages()1842         void clearAllRecordedMessages() {
1843             mMessages.clear();
1844         }
1845 
1846         @Override
sendMessageAtTime(Message msg, long uptimeMillis)1847         public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
1848             final Runnable cb = msg.getCallback();
1849             if (cb != null && uptimeMillis <= SystemClock.uptimeMillis()) {
1850                 // run mHandler.post calls immediately
1851                 cb.run();
1852                 return true;
1853             }
1854             Message copy = new Message();
1855             copy.copyFrom(msg);
1856             copy.setCallback(cb);
1857             mMessages.add(copy);
1858             return super.sendMessageAtTime(msg, uptimeMillis);
1859         }
1860 
processPostDelayedCallbacksWithin(long millis)1861         public void processPostDelayedCallbacksWithin(long millis) {
1862             final long whenMax = SystemClock.uptimeMillis() + millis;
1863             for (Message msg : mMessages) {
1864                 final Runnable cb = msg.getCallback();
1865                 if (cb != null && msg.getWhen() <= whenMax) {
1866                     msg.setCallback(null);
1867                     cb.run();
1868                 }
1869             }
1870         }
1871     }
1872 }
1873