Loading core/java/android/content/Intent.java +7 −2 Original line number Diff line number Diff line Loading @@ -3889,7 +3889,7 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.USER_INITIALIZE"; /** * Sent when a user switch is happening, causing the process's user to be * Sent after a user switch is complete, if the switch caused the process's user to be * brought to the foreground. This is only sent to receivers registered * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) * Context.registerReceiver}. It is sent to the user that is going to the Loading @@ -3901,7 +3901,7 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.USER_FOREGROUND"; /** * Sent when a user switch is happening, causing the process's user to be * Sent after a user switch is complete, if the switch caused the process's user to be * sent to the background. This is only sent to receivers registered * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) * Context.registerReceiver}. It is sent to the user that is going to the Loading Loading @@ -4042,6 +4042,11 @@ public class Intent implements Parcelable, Cloneable { * the current state of the user. * @hide */ /* * This broadcast is sent after the user switch is complete. In case a task needs to be done * while the switch is happening (i.e. while the screen is frozen to hide UI jank), please use * ActivityManagerService.registerUserSwitchObserver method. */ @SystemApi public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED"; Loading services/core/java/com/android/server/am/UserController.java +17 −14 Original line number Diff line number Diff line Loading @@ -1769,7 +1769,7 @@ class UserController implements Handler.Callback { if (foreground) { t.traceBegin("moveUserToForeground"); moveUserToForeground(uss, oldUserId, userId); moveUserToForeground(uss, userId); t.traceEnd(); } else { t.traceBegin("finishUserBoot"); Loading Loading @@ -1983,21 +1983,25 @@ class UserController implements Handler.Callback { /** Called on handler thread */ @VisibleForTesting void dispatchUserSwitchComplete(@UserIdInt int userId) { void dispatchUserSwitchComplete(@UserIdInt int oldUserId, @UserIdInt int newUserId) { final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("dispatchUserSwitchComplete-" + userId); t.traceBegin("dispatchUserSwitchComplete-" + newUserId); mInjector.getWindowManager().setSwitchingUser(false); final int observerCount = mUserSwitchObservers.beginBroadcast(); for (int i = 0; i < observerCount; i++) { try { t.traceBegin("onUserSwitchComplete-" + userId + " #" + i + " " t.traceBegin("onUserSwitchComplete-" + newUserId + " #" + i + " " + mUserSwitchObservers.getBroadcastCookie(i)); mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId); mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); t.traceEnd(); } catch (RemoteException e) { // Ignore } } mUserSwitchObservers.finishBroadcast(); t.traceBegin("sendUserSwitchBroadcasts-" + oldUserId + "-" + newUserId); sendUserSwitchBroadcasts(oldUserId, newUserId); t.traceEnd(); t.traceEnd(); } Loading Loading @@ -2159,7 +2163,8 @@ class UserController implements Handler.Callback { // Do the keyguard dismiss and unfreeze later mHandler.removeMessages(COMPLETE_USER_SWITCH_MSG); mHandler.sendMessage(mHandler.obtainMessage(COMPLETE_USER_SWITCH_MSG, newUserId, 0)); mHandler.sendMessage(mHandler.obtainMessage( COMPLETE_USER_SWITCH_MSG, oldUserId, newUserId)); uss.switching = false; stopGuestOrEphemeralUserIfBackground(oldUserId); Loading @@ -2169,7 +2174,7 @@ class UserController implements Handler.Callback { } @VisibleForTesting void completeUserSwitch(int newUserId) { void completeUserSwitch(int oldUserId, int newUserId) { final boolean isUserSwitchUiEnabled = isUserSwitchUiEnabled(); final Runnable runnable = () -> { if (isUserSwitchUiEnabled) { Loading @@ -2177,7 +2182,7 @@ class UserController implements Handler.Callback { } mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG); mHandler.sendMessage(mHandler.obtainMessage( REPORT_USER_SWITCH_COMPLETE_MSG, newUserId, 0)); REPORT_USER_SWITCH_COMPLETE_MSG, oldUserId, newUserId)); }; // If there is no challenge set, dismiss the keyguard right away Loading @@ -2202,7 +2207,7 @@ class UserController implements Handler.Callback { t.traceEnd(); } private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) { private void moveUserToForeground(UserState uss, int newUserId) { boolean homeInFront = mInjector.taskSupervisorSwitchUser(newUserId, uss); if (homeInFront) { mInjector.startHomeActivity(newUserId, "moveUserToForeground"); Loading @@ -2210,7 +2215,6 @@ class UserController implements Handler.Callback { mInjector.taskSupervisorResumeFocusedStackTopActivity(); } EventLogTags.writeAmSwitchUser(newUserId); sendUserSwitchBroadcasts(oldUserId, newUserId); } void sendUserSwitchBroadcasts(int oldUserId, int newUserId) { Loading Loading @@ -3080,9 +3084,8 @@ class UserController implements Handler.Callback { dispatchForegroundProfileChanged(msg.arg1); break; case REPORT_USER_SWITCH_COMPLETE_MSG: dispatchUserSwitchComplete(msg.arg1); logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_SWITCH_USER, dispatchUserSwitchComplete(msg.arg1, msg.arg2); logUserLifecycleEvent(msg.arg2, USER_LIFECYCLE_EVENT_SWITCH_USER, USER_LIFECYCLE_EVENT_STATE_FINISH); break; case REPORT_LOCKED_BOOT_COMPLETE_MSG: Loading @@ -3100,7 +3103,7 @@ class UserController implements Handler.Callback { logAndClearSessionId(msg.arg1); break; case COMPLETE_USER_SWITCH_MSG: completeUserSwitch(msg.arg1); completeUserSwitch(msg.arg1, msg.arg2); break; } return false; Loading services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +24 −15 Original line number Diff line number Diff line Loading @@ -113,6 +113,8 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Tests for {@link UserController}. Loading Loading @@ -146,9 +148,11 @@ public class UserControllerTest { private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList( Intent.ACTION_USER_STARTED, Intent.ACTION_USER_SWITCHED, Intent.ACTION_USER_STARTING); private static final List<String> START_FOREGROUND_USER_DEFERRED_ACTIONS = newArrayList( Intent.ACTION_USER_SWITCHED); private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList( Intent.ACTION_USER_STARTED, Intent.ACTION_LOCKED_BOOT_COMPLETED, Loading Loading @@ -397,11 +401,11 @@ public class UserControllerTest { private void continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId) { mUserController.continueUserSwitch(userState, oldUserId, newUserId); mInjector.mHandler.removeMessages(UserController.COMPLETE_USER_SWITCH_MSG); mUserController.completeUserSwitch(newUserId); mUserController.completeUserSwitch(oldUserId, newUserId); } @Test public void testContinueUserSwitch() throws RemoteException { public void testContinueUserSwitch() { mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); // Start user -- this will update state of mUserController Loading @@ -416,12 +420,12 @@ public class UserControllerTest { continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector, times(0)).dismissKeyguard(any(), anyString()); verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen(); continueUserSwitchAssertions(TEST_USER_ID, false); continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false); verifySystemUserVisibilityChangesNeverNotified(); } @Test public void testContinueUserSwitchDismissKeyguard() throws RemoteException { public void testContinueUserSwitchDismissKeyguard() { when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(false); mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); Loading @@ -437,12 +441,12 @@ public class UserControllerTest { continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector, times(1)).dismissKeyguard(any(), anyString()); verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen(); continueUserSwitchAssertions(TEST_USER_ID, false); continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false); verifySystemUserVisibilityChangesNeverNotified(); } @Test public void testContinueUserSwitchUIDisabled() throws RemoteException { public void testContinueUserSwitchUIDisabled() { mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); Loading @@ -457,11 +461,11 @@ public class UserControllerTest { // Verify that continueUserSwitch worked as expected continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); continueUserSwitchAssertions(TEST_USER_ID, false); continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false); } private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping) throws RemoteException { private void continueUserSwitchAssertions(int expectedOldUserId, int expectedNewUserId, boolean backgroundUserStopping) { Set<Integer> expectedCodes = new LinkedHashSet<>(); expectedCodes.add(COMPLETE_USER_SWITCH_MSG); expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG); Loading @@ -473,7 +477,8 @@ public class UserControllerTest { assertEquals("Unexpected message sent", expectedCodes, actualCodes); Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG); assertNotNull(msg); assertEquals("Unexpected userId", expectedUserId, msg.arg1); assertEquals("Unexpected oldUserId", expectedOldUserId, msg.arg1); assertEquals("Unexpected newUserId", expectedNewUserId, msg.arg2); } @Test Loading @@ -486,16 +491,21 @@ public class UserControllerTest { mUserController.startUser(TEST_USER_ID, true); Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); assertNotNull(reportMsg); int oldUserId = reportMsg.arg1; int newUserId = reportMsg.arg2; mInjector.mHandler.clearAllRecordedMessages(); // Mockito can't reset only interactions, so just verify that this hasn't been // called with 'false' until after dispatchUserSwitchComplete. verify(mInjector.getWindowManager(), never()).setSwitchingUser(false); // Call dispatchUserSwitchComplete mUserController.dispatchUserSwitchComplete(newUserId); mUserController.dispatchUserSwitchComplete(oldUserId, newUserId); verify(observer, times(1)).onUserSwitchComplete(anyInt()); verify(observer).onUserSwitchComplete(TEST_USER_ID); verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false); startUserAssertions(Stream.concat( START_FOREGROUND_USER_ACTIONS.stream(), START_FOREGROUND_USER_DEFERRED_ACTIONS.stream() ).collect(Collectors.toList()), Collections.emptySet()); } @Test Loading Loading @@ -902,8 +912,7 @@ public class UserControllerTest { } private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, int expectedNumberOfCalls, boolean expectOldUserStopping) throws RemoteException { int expectedNumberOfCalls, boolean expectOldUserStopping) { // Start user -- this will update state of mUserController mUserController.startUser(newUserId, true); Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); Loading @@ -918,7 +927,7 @@ public class UserControllerTest { continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector.getWindowManager(), times(expectedNumberOfCalls)) .stopFreezingScreen(); continueUserSwitchAssertions(newUserId, expectOldUserStopping); continueUserSwitchAssertions(oldUserId, newUserId, expectOldUserStopping); } private void setUpUser(@UserIdInt int userId, @UserInfoFlag int flags) { Loading Loading
core/java/android/content/Intent.java +7 −2 Original line number Diff line number Diff line Loading @@ -3889,7 +3889,7 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.USER_INITIALIZE"; /** * Sent when a user switch is happening, causing the process's user to be * Sent after a user switch is complete, if the switch caused the process's user to be * brought to the foreground. This is only sent to receivers registered * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) * Context.registerReceiver}. It is sent to the user that is going to the Loading @@ -3901,7 +3901,7 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.USER_FOREGROUND"; /** * Sent when a user switch is happening, causing the process's user to be * Sent after a user switch is complete, if the switch caused the process's user to be * sent to the background. This is only sent to receivers registered * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) * Context.registerReceiver}. It is sent to the user that is going to the Loading Loading @@ -4042,6 +4042,11 @@ public class Intent implements Parcelable, Cloneable { * the current state of the user. * @hide */ /* * This broadcast is sent after the user switch is complete. In case a task needs to be done * while the switch is happening (i.e. while the screen is frozen to hide UI jank), please use * ActivityManagerService.registerUserSwitchObserver method. */ @SystemApi public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED"; Loading
services/core/java/com/android/server/am/UserController.java +17 −14 Original line number Diff line number Diff line Loading @@ -1769,7 +1769,7 @@ class UserController implements Handler.Callback { if (foreground) { t.traceBegin("moveUserToForeground"); moveUserToForeground(uss, oldUserId, userId); moveUserToForeground(uss, userId); t.traceEnd(); } else { t.traceBegin("finishUserBoot"); Loading Loading @@ -1983,21 +1983,25 @@ class UserController implements Handler.Callback { /** Called on handler thread */ @VisibleForTesting void dispatchUserSwitchComplete(@UserIdInt int userId) { void dispatchUserSwitchComplete(@UserIdInt int oldUserId, @UserIdInt int newUserId) { final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("dispatchUserSwitchComplete-" + userId); t.traceBegin("dispatchUserSwitchComplete-" + newUserId); mInjector.getWindowManager().setSwitchingUser(false); final int observerCount = mUserSwitchObservers.beginBroadcast(); for (int i = 0; i < observerCount; i++) { try { t.traceBegin("onUserSwitchComplete-" + userId + " #" + i + " " t.traceBegin("onUserSwitchComplete-" + newUserId + " #" + i + " " + mUserSwitchObservers.getBroadcastCookie(i)); mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId); mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); t.traceEnd(); } catch (RemoteException e) { // Ignore } } mUserSwitchObservers.finishBroadcast(); t.traceBegin("sendUserSwitchBroadcasts-" + oldUserId + "-" + newUserId); sendUserSwitchBroadcasts(oldUserId, newUserId); t.traceEnd(); t.traceEnd(); } Loading Loading @@ -2159,7 +2163,8 @@ class UserController implements Handler.Callback { // Do the keyguard dismiss and unfreeze later mHandler.removeMessages(COMPLETE_USER_SWITCH_MSG); mHandler.sendMessage(mHandler.obtainMessage(COMPLETE_USER_SWITCH_MSG, newUserId, 0)); mHandler.sendMessage(mHandler.obtainMessage( COMPLETE_USER_SWITCH_MSG, oldUserId, newUserId)); uss.switching = false; stopGuestOrEphemeralUserIfBackground(oldUserId); Loading @@ -2169,7 +2174,7 @@ class UserController implements Handler.Callback { } @VisibleForTesting void completeUserSwitch(int newUserId) { void completeUserSwitch(int oldUserId, int newUserId) { final boolean isUserSwitchUiEnabled = isUserSwitchUiEnabled(); final Runnable runnable = () -> { if (isUserSwitchUiEnabled) { Loading @@ -2177,7 +2182,7 @@ class UserController implements Handler.Callback { } mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG); mHandler.sendMessage(mHandler.obtainMessage( REPORT_USER_SWITCH_COMPLETE_MSG, newUserId, 0)); REPORT_USER_SWITCH_COMPLETE_MSG, oldUserId, newUserId)); }; // If there is no challenge set, dismiss the keyguard right away Loading @@ -2202,7 +2207,7 @@ class UserController implements Handler.Callback { t.traceEnd(); } private void moveUserToForeground(UserState uss, int oldUserId, int newUserId) { private void moveUserToForeground(UserState uss, int newUserId) { boolean homeInFront = mInjector.taskSupervisorSwitchUser(newUserId, uss); if (homeInFront) { mInjector.startHomeActivity(newUserId, "moveUserToForeground"); Loading @@ -2210,7 +2215,6 @@ class UserController implements Handler.Callback { mInjector.taskSupervisorResumeFocusedStackTopActivity(); } EventLogTags.writeAmSwitchUser(newUserId); sendUserSwitchBroadcasts(oldUserId, newUserId); } void sendUserSwitchBroadcasts(int oldUserId, int newUserId) { Loading Loading @@ -3080,9 +3084,8 @@ class UserController implements Handler.Callback { dispatchForegroundProfileChanged(msg.arg1); break; case REPORT_USER_SWITCH_COMPLETE_MSG: dispatchUserSwitchComplete(msg.arg1); logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_SWITCH_USER, dispatchUserSwitchComplete(msg.arg1, msg.arg2); logUserLifecycleEvent(msg.arg2, USER_LIFECYCLE_EVENT_SWITCH_USER, USER_LIFECYCLE_EVENT_STATE_FINISH); break; case REPORT_LOCKED_BOOT_COMPLETE_MSG: Loading @@ -3100,7 +3103,7 @@ class UserController implements Handler.Callback { logAndClearSessionId(msg.arg1); break; case COMPLETE_USER_SWITCH_MSG: completeUserSwitch(msg.arg1); completeUserSwitch(msg.arg1, msg.arg2); break; } return false; Loading
services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +24 −15 Original line number Diff line number Diff line Loading @@ -113,6 +113,8 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Tests for {@link UserController}. Loading Loading @@ -146,9 +148,11 @@ public class UserControllerTest { private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList( Intent.ACTION_USER_STARTED, Intent.ACTION_USER_SWITCHED, Intent.ACTION_USER_STARTING); private static final List<String> START_FOREGROUND_USER_DEFERRED_ACTIONS = newArrayList( Intent.ACTION_USER_SWITCHED); private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList( Intent.ACTION_USER_STARTED, Intent.ACTION_LOCKED_BOOT_COMPLETED, Loading Loading @@ -397,11 +401,11 @@ public class UserControllerTest { private void continueAndCompleteUserSwitch(UserState userState, int oldUserId, int newUserId) { mUserController.continueUserSwitch(userState, oldUserId, newUserId); mInjector.mHandler.removeMessages(UserController.COMPLETE_USER_SWITCH_MSG); mUserController.completeUserSwitch(newUserId); mUserController.completeUserSwitch(oldUserId, newUserId); } @Test public void testContinueUserSwitch() throws RemoteException { public void testContinueUserSwitch() { mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); // Start user -- this will update state of mUserController Loading @@ -416,12 +420,12 @@ public class UserControllerTest { continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector, times(0)).dismissKeyguard(any(), anyString()); verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen(); continueUserSwitchAssertions(TEST_USER_ID, false); continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false); verifySystemUserVisibilityChangesNeverNotified(); } @Test public void testContinueUserSwitchDismissKeyguard() throws RemoteException { public void testContinueUserSwitchDismissKeyguard() { when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(false); mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); Loading @@ -437,12 +441,12 @@ public class UserControllerTest { continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector, times(1)).dismissKeyguard(any(), anyString()); verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen(); continueUserSwitchAssertions(TEST_USER_ID, false); continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false); verifySystemUserVisibilityChangesNeverNotified(); } @Test public void testContinueUserSwitchUIDisabled() throws RemoteException { public void testContinueUserSwitchUIDisabled() { mUserController.setInitialConfig(/* userSwitchUiEnabled= */ false, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); Loading @@ -457,11 +461,11 @@ public class UserControllerTest { // Verify that continueUserSwitch worked as expected continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); continueUserSwitchAssertions(TEST_USER_ID, false); continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false); } private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping) throws RemoteException { private void continueUserSwitchAssertions(int expectedOldUserId, int expectedNewUserId, boolean backgroundUserStopping) { Set<Integer> expectedCodes = new LinkedHashSet<>(); expectedCodes.add(COMPLETE_USER_SWITCH_MSG); expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG); Loading @@ -473,7 +477,8 @@ public class UserControllerTest { assertEquals("Unexpected message sent", expectedCodes, actualCodes); Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG); assertNotNull(msg); assertEquals("Unexpected userId", expectedUserId, msg.arg1); assertEquals("Unexpected oldUserId", expectedOldUserId, msg.arg1); assertEquals("Unexpected newUserId", expectedNewUserId, msg.arg2); } @Test Loading @@ -486,16 +491,21 @@ public class UserControllerTest { mUserController.startUser(TEST_USER_ID, true); Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); assertNotNull(reportMsg); int oldUserId = reportMsg.arg1; int newUserId = reportMsg.arg2; mInjector.mHandler.clearAllRecordedMessages(); // Mockito can't reset only interactions, so just verify that this hasn't been // called with 'false' until after dispatchUserSwitchComplete. verify(mInjector.getWindowManager(), never()).setSwitchingUser(false); // Call dispatchUserSwitchComplete mUserController.dispatchUserSwitchComplete(newUserId); mUserController.dispatchUserSwitchComplete(oldUserId, newUserId); verify(observer, times(1)).onUserSwitchComplete(anyInt()); verify(observer).onUserSwitchComplete(TEST_USER_ID); verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false); startUserAssertions(Stream.concat( START_FOREGROUND_USER_ACTIONS.stream(), START_FOREGROUND_USER_DEFERRED_ACTIONS.stream() ).collect(Collectors.toList()), Collections.emptySet()); } @Test Loading Loading @@ -902,8 +912,7 @@ public class UserControllerTest { } private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, int expectedNumberOfCalls, boolean expectOldUserStopping) throws RemoteException { int expectedNumberOfCalls, boolean expectOldUserStopping) { // Start user -- this will update state of mUserController mUserController.startUser(newUserId, true); Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); Loading @@ -918,7 +927,7 @@ public class UserControllerTest { continueAndCompleteUserSwitch(userState, oldUserId, newUserId); verify(mInjector.getWindowManager(), times(expectedNumberOfCalls)) .stopFreezingScreen(); continueUserSwitchAssertions(newUserId, expectOldUserStopping); continueUserSwitchAssertions(oldUserId, newUserId, expectOldUserStopping); } private void setUpUser(@UserIdInt int userId, @UserInfoFlag int flags) { Loading