diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index c2ddf4535d915..1490c6a32fbd7 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -101,7 +101,7 @@ interface IUserManager { Bundle getDefaultGuestRestrictions(); int removeUserWhenPossible(int userId, boolean overrideDevicePolicy); boolean markGuestForDeletion(int userId); - UserInfo findCurrentGuestUser(); + List getGuestUsers(); boolean isQuietModeEnabled(int userId); UserHandle createUserWithAttributes(in String userName, in String userType, int flags, in Bitmap userIcon, diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 5f2f710e3c015..08d15c72c47fb 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -3682,15 +3682,36 @@ public class UserManager { } } + // TODO(b/256690588): Remove this after removing its callsites. /** * Gets the existing guest user if it exists. This does not include guest users that are dying. * @return The existing guest user if it exists. Null otherwise. * @hide + * + * @deprecated Use {@link #getGuestUsers()} */ + @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public UserInfo findCurrentGuestUser() { try { - return mService.findCurrentGuestUser(); + final List guestUsers = mService.getGuestUsers(); + if (guestUsers.size() == 0) { + return null; + } + return guestUsers.get(0); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * Returns the existing guest users. This does not include guest users that are dying. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + public @NonNull List getGuestUsers() { + try { + return mService.getGuestUsers(); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 251da8441e0be..365e0ebe2e070 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -2440,8 +2440,8 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mGuestRestrictions) { mGuestRestrictions.clear(); mGuestRestrictions.putAll(restrictions); - UserInfo guest = findCurrentGuestUser(); - if (guest != null) { + final List guests = getGuestUsers(); + for (UserInfo guest : guests) { synchronized (mRestrictionsLock) { updateUserRestrictionsInternalLR(mGuestRestrictions, guest.id); } @@ -3687,10 +3687,12 @@ public class UserManagerService extends IUserManager.Stub { ); } // DISALLOW_CONFIG_WIFI was made a default guest restriction some time during version 6. - final UserInfo currentGuestUser = findCurrentGuestUser(); - if (currentGuestUser != null && !hasUserRestriction( - UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) { - setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id); + final List guestUsers = getGuestUsers(); + for (UserInfo guestUser : guestUsers) { + if (guestUser != null && !hasUserRestriction( + UserManager.DISALLOW_CONFIG_WIFI, guestUser.id)) { + setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, guestUser.id); + } } userVersion = 7; } @@ -5233,26 +5235,26 @@ public class UserManagerService extends IUserManager.Stub { } /** - * Find the current guest user. If the Guest user is partial, + * Gets the existing guest users. If a Guest user is partial, * then do not include it in the results as it is about to die. * - * @return The current guest user. Null if it doesn't exist. - * @hide + * @return list of existing Guest users currently on the device. */ @Override - public UserInfo findCurrentGuestUser() { - checkManageUsersPermission("findCurrentGuestUser"); + public List getGuestUsers() { + checkManageUsersPermission("getGuestUsers"); + final ArrayList guestUsers = new ArrayList<>(); synchronized (mUsersLock) { final int size = mUsers.size(); for (int i = 0; i < size; i++) { final UserInfo user = mUsers.valueAt(i).info; if (user.isGuest() && !user.guestToRemove && !user.preCreated && !mRemovingUserIds.get(user.id)) { - return user; + guestUsers.add(user); } } } - return null; + return guestUsers; } /** diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 2e7e583ad8376..1b8d81d952810 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -48,6 +48,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; import org.junit.After; @@ -495,10 +496,22 @@ public final class UserManagerTest { removeUser(userInfo.id); } + private void requireSingleGuest() throws Exception { + assumeTrue("device supports single guest", + UserTypeFactory.getUserTypes().get(UserManager.USER_TYPE_FULL_GUEST) + .getMaxAllowed() == 1); + } + + private void requireMultipleGuests() throws Exception { + assumeTrue("device supports multiple guests", + UserTypeFactory.getUserTypes().get(UserManager.USER_TYPE_FULL_GUEST) + .getMaxAllowed() > 1); + } @MediumTest @Test - public void testThereCanBeOnlyOneGuest() throws Exception { + public void testThereCanBeOnlyOneGuest_singleGuest() throws Exception { + requireSingleGuest(); assertThat(mUserManager.canAddMoreUsers(mUserManager.USER_TYPE_FULL_GUEST)).isTrue(); UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST); assertThat(userInfo1).isNotNull(); @@ -507,6 +520,18 @@ public final class UserManagerTest { assertThat(userInfo2).isNull(); } + @MediumTest + @Test + public void testThereCanBeMultipleGuests_multipleGuests() throws Exception { + requireMultipleGuests(); + assertThat(mUserManager.canAddMoreUsers(mUserManager.USER_TYPE_FULL_GUEST)).isTrue(); + UserInfo userInfo1 = createUser("Guest 1", UserInfo.FLAG_GUEST); + assertThat(userInfo1).isNotNull(); + assertThat(mUserManager.canAddMoreUsers(mUserManager.USER_TYPE_FULL_GUEST)).isTrue(); + UserInfo userInfo2 = createUser("Guest 2", UserInfo.FLAG_GUEST); + assertThat(userInfo2).isNotNull(); + } + @MediumTest @Test public void testFindExistingGuest_guestExists() throws Exception { @@ -516,6 +541,54 @@ public final class UserManagerTest { assertThat(foundGuest).isNotNull(); } + @MediumTest + @Test + public void testGetGuestUsers_singleGuest() throws Exception { + requireSingleGuest(); + UserInfo userInfo1 = createUser("Guest1", UserInfo.FLAG_GUEST); + assertThat(userInfo1).isNotNull(); + List guestsFound = mUserManager.getGuestUsers(); + assertThat(guestsFound).hasSize(1); + assertThat(guestsFound.get(0).name).isEqualTo("Guest1"); + } + + @MediumTest + @Test + public void testGetGuestUsers_multipleGuests() throws Exception { + requireMultipleGuests(); + UserInfo userInfo1 = createUser("Guest1", UserInfo.FLAG_GUEST); + assertThat(userInfo1).isNotNull(); + UserInfo userInfo2 = createUser("Guest2", UserInfo.FLAG_GUEST); + assertThat(userInfo2).isNotNull(); + + List guestsFound = mUserManager.getGuestUsers(); + assertThat(guestsFound).hasSize(2); + assertThat(ImmutableList.of(guestsFound.get(0).name, guestsFound.get(1).name)) + .containsExactly("Guest1", "Guest2"); + } + + @MediumTest + @Test + public void testGetGuestUsers_markGuestForDeletion() throws Exception { + requireMultipleGuests(); + UserInfo userInfo1 = createUser("Guest1", UserInfo.FLAG_GUEST); + assertThat(userInfo1).isNotNull(); + UserInfo userInfo2 = createUser("Guest2", UserInfo.FLAG_GUEST); + assertThat(userInfo2).isNotNull(); + + boolean markedForDeletion1 = mUserManager.markGuestForDeletion(userInfo1.id); + assertThat(markedForDeletion1).isTrue(); + + List guestsFound = mUserManager.getGuestUsers(); + assertThat(guestsFound.size()).isEqualTo(1); + + boolean markedForDeletion2 = mUserManager.markGuestForDeletion(userInfo2.id); + assertThat(markedForDeletion2).isTrue(); + + guestsFound = mUserManager.getGuestUsers(); + assertThat(guestsFound).isEmpty(); + } + @SmallTest @Test public void testFindExistingGuest_guestDoesNotExist() throws Exception { @@ -523,6 +596,13 @@ public final class UserManagerTest { assertThat(foundGuest).isNull(); } + @SmallTest + @Test + public void testGetGuestUsers_guestDoesNotExist() throws Exception { + List guestsFound = mUserManager.getGuestUsers(); + assertThat(guestsFound).isEmpty(); + } + @MediumTest @Test public void testSetUserAdmin() throws Exception {