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.content.pm.PackageManager.PERMISSION_GRANTED; 20 import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; 21 22 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 23 24 import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG; 25 import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG; 26 import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG; 27 import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG; 28 import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG; 29 import static com.android.server.am.UserController.SYSTEM_USER_START_MSG; 30 import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG; 31 32 import static com.google.android.collect.Lists.newArrayList; 33 import static com.google.android.collect.Sets.newHashSet; 34 import static com.google.common.truth.Truth.assertWithMessage; 35 36 import static org.junit.Assert.assertEquals; 37 import static org.junit.Assert.assertFalse; 38 import static org.junit.Assert.assertNotNull; 39 import static org.junit.Assert.assertTrue; 40 import static org.mockito.ArgumentMatchers.anyString; 41 import static org.mockito.Matchers.any; 42 import static org.mockito.Matchers.anyBoolean; 43 import static org.mockito.Matchers.anyInt; 44 import static org.mockito.Matchers.eq; 45 import static org.mockito.Mockito.doAnswer; 46 import static org.mockito.Mockito.doNothing; 47 import static org.mockito.Mockito.doReturn; 48 import static org.mockito.Mockito.mock; 49 import static org.mockito.Mockito.never; 50 import static org.mockito.Mockito.spy; 51 import static org.mockito.Mockito.times; 52 import static org.mockito.Mockito.validateMockitoUsage; 53 import static org.mockito.Mockito.verify; 54 import static org.mockito.Mockito.when; 55 56 import android.app.IUserSwitchObserver; 57 import android.content.Context; 58 import android.content.IIntentReceiver; 59 import android.content.Intent; 60 import android.content.pm.UserInfo; 61 import android.os.Binder; 62 import android.os.Bundle; 63 import android.os.Handler; 64 import android.os.HandlerThread; 65 import android.os.IRemoteCallback; 66 import android.os.Looper; 67 import android.os.Message; 68 import android.os.RemoteException; 69 import android.os.UserHandle; 70 import android.os.UserManagerInternal; 71 import android.os.storage.IStorageManager; 72 import android.platform.test.annotations.Presubmit; 73 import android.util.Log; 74 75 76 import androidx.test.filters.FlakyTest; 77 import androidx.test.filters.SmallTest; 78 79 import com.android.server.FgThread; 80 import com.android.server.pm.UserManagerService; 81 import com.android.server.wm.WindowManagerService; 82 83 import org.junit.After; 84 import org.junit.Before; 85 import org.junit.Test; 86 87 import java.util.ArrayList; 88 import java.util.Arrays; 89 import java.util.Collections; 90 import java.util.HashMap; 91 import java.util.LinkedHashSet; 92 import java.util.List; 93 import java.util.Set; 94 95 /** 96 * Tests for {@link UserController}. 97 * 98 * Build/Install/Run: 99 * atest FrameworksServicesTests:UserControllerTest 100 */ 101 @SmallTest 102 @Presubmit 103 104 public class UserControllerTest { 105 // Use big enough user id to avoid picking up already active user id. 106 private static final int TEST_USER_ID = 100; 107 private static final int TEST_USER_ID1 = 101; 108 private static final int TEST_USER_ID2 = 102; 109 private static final int NONEXIST_USER_ID = 2; 110 private static final String TAG = UserControllerTest.class.getSimpleName(); 111 112 private static final long HANDLER_WAIT_TIME_MS = 100; 113 114 private UserController mUserController; 115 private TestInjector mInjector; 116 private final HashMap<Integer, UserState> mUserStates = new HashMap<>(); 117 118 private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList( 119 Intent.ACTION_USER_STARTED, 120 Intent.ACTION_USER_SWITCHED, 121 Intent.ACTION_USER_STARTING); 122 123 private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList( 124 Intent.ACTION_USER_STARTED, 125 Intent.ACTION_LOCKED_BOOT_COMPLETED, 126 Intent.ACTION_USER_STARTING); 127 128 private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet( 129 REPORT_USER_SWITCH_MSG, 130 USER_SWITCH_TIMEOUT_MSG, 131 SYSTEM_USER_START_MSG, 132 SYSTEM_USER_CURRENT_MSG); 133 134 private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet( 135 SYSTEM_USER_START_MSG, 136 REPORT_LOCKED_BOOT_COMPLETE_MSG); 137 138 @Before setUp()139 public void setUp() throws Exception { 140 runWithDexmakerShareClassLoader(() -> { 141 mInjector = spy(new TestInjector(getInstrumentation().getTargetContext())); 142 doNothing().when(mInjector).clearAllLockedTasks(anyString()); 143 doNothing().when(mInjector).startHomeActivity(anyInt(), anyString()); 144 doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any()); 145 doNothing().when(mInjector).stackSupervisorResumeFocusedStackTopActivity(); 146 doNothing().when(mInjector).systemServiceManagerCleanupUser(anyInt()); 147 doNothing().when(mInjector).activityManagerForceStopPackage(anyInt(), anyString()); 148 doNothing().when(mInjector).activityManagerOnUserStopped(anyInt()); 149 doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt()); 150 doNothing().when(mInjector).stackSupervisorRemoveUser(anyInt()); 151 mUserController = new UserController(mInjector); 152 setUpUser(TEST_USER_ID, 0); 153 }); 154 } 155 156 @After tearDown()157 public void tearDown() throws Exception { 158 mInjector.mHandlerThread.quit(); 159 validateMockitoUsage(); 160 } 161 162 @Test testStartUser_foreground()163 public void testStartUser_foreground() { 164 mUserController.startUser(TEST_USER_ID, true /* foreground */); 165 verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt()); 166 verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); 167 verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean()); 168 verify(mInjector.getWindowManager()).setSwitchingUser(true); 169 verify(mInjector).clearAllLockedTasks(anyString()); 170 startForegroundUserAssertions(); 171 } 172 173 @FlakyTest(bugId = 118932054) 174 @Test testStartUser_background()175 public void testStartUser_background() { 176 mUserController.startUser(TEST_USER_ID, false /* foreground */); 177 verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt()); 178 verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean()); 179 verify(mInjector, never()).clearAllLockedTasks(anyString()); 180 startBackgroundUserAssertions(); 181 } 182 183 @Test testStartUserUIDisabled()184 public void testStartUserUIDisabled() { 185 mUserController.mUserSwitchUiEnabled = false; 186 mUserController.startUser(TEST_USER_ID, true /* foreground */); 187 verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt()); 188 verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); 189 verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean()); 190 startForegroundUserAssertions(); 191 } 192 startUserAssertions( List<String> expectedActions, Set<Integer> expectedMessageCodes)193 private void startUserAssertions( 194 List<String> expectedActions, Set<Integer> expectedMessageCodes) { 195 assertEquals(expectedActions, getActions(mInjector.mSentIntents)); 196 Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes(); 197 assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes); 198 } 199 startBackgroundUserAssertions()200 private void startBackgroundUserAssertions() { 201 startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES); 202 } 203 startForegroundUserAssertions()204 private void startForegroundUserAssertions() { 205 startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES); 206 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 207 assertNotNull(reportMsg); 208 UserState userState = (UserState) reportMsg.obj; 209 assertNotNull(userState); 210 assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier()); 211 assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state); 212 assertEquals("Unexpected old user id", 0, reportMsg.arg1); 213 assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2); 214 } 215 216 @Test testFailedStartUserInForeground()217 public void testFailedStartUserInForeground() { 218 mUserController.mUserSwitchUiEnabled = false; 219 mUserController.startUserInForeground(NONEXIST_USER_ID); 220 verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean()); 221 verify(mInjector.getWindowManager()).setSwitchingUser(false); 222 } 223 224 @Test testDispatchUserSwitch()225 public void testDispatchUserSwitch() throws RemoteException { 226 // Prepare mock observer and register it 227 IUserSwitchObserver observer = mock(IUserSwitchObserver.class); 228 when(observer.asBinder()).thenReturn(new Binder()); 229 doAnswer(invocation -> { 230 IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1]; 231 callback.sendResult(null); 232 return null; 233 }).when(observer).onUserSwitching(anyInt(), any()); 234 mUserController.registerUserSwitchObserver(observer, "mock"); 235 // Start user -- this will update state of mUserController 236 mUserController.startUser(TEST_USER_ID, true); 237 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 238 assertNotNull(reportMsg); 239 UserState userState = (UserState) reportMsg.obj; 240 int oldUserId = reportMsg.arg1; 241 int newUserId = reportMsg.arg2; 242 // Call dispatchUserSwitch and verify that observer was called only once 243 mInjector.mHandler.clearAllRecordedMessages(); 244 mUserController.dispatchUserSwitch(userState, oldUserId, newUserId); 245 verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any()); 246 Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG); 247 Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes(); 248 assertEquals("Unexpected message sent", expectedCodes, actualCodes); 249 Message conMsg = mInjector.mHandler.getMessageForCode(CONTINUE_USER_SWITCH_MSG); 250 assertNotNull(conMsg); 251 userState = (UserState) conMsg.obj; 252 assertNotNull(userState); 253 assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier()); 254 assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state); 255 assertEquals("Unexpected old user id", 0, conMsg.arg1); 256 assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2); 257 } 258 259 @Test testDispatchUserSwitchBadReceiver()260 public void testDispatchUserSwitchBadReceiver() throws RemoteException { 261 // Prepare mock observer which doesn't notify the callback and register it 262 IUserSwitchObserver observer = mock(IUserSwitchObserver.class); 263 when(observer.asBinder()).thenReturn(new Binder()); 264 mUserController.registerUserSwitchObserver(observer, "mock"); 265 // Start user -- this will update state of mUserController 266 mUserController.startUser(TEST_USER_ID, true); 267 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 268 assertNotNull(reportMsg); 269 UserState userState = (UserState) reportMsg.obj; 270 int oldUserId = reportMsg.arg1; 271 int newUserId = reportMsg.arg2; 272 // Call dispatchUserSwitch and verify that observer was called only once 273 mInjector.mHandler.clearAllRecordedMessages(); 274 mUserController.dispatchUserSwitch(userState, oldUserId, newUserId); 275 verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any()); 276 // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout) 277 Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes(); 278 assertWithMessage("No messages should be sent").that(actualCodes).isEmpty(); 279 } 280 281 @Test testContinueUserSwitch()282 public void testContinueUserSwitch() throws RemoteException { 283 // Start user -- this will update state of mUserController 284 mUserController.startUser(TEST_USER_ID, true); 285 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 286 assertNotNull(reportMsg); 287 UserState userState = (UserState) reportMsg.obj; 288 int oldUserId = reportMsg.arg1; 289 int newUserId = reportMsg.arg2; 290 mInjector.mHandler.clearAllRecordedMessages(); 291 // Verify that continueUserSwitch worked as expected 292 mUserController.continueUserSwitch(userState, oldUserId, newUserId); 293 verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen(); 294 continueUserSwitchAssertions(TEST_USER_ID, false); 295 } 296 297 @Test testContinueUserSwitchUIDisabled()298 public void testContinueUserSwitchUIDisabled() throws RemoteException { 299 mUserController.mUserSwitchUiEnabled = false; 300 // Start user -- this will update state of mUserController 301 mUserController.startUser(TEST_USER_ID, true); 302 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 303 assertNotNull(reportMsg); 304 UserState userState = (UserState) reportMsg.obj; 305 int oldUserId = reportMsg.arg1; 306 int newUserId = reportMsg.arg2; 307 mInjector.mHandler.clearAllRecordedMessages(); 308 // Verify that continueUserSwitch worked as expected 309 mUserController.continueUserSwitch(userState, oldUserId, newUserId); 310 verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); 311 continueUserSwitchAssertions(TEST_USER_ID, false); 312 } 313 continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping)314 private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping) 315 throws RemoteException { 316 Set<Integer> expectedCodes = new LinkedHashSet<>(); 317 expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG); 318 if (backgroundUserStopping) { 319 expectedCodes.add(0); // this is for directly posting in stopping. 320 } 321 Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes(); 322 assertEquals("Unexpected message sent", expectedCodes, actualCodes); 323 Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG); 324 assertNotNull(msg); 325 assertEquals("Unexpected userId", expectedUserId, msg.arg1); 326 } 327 328 @Test testDispatchUserSwitchComplete()329 public void testDispatchUserSwitchComplete() throws RemoteException { 330 // Prepare mock observer and register it 331 IUserSwitchObserver observer = mock(IUserSwitchObserver.class); 332 when(observer.asBinder()).thenReturn(new Binder()); 333 mUserController.registerUserSwitchObserver(observer, "mock"); 334 // Start user -- this will update state of mUserController 335 mUserController.startUser(TEST_USER_ID, true); 336 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 337 assertNotNull(reportMsg); 338 int newUserId = reportMsg.arg2; 339 mInjector.mHandler.clearAllRecordedMessages(); 340 // Mockito can't reset only interactions, so just verify that this hasn't been 341 // called with 'false' until after dispatchUserSwitchComplete. 342 verify(mInjector.getWindowManager(), never()).setSwitchingUser(false); 343 // Call dispatchUserSwitchComplete 344 mUserController.dispatchUserSwitchComplete(newUserId); 345 verify(observer, times(1)).onUserSwitchComplete(anyInt()); 346 verify(observer).onUserSwitchComplete(TEST_USER_ID); 347 verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false); 348 } 349 350 @Test testExplicitSystenUserStartInBackground()351 public void testExplicitSystenUserStartInBackground() { 352 setUpUser(UserHandle.USER_SYSTEM, 0); 353 assertFalse(mUserController.isSystemUserStarted()); 354 assertTrue(mUserController.startUser(UserHandle.USER_SYSTEM, false, null)); 355 assertTrue(mUserController.isSystemUserStarted()); 356 } 357 358 /** 359 * Test stopping of user from max running users limit. 360 */ 361 @Test testUserStoppingForMultipleUsersNormalMode()362 public void testUserStoppingForMultipleUsersNormalMode() 363 throws InterruptedException, RemoteException { 364 setUpUser(TEST_USER_ID1, 0); 365 setUpUser(TEST_USER_ID2, 0); 366 mUserController.mMaxRunningUsers = 3; 367 int numerOfUserSwitches = 1; 368 addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM, 369 numerOfUserSwitches, false); 370 // running: user 0, USER_ID 371 assertTrue(mUserController.canStartMoreUsers()); 372 assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}), 373 mUserController.getRunningUsersLU()); 374 375 numerOfUserSwitches++; 376 addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID, 377 numerOfUserSwitches, false); 378 // running: user 0, USER_ID, USER_ID1 379 assertFalse(mUserController.canStartMoreUsers()); 380 assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID, TEST_USER_ID1}), 381 mUserController.getRunningUsersLU()); 382 383 numerOfUserSwitches++; 384 addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1, 385 numerOfUserSwitches, false); 386 UserState ussUser2 = mUserStates.get(TEST_USER_ID2); 387 // skip middle step and call this directly. 388 mUserController.finishUserSwitch(ussUser2); 389 waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS); 390 // running: user 0, USER_ID1, USER_ID2 391 // USER_ID should be stopped as it is least recently used non user0. 392 assertFalse(mUserController.canStartMoreUsers()); 393 assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1, TEST_USER_ID2}), 394 mUserController.getRunningUsersLU()); 395 } 396 397 /** 398 * This test tests delayed locking mode using 4 users. As core logic of delayed locking is 399 * happening in finishUserStopped call, the test also calls finishUserStopped while skipping 400 * all middle steps which takes too much work to mock. 401 */ 402 @Test testUserStoppingForMultipleUsersDelayedLockingMode()403 public void testUserStoppingForMultipleUsersDelayedLockingMode() 404 throws InterruptedException, RemoteException { 405 setUpUser(TEST_USER_ID1, 0); 406 setUpUser(TEST_USER_ID2, 0); 407 mUserController.mMaxRunningUsers = 3; 408 mUserController.mDelayUserDataLocking = true; 409 int numerOfUserSwitches = 1; 410 addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM, 411 numerOfUserSwitches, false); 412 // running: user 0, USER_ID 413 assertTrue(mUserController.canStartMoreUsers()); 414 assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}), 415 mUserController.getRunningUsersLU()); 416 numerOfUserSwitches++; 417 418 addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID, 419 numerOfUserSwitches, true); 420 // running: user 0, USER_ID1 421 // stopped + unlocked: USER_ID 422 numerOfUserSwitches++; 423 assertTrue(mUserController.canStartMoreUsers()); 424 assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1}), 425 mUserController.getRunningUsersLU()); 426 // Skip all other steps and test unlock delaying only 427 UserState uss = mUserStates.get(TEST_USER_ID); 428 uss.setState(UserState.STATE_SHUTDOWN); // necessary state change from skipped part 429 mUserController.finishUserStopped(uss); 430 // Cannot mock FgThread handler, so confirm that there is no posted message left before 431 // checking. 432 waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS); 433 verify(mInjector.mStorageManagerMock, times(0)) 434 .lockUserKey(anyInt()); 435 436 addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1, 437 numerOfUserSwitches, true); 438 // running: user 0, USER_ID2 439 // stopped + unlocked: USER_ID1 440 // stopped + locked: USER_ID 441 assertTrue(mUserController.canStartMoreUsers()); 442 assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID2}), 443 mUserController.getRunningUsersLU()); 444 UserState ussUser1 = mUserStates.get(TEST_USER_ID1); 445 ussUser1.setState(UserState.STATE_SHUTDOWN); 446 mUserController.finishUserStopped(ussUser1); 447 waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS); 448 verify(mInjector.mStorageManagerMock, times(1)) 449 .lockUserKey(TEST_USER_ID); 450 } 451 addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, int expectedNumberOfCalls, boolean expectOldUserStopping)452 private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, 453 int expectedNumberOfCalls, boolean expectOldUserStopping) 454 throws RemoteException { 455 // Start user -- this will update state of mUserController 456 mUserController.startUser(newUserId, true); 457 Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); 458 assertNotNull(reportMsg); 459 UserState userState = (UserState) reportMsg.obj; 460 int oldUserId = reportMsg.arg1; 461 assertEquals(expectedOldUserId, oldUserId); 462 assertEquals(newUserId, reportMsg.arg2); 463 mUserStates.put(newUserId, userState); 464 mInjector.mHandler.clearAllRecordedMessages(); 465 // Verify that continueUserSwitch worked as expected 466 mUserController.continueUserSwitch(userState, oldUserId, newUserId); 467 verify(mInjector.getWindowManager(), times(expectedNumberOfCalls)) 468 .stopFreezingScreen(); 469 continueUserSwitchAssertions(newUserId, expectOldUserStopping); 470 } 471 setUpUser(int userId, int flags)472 private void setUpUser(int userId, int flags) { 473 UserInfo userInfo = new UserInfo(userId, "User" + userId, flags); 474 when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo); 475 } 476 getActions(List<Intent> intents)477 private static List<String> getActions(List<Intent> intents) { 478 List<String> result = new ArrayList<>(); 479 for (Intent intent : intents) { 480 result.add(intent.getAction()); 481 } 482 return result; 483 } 484 waitForHandlerToComplete(Handler handler, long waitTimeMs)485 private void waitForHandlerToComplete(Handler handler, long waitTimeMs) 486 throws InterruptedException { 487 final Object lock = new Object(); 488 synchronized (lock) { 489 handler.post(() -> { 490 synchronized (lock) { 491 lock.notify(); 492 } 493 }); 494 lock.wait(waitTimeMs); 495 } 496 } 497 498 // Should be public to allow mocking 499 private static class TestInjector extends UserController.Injector { 500 public final TestHandler mHandler; 501 public final HandlerThread mHandlerThread; 502 public final UserManagerService mUserManagerMock; 503 public final List<Intent> mSentIntents = new ArrayList<>(); 504 505 private final TestHandler mUiHandler; 506 507 private final IStorageManager mStorageManagerMock; 508 private final UserManagerInternal mUserManagerInternalMock; 509 private final WindowManagerService mWindowManagerMock; 510 511 private final Context mCtx; 512 TestInjector(Context ctx)513 TestInjector(Context ctx) { 514 super(null); 515 mCtx = ctx; 516 mHandlerThread = new HandlerThread(TAG); 517 mHandlerThread.start(); 518 mHandler = new TestHandler(mHandlerThread.getLooper()); 519 mUiHandler = new TestHandler(mHandlerThread.getLooper()); 520 mUserManagerMock = mock(UserManagerService.class); 521 mUserManagerInternalMock = mock(UserManagerInternal.class); 522 mWindowManagerMock = mock(WindowManagerService.class); 523 mStorageManagerMock = mock(IStorageManager.class); 524 } 525 526 @Override getHandler(Handler.Callback callback)527 protected Handler getHandler(Handler.Callback callback) { 528 return mHandler; 529 } 530 531 @Override getUiHandler(Handler.Callback callback)532 protected Handler getUiHandler(Handler.Callback callback) { 533 return mUiHandler; 534 } 535 536 @Override getUserManager()537 protected UserManagerService getUserManager() { 538 return mUserManagerMock; 539 } 540 541 @Override getUserManagerInternal()542 UserManagerInternal getUserManagerInternal() { 543 return mUserManagerInternalMock; 544 } 545 546 @Override getContext()547 protected Context getContext() { 548 return mCtx; 549 } 550 551 @Override checkCallingPermission(String permission)552 int checkCallingPermission(String permission) { 553 Log.i(TAG, "checkCallingPermission " + permission); 554 return PERMISSION_GRANTED; 555 } 556 557 @Override getWindowManager()558 WindowManagerService getWindowManager() { 559 return mWindowManagerMock; 560 } 561 562 @Override updateUserConfiguration()563 void updateUserConfiguration() { 564 Log.i(TAG, "updateUserConfiguration"); 565 } 566 567 @Override broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId)568 protected int broadcastIntent(Intent intent, String resolvedType, 569 IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, 570 String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, 571 boolean sticky, int callingPid, int callingUid, int realCallingUid, 572 int realCallingPid, int userId) { 573 Log.i(TAG, "broadcastIntentLocked " + intent); 574 mSentIntents.add(intent); 575 return 0; 576 } 577 578 @Override reportGlobalUsageEventLocked(int event)579 void reportGlobalUsageEventLocked(int event) { 580 } 581 582 @Override reportCurWakefulnessUsageEvent()583 void reportCurWakefulnessUsageEvent() { 584 } 585 586 @Override isRuntimeRestarted()587 boolean isRuntimeRestarted() { 588 // to pass all metrics related calls 589 return true; 590 } 591 592 @Override getStorageManager()593 protected IStorageManager getStorageManager() { 594 return mStorageManagerMock; 595 } 596 } 597 598 private static class TestHandler extends Handler { 599 private final List<Message> mMessages = new ArrayList<>(); 600 TestHandler(Looper looper)601 TestHandler(Looper looper) { 602 super(looper); 603 } 604 getMessageCodes()605 Set<Integer> getMessageCodes() { 606 Set<Integer> result = new LinkedHashSet<>(); 607 for (Message msg : mMessages) { 608 result.add(msg.what); 609 } 610 return result; 611 } 612 getMessageForCode(int what)613 Message getMessageForCode(int what) { 614 for (Message msg : mMessages) { 615 if (msg.what == what) { 616 return msg; 617 } 618 } 619 return null; 620 } 621 clearAllRecordedMessages()622 void clearAllRecordedMessages() { 623 mMessages.clear(); 624 } 625 626 @Override sendMessageAtTime(Message msg, long uptimeMillis)627 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 628 Message copy = new Message(); 629 copy.copyFrom(msg); 630 mMessages.add(copy); 631 return super.sendMessageAtTime(msg, uptimeMillis); 632 } 633 } 634 } 635