Loading core/java/android/os/UserManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -1427,8 +1427,8 @@ public class UserManager { public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** * Specifies if a user is not allowed to run in the background and should be stopped during * user switch. The default value is <code>false</code>. * Specifies if a user is not allowed to run in the background and should be stopped and locked * during user switch. The default value is <code>false</code>. * * <p>This restriction can be set by device owners and profile owners. * Loading services/core/java/com/android/server/am/UserController.java +35 −19 Original line number Diff line number Diff line Loading @@ -1350,41 +1350,57 @@ class UserController implements Handler.Callback { } /** * For mDelayUserDataLocking mode, storage once unlocked is kept unlocked. * Total number of unlocked user storage is limited by mMaxRunningUsers. * If there are more unlocked users, evict and lock the least recently stopped user and * lock that user's data. Regardless of the mode, ephemeral user is always locked * immediately. * Returns which user, if any, should be locked when the given user is stopped. * * For typical (non-mDelayUserDataLocking) devices and users, this will be the provided user. * * However, for some devices or users (based on {@link #canDelayDataLockingForUser(int)}), * storage once unlocked is kept unlocked, even after the user is stopped, so the user to be * locked (if any) may differ. * * For mDelayUserDataLocking devices, the total number of unlocked user storage is limited * (currently by mMaxRunningUsers). If there are more unlocked users, evict and lock the least * recently stopped user and lock that user's data. * * Regardless of the mode, ephemeral user is always locked immediately. * * @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked. */ @GuardedBy("mLock") private int updateUserToLockLU(@UserIdInt int userId, boolean allowDelayedLocking) { int userIdToLock = userId; // TODO: Decouple the delayed locking flows from mMaxRunningUsers or rename the property to // state maximum running unlocked users specifically if (canDelayDataLockingForUser(userIdToLock) && allowDelayedLocking && !getUserInfo(userId).isEphemeral() && !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) { if (!canDelayDataLockingForUser(userId) || !allowDelayedLocking || getUserInfo(userId).isEphemeral() || hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) { return userId; } // Once we reach here, we are in a delayed locking scenario. // Now, no user will be locked, unless the device's policy dictates we should based on the // maximum of such users allowed for the device. if (mDelayUserDataLocking) { // arg should be object, not index mLastActiveUsersForDelayedLocking.remove((Integer) userId); mLastActiveUsersForDelayedLocking.add(0, userId); int totalUnlockedUsers = mStartedUsers.size() + mLastActiveUsersForDelayedLocking.size(); // TODO: Decouple the delayed locking flows from mMaxRunningUsers. These users aren't // running so this calculation shouldn't be based on this parameter. Also note that // that if these devices ever support background running users (such as profiles), the // implementation is incorrect since starting such users can cause the max to be // exceeded. if (totalUnlockedUsers > mMaxRunningUsers) { // should lock a user userIdToLock = mLastActiveUsersForDelayedLocking.get( final int userIdToLock = mLastActiveUsersForDelayedLocking.get( mLastActiveUsersForDelayedLocking.size() - 1); mLastActiveUsersForDelayedLocking .remove(mLastActiveUsersForDelayedLocking.size() - 1); Slogf.i(TAG, "finishUserStopped, stopping user:" + userId + " lock user:" + userIdToLock); } else { Slogf.i(TAG, "finishUserStopped, user:" + userId + ", skip locking"); // do not lock userIdToLock = UserHandle.USER_NULL; Slogf.i(TAG, "finishUserStopped: should stop user " + userId + " but should lock user " + userIdToLock); return userIdToLock; } } return userIdToLock; Slogf.i(TAG, "finishUserStopped: should stop user " + userId + " but without any locking"); return UserHandle.USER_NULL; } /** Loading services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +28 −23 Original line number Diff line number Diff line Loading @@ -682,19 +682,19 @@ public class UserControllerTest { /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); setUpAndStartUserInBackground(TEST_USER_ID); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ null, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID1); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID2); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ null, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID3); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); } Loading Loading @@ -739,21 +739,21 @@ public class UserControllerTest { mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ true); // delayedLocking set and no KeyEvictedCallback, so it should not lock. // allowDelayedLocking set and no KeyEvictedCallback, so it should not lock. setUpAndStartUserInBackground(TEST_USER_ID); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ null, /* expectLocking= */ false); setUpAndStartUserInBackground(TEST_USER_ID1); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID2); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ null, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID3); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); } Loading Loading @@ -843,7 +843,7 @@ public class UserControllerTest { mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE, android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ false); } Loading @@ -855,19 +855,20 @@ public class UserControllerTest { mSetFlagsRule.disableFlags( android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); mSetFlagsRule.disableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags( android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_PRIVATE); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); } /** Delayed-locking users (as opposed to devices) have no limits on how many can be unlocked. */ @Test public void testStopPrivateProfileWithDelayedLocking_maxRunningUsersBreached() public void testStopPrivateProfileWithDelayedLocking_imperviousToNumberOfRunningUsers() throws Exception { mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true, /* maxRunningUsers= */ 1, /* delayUserDataLocking= */ false); Loading @@ -875,10 +876,14 @@ public class UserControllerTest { android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE); setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_MANAGED); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ false); } /** * Tests that when a device/user (managed profile) does not permit delayed locking, then * even if allowDelayedLocking is true, the user will still be locked. */ @Test public void testStopManagedProfileWithDelayedLocking() throws Exception { mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true, Loading @@ -886,7 +891,7 @@ public class UserControllerTest { mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE, android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_MANAGED); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); } Loading Loading @@ -1087,29 +1092,29 @@ public class UserControllerTest { mUserStates.put(userId, mUserController.getStartedUserState(userId)); } private void assertUserLockedOrUnlockedAfterStopping(int userId, boolean delayedLocking, private void assertUserLockedOrUnlockedAfterStopping(int userId, boolean allowDelayedLocking, KeyEvictedCallback keyEvictedCallback, boolean expectLocking) throws Exception { int r = mUserController.stopUser(userId, /* force= */ true, /* delayedLocking= */ delayedLocking, null, keyEvictedCallback); int r = mUserController.stopUser(userId, /* force= */ true, /* allowDelayedLocking= */ allowDelayedLocking, null, keyEvictedCallback); assertThat(r).isEqualTo(ActivityManager.USER_OP_SUCCESS); assertUserLockedOrUnlockedState(userId, delayedLocking, expectLocking); assertUserLockedOrUnlockedState(userId, allowDelayedLocking, expectLocking); } private void assertProfileLockedOrUnlockedAfterStopping(int userId, boolean expectLocking) throws Exception { boolean profileStopped = mUserController.stopProfile(userId); assertThat(profileStopped).isTrue(); assertUserLockedOrUnlockedState(userId, /* delayedLocking= */ false, expectLocking); assertUserLockedOrUnlockedState(userId, /* allowDelayedLocking= */ false, expectLocking); } private void assertUserLockedOrUnlockedState(int userId, boolean delayedLocking, private void assertUserLockedOrUnlockedState(int userId, boolean allowDelayedLocking, boolean expectLocking) throws InterruptedException, RemoteException { // fake all interim steps UserState ussUser = mUserStates.get(userId); ussUser.setState(UserState.STATE_SHUTDOWN); // Passing delayedLocking invalidates incorrect internal data passing but currently there is // no easy way to get that information passed through lambda. mUserController.finishUserStopped(ussUser, delayedLocking); mUserController.finishUserStopped(ussUser, allowDelayedLocking); waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS); verify(mInjector.mStorageManagerMock, times(expectLocking ? 1 : 0)) .lockCeStorage(userId); Loading Loading
core/java/android/os/UserManager.java +2 −2 Original line number Diff line number Diff line Loading @@ -1427,8 +1427,8 @@ public class UserManager { public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** * Specifies if a user is not allowed to run in the background and should be stopped during * user switch. The default value is <code>false</code>. * Specifies if a user is not allowed to run in the background and should be stopped and locked * during user switch. The default value is <code>false</code>. * * <p>This restriction can be set by device owners and profile owners. * Loading
services/core/java/com/android/server/am/UserController.java +35 −19 Original line number Diff line number Diff line Loading @@ -1350,41 +1350,57 @@ class UserController implements Handler.Callback { } /** * For mDelayUserDataLocking mode, storage once unlocked is kept unlocked. * Total number of unlocked user storage is limited by mMaxRunningUsers. * If there are more unlocked users, evict and lock the least recently stopped user and * lock that user's data. Regardless of the mode, ephemeral user is always locked * immediately. * Returns which user, if any, should be locked when the given user is stopped. * * For typical (non-mDelayUserDataLocking) devices and users, this will be the provided user. * * However, for some devices or users (based on {@link #canDelayDataLockingForUser(int)}), * storage once unlocked is kept unlocked, even after the user is stopped, so the user to be * locked (if any) may differ. * * For mDelayUserDataLocking devices, the total number of unlocked user storage is limited * (currently by mMaxRunningUsers). If there are more unlocked users, evict and lock the least * recently stopped user and lock that user's data. * * Regardless of the mode, ephemeral user is always locked immediately. * * @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked. */ @GuardedBy("mLock") private int updateUserToLockLU(@UserIdInt int userId, boolean allowDelayedLocking) { int userIdToLock = userId; // TODO: Decouple the delayed locking flows from mMaxRunningUsers or rename the property to // state maximum running unlocked users specifically if (canDelayDataLockingForUser(userIdToLock) && allowDelayedLocking && !getUserInfo(userId).isEphemeral() && !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) { if (!canDelayDataLockingForUser(userId) || !allowDelayedLocking || getUserInfo(userId).isEphemeral() || hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) { return userId; } // Once we reach here, we are in a delayed locking scenario. // Now, no user will be locked, unless the device's policy dictates we should based on the // maximum of such users allowed for the device. if (mDelayUserDataLocking) { // arg should be object, not index mLastActiveUsersForDelayedLocking.remove((Integer) userId); mLastActiveUsersForDelayedLocking.add(0, userId); int totalUnlockedUsers = mStartedUsers.size() + mLastActiveUsersForDelayedLocking.size(); // TODO: Decouple the delayed locking flows from mMaxRunningUsers. These users aren't // running so this calculation shouldn't be based on this parameter. Also note that // that if these devices ever support background running users (such as profiles), the // implementation is incorrect since starting such users can cause the max to be // exceeded. if (totalUnlockedUsers > mMaxRunningUsers) { // should lock a user userIdToLock = mLastActiveUsersForDelayedLocking.get( final int userIdToLock = mLastActiveUsersForDelayedLocking.get( mLastActiveUsersForDelayedLocking.size() - 1); mLastActiveUsersForDelayedLocking .remove(mLastActiveUsersForDelayedLocking.size() - 1); Slogf.i(TAG, "finishUserStopped, stopping user:" + userId + " lock user:" + userIdToLock); } else { Slogf.i(TAG, "finishUserStopped, user:" + userId + ", skip locking"); // do not lock userIdToLock = UserHandle.USER_NULL; Slogf.i(TAG, "finishUserStopped: should stop user " + userId + " but should lock user " + userIdToLock); return userIdToLock; } } return userIdToLock; Slogf.i(TAG, "finishUserStopped: should stop user " + userId + " but without any locking"); return UserHandle.USER_NULL; } /** Loading
services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +28 −23 Original line number Diff line number Diff line Loading @@ -682,19 +682,19 @@ public class UserControllerTest { /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false); setUpAndStartUserInBackground(TEST_USER_ID); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ null, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID1); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID2); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ null, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID3); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); } Loading Loading @@ -739,21 +739,21 @@ public class UserControllerTest { mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true, /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ true); // delayedLocking set and no KeyEvictedCallback, so it should not lock. // allowDelayedLocking set and no KeyEvictedCallback, so it should not lock. setUpAndStartUserInBackground(TEST_USER_ID); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ null, /* expectLocking= */ false); setUpAndStartUserInBackground(TEST_USER_ID1); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID2); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ null, /* expectLocking= */ true); setUpAndStartUserInBackground(TEST_USER_ID3); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* delayedLocking= */ false, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID3, /* allowDelayedLocking= */ false, /* keyEvictedCallback= */ mKeyEvictedCallback, /* expectLocking= */ true); } Loading Loading @@ -843,7 +843,7 @@ public class UserControllerTest { mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE, android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ false); } Loading @@ -855,19 +855,20 @@ public class UserControllerTest { mSetFlagsRule.disableFlags( android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); mSetFlagsRule.disableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE); mSetFlagsRule.enableFlags( android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_PRIVATE); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID2, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); } /** Delayed-locking users (as opposed to devices) have no limits on how many can be unlocked. */ @Test public void testStopPrivateProfileWithDelayedLocking_maxRunningUsersBreached() public void testStopPrivateProfileWithDelayedLocking_imperviousToNumberOfRunningUsers() throws Exception { mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true, /* maxRunningUsers= */ 1, /* delayUserDataLocking= */ false); Loading @@ -875,10 +876,14 @@ public class UserControllerTest { android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_PRIVATE); setUpAndStartProfileInBackground(TEST_USER_ID2, UserManager.USER_TYPE_PROFILE_MANAGED); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ false); } /** * Tests that when a device/user (managed profile) does not permit delayed locking, then * even if allowDelayedLocking is true, the user will still be locked. */ @Test public void testStopManagedProfileWithDelayedLocking() throws Exception { mUserController.setInitialConfig(/* mUserSwitchUiEnabled */ true, Loading @@ -886,7 +891,7 @@ public class UserControllerTest { mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE, android.multiuser.Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE); setUpAndStartProfileInBackground(TEST_USER_ID1, UserManager.USER_TYPE_PROFILE_MANAGED); assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* delayedLocking= */ true, assertUserLockedOrUnlockedAfterStopping(TEST_USER_ID1, /* allowDelayedLocking= */ true, /* keyEvictedCallback */ null, /* expectLocking= */ true); } Loading Loading @@ -1087,29 +1092,29 @@ public class UserControllerTest { mUserStates.put(userId, mUserController.getStartedUserState(userId)); } private void assertUserLockedOrUnlockedAfterStopping(int userId, boolean delayedLocking, private void assertUserLockedOrUnlockedAfterStopping(int userId, boolean allowDelayedLocking, KeyEvictedCallback keyEvictedCallback, boolean expectLocking) throws Exception { int r = mUserController.stopUser(userId, /* force= */ true, /* delayedLocking= */ delayedLocking, null, keyEvictedCallback); int r = mUserController.stopUser(userId, /* force= */ true, /* allowDelayedLocking= */ allowDelayedLocking, null, keyEvictedCallback); assertThat(r).isEqualTo(ActivityManager.USER_OP_SUCCESS); assertUserLockedOrUnlockedState(userId, delayedLocking, expectLocking); assertUserLockedOrUnlockedState(userId, allowDelayedLocking, expectLocking); } private void assertProfileLockedOrUnlockedAfterStopping(int userId, boolean expectLocking) throws Exception { boolean profileStopped = mUserController.stopProfile(userId); assertThat(profileStopped).isTrue(); assertUserLockedOrUnlockedState(userId, /* delayedLocking= */ false, expectLocking); assertUserLockedOrUnlockedState(userId, /* allowDelayedLocking= */ false, expectLocking); } private void assertUserLockedOrUnlockedState(int userId, boolean delayedLocking, private void assertUserLockedOrUnlockedState(int userId, boolean allowDelayedLocking, boolean expectLocking) throws InterruptedException, RemoteException { // fake all interim steps UserState ussUser = mUserStates.get(userId); ussUser.setState(UserState.STATE_SHUTDOWN); // Passing delayedLocking invalidates incorrect internal data passing but currently there is // no easy way to get that information passed through lambda. mUserController.finishUserStopped(ussUser, delayedLocking); mUserController.finishUserStopped(ussUser, allowDelayedLocking); waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS); verify(mInjector.mStorageManagerMock, times(expectLocking ? 1 : 0)) .lockCeStorage(userId); Loading