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