diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 728476aebf3ef..3b5e5bcce7aeb 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -670,7 +670,7 @@ final class UserController { } mInjector.systemServiceManagerCleanupUser(userId); synchronized (mLock) { - mInjector.stackSupervisorRemoveUserLocked(userId); + mInjector.getActivityStackSupervisor().removeUserLocked(userId); } // Remove the user if it is ephemeral. if (getUserInfo(userId).isEphemeral()) { @@ -823,8 +823,10 @@ final class UserController { return true; } - mInjector.stackSupervisorSetLockTaskModeLocked(null, - ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false); + if (foreground) { + mInjector.getActivityStackSupervisor().setLockTaskModeLocked( + null, ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false); + } final UserInfo userInfo = getUserInfo(userId); if (userInfo == null) { @@ -1202,11 +1204,12 @@ final class UserController { } void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) { - boolean homeInFront = mInjector.stackSupervisorSwitchUserLocked(newUserId, uss); + boolean homeInFront = + mInjector.getActivityStackSupervisor().switchUserLocked(newUserId, uss); if (homeInFront) { mInjector.startHomeActivityLocked(newUserId, "moveUserToForeground"); } else { - mInjector.stackSupervisorResumeFocusedStackTopActivityLocked(); + mInjector.getActivityStackSupervisor().resumeFocusedStackTopActivityLocked(); } EventLogTags.writeAmSwitchUser(newUserId); sendUserSwitchBroadcastsLocked(oldUserId, newUserId); @@ -1680,10 +1683,6 @@ final class UserController { mService.mSystemServiceManager.cleanupUser(userId); } - void stackSupervisorRemoveUserLocked(int userId) { - mService.mStackSupervisor.removeUserLocked(userId); - } - protected UserManagerService getUserManager() { if (mUserManager == null) { IBinder b = ServiceManager.getService(Context.USER_SERVICE); @@ -1743,24 +1742,10 @@ final class UserController { return mService.checkComponentPermission(permission, pid, uid, owningUid, exported); } - boolean stackSupervisorSwitchUserLocked(int userId, UserState uss) { - return mService.mStackSupervisor.switchUserLocked(userId, uss); - } - void startHomeActivityLocked(int userId, String reason) { mService.startHomeActivityLocked(userId, reason); } - void stackSupervisorResumeFocusedStackTopActivityLocked() { - mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); - } - - void stackSupervisorSetLockTaskModeLocked(TaskRecord task, int lockTaskModeState, - String reason, boolean andResume) { - mService.mStackSupervisor.setLockTaskModeLocked(task, lockTaskModeState, reason, - andResume); - } - void updateUserConfigurationLocked() { mService.updateUserConfigurationLocked(); } @@ -1778,5 +1763,9 @@ final class UserController { true /* above system */); d.show(); } + + ActivityStackSupervisor getActivityStackSupervisor() { + return mService.mStackSupervisor; + } } } diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index 0f1b81e49f9ed..7a4746a7f54ba 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -16,6 +16,7 @@ package com.android.server.am; +import android.app.ActivityManager; import android.app.IUserSwitchObserver; import android.content.Context; import android.content.IIntentReceiver; @@ -49,16 +50,20 @@ import java.util.Set; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.android.server.am.ActivityManagerService.CONTINUE_USER_SWITCH_MSG; +import static com.android.server.am.ActivityManagerService.REPORT_LOCKED_BOOT_COMPLETE_MSG; import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG; import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG; import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG; import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG; import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -71,9 +76,29 @@ public class UserControllerTest extends AndroidTestCase { private UserController mUserController; private TestInjector mInjector; + private static final List START_FOREGROUND_USER_ACTIONS = + Arrays.asList( + Intent.ACTION_USER_STARTED, + Intent.ACTION_USER_SWITCHED, + Intent.ACTION_USER_STARTING); + + private static final List START_BACKGROUND_USER_ACTIONS = + Arrays.asList( + Intent.ACTION_USER_STARTED, + Intent.ACTION_LOCKED_BOOT_COMPLETED, + Intent.ACTION_USER_STARTING); + + private static final Set START_FOREGROUND_USER_MESSAGE_CODES = + new HashSet<>(Arrays.asList(REPORT_USER_SWITCH_MSG, USER_SWITCH_TIMEOUT_MSG, + SYSTEM_USER_START_MSG, SYSTEM_USER_CURRENT_MSG)); + + private static final Set START_BACKGROUND_USER_MESSAGE_CODES = + new HashSet<>(Arrays.asList(SYSTEM_USER_START_MSG, REPORT_LOCKED_BOOT_COMPLETE_MSG)); + @Override public void setUp() throws Exception { super.setUp(); + System.setProperty("dexmaker.share_classloader", "true"); mInjector = new TestInjector(getContext()); mUserController = new UserController(mInjector); setUpUser(TEST_USER_ID, 0); @@ -83,39 +108,62 @@ public class UserControllerTest extends AndroidTestCase { protected void tearDown() throws Exception { super.tearDown(); mInjector.handlerThread.quit(); - } @SmallTest - public void testStartUser() throws RemoteException { - mUserController.startUser(TEST_USER_ID, true); + public void testStartUser_foreground() throws RemoteException { + mUserController.startUser(TEST_USER_ID, true /* foreground */); Mockito.verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt()); Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean()); Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(true); - startUserAssertions(); + Mockito.verify(mInjector.getActivityStackSupervisor()).setLockTaskModeLocked( + nullable(TaskRecord.class), + eq(ActivityManager.LOCK_TASK_MODE_NONE), + anyString(), + anyBoolean()); + startForegroundUserAssertions(); + } + + @SmallTest + public void testStartUser_background() throws RemoteException { + mUserController.startUser(TEST_USER_ID, false /* foreground */); + Mockito.verify( + mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt()); + Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean()); + Mockito.verify(mInjector.getActivityStackSupervisor(), never()).setLockTaskModeLocked( + nullable(TaskRecord.class), + eq(ActivityManager.LOCK_TASK_MODE_NONE), + anyString(), + anyBoolean()); + startBackgroundUserAssertions(); } @SmallTest public void testStartUserUIDisabled() throws RemoteException { mUserController.mUserSwitchUiEnabled = false; - mUserController.startUser(TEST_USER_ID, true); + mUserController.startUser(TEST_USER_ID, true /* foreground */); Mockito.verify(mInjector.getWindowManager(), never()) .startFreezingScreen(anyInt(), anyInt()); Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean()); - startUserAssertions(); + startForegroundUserAssertions(); } - private void startUserAssertions() throws RemoteException { - List expectedActions = Arrays.asList(Intent.ACTION_USER_STARTED, - Intent.ACTION_USER_SWITCHED, Intent.ACTION_USER_STARTING); + private void startUserAssertions( + List expectedActions, Set expectedMessageCodes) + throws RemoteException { assertEquals(expectedActions, getActions(mInjector.sentIntents)); - Set expectedCodes = new HashSet<>( - Arrays.asList(REPORT_USER_SWITCH_MSG, USER_SWITCH_TIMEOUT_MSG, - SYSTEM_USER_START_MSG, SYSTEM_USER_CURRENT_MSG)); Set actualCodes = mInjector.handler.getMessageCodes(); - assertEquals("Unexpected message sent", expectedCodes, actualCodes); + assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes); + } + + private void startBackgroundUserAssertions() throws RemoteException { + startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES); + } + + private void startForegroundUserAssertions() throws RemoteException { + startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES); Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG); assertNotNull(reportMsg); UserState userState = (UserState) reportMsg.obj; @@ -275,6 +323,7 @@ public class UserControllerTest extends AndroidTestCase { UserManagerService userManagerMock; UserManagerInternal userManagerInternalMock; WindowManagerService windowManagerMock; + ActivityStackSupervisor activityStackSupervisor; private Context mCtx; List sentIntents = new ArrayList<>(); @@ -287,6 +336,7 @@ public class UserControllerTest extends AndroidTestCase { userManagerMock = mock(UserManagerService.class); userManagerInternalMock = mock(UserManagerInternal.class); windowManagerMock = mock(WindowManagerService.class); + activityStackSupervisor = mock(ActivityStackSupervisor.class); } @Override @@ -320,12 +370,6 @@ public class UserControllerTest extends AndroidTestCase { return PERMISSION_GRANTED; } - @Override - void stackSupervisorSetLockTaskModeLocked(TaskRecord task, int lockTaskModeState, - String reason, boolean andResume) { - Log.i(TAG, "stackSupervisorSetLockTaskModeLocked"); - } - @Override WindowManagerService getWindowManager() { return windowManagerMock; @@ -346,17 +390,16 @@ public class UserControllerTest extends AndroidTestCase { return 0; } - @Override - boolean stackSupervisorSwitchUserLocked(int userId, UserState uss) { - Log.i(TAG, "stackSupervisorSwitchUserLocked " + userId); - return true; - } - @Override void startHomeActivityLocked(int userId, String reason) { Log.i(TAG, "startHomeActivityLocked " + userId); } - } + + @Override + ActivityStackSupervisor getActivityStackSupervisor() { + return activityStackSupervisor; + } + } private static class TestHandler extends Handler { private final List mMessages = new ArrayList<>();