Add getGuestUsers API now that multiple guests are allowed

Bug: 256690588
Test: atest com.android.server.pm.UserManagerTest
Change-Id: Id7466cc860d5501be00df70c4c5a8f3a4e2183ec
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index d31540a..d988826 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -100,7 +100,7 @@
     Bundle getDefaultGuestRestrictions();
     int removeUserWhenPossible(int userId, boolean overrideDevicePolicy);
     boolean markGuestForDeletion(int userId);
-    UserInfo findCurrentGuestUser();
+    List<UserInfo> 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 dd02e02..71f6fc4 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3713,15 +3713,36 @@
         }
     }
 
+    // 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<UserInfo> 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<UserInfo> 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 3234e87..5d61a8a 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2380,8 +2380,8 @@
         synchronized (mGuestRestrictions) {
             mGuestRestrictions.clear();
             mGuestRestrictions.putAll(restrictions);
-            UserInfo guest = findCurrentGuestUser();
-            if (guest != null) {
+            final List<UserInfo> guests = getGuestUsers();
+            for (UserInfo guest : guests) {
                 synchronized (mRestrictionsLock) {
                     updateUserRestrictionsInternalLR(mGuestRestrictions, guest.id);
                 }
@@ -3627,10 +3627,12 @@
                 );
             }
             // 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<UserInfo> 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;
         }
@@ -5173,26 +5175,26 @@
     }
 
     /**
-     * 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<UserInfo> getGuestUsers() {
+        checkManageUsersPermission("getGuestUsers");
+        final ArrayList<UserInfo> 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 2e7e583..1b8d81d 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.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 @@
         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();
@@ -509,6 +522,18 @@
 
     @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 {
         UserInfo userInfo1 = createUser("Guest", UserInfo.FLAG_GUEST);
         assertThat(userInfo1).isNotNull();
@@ -516,6 +541,54 @@
         assertThat(foundGuest).isNotNull();
     }
 
+    @MediumTest
+    @Test
+    public void testGetGuestUsers_singleGuest() throws Exception {
+        requireSingleGuest();
+        UserInfo userInfo1 = createUser("Guest1", UserInfo.FLAG_GUEST);
+        assertThat(userInfo1).isNotNull();
+        List<UserInfo> 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<UserInfo> 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<UserInfo> 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 @@
         assertThat(foundGuest).isNull();
     }
 
+    @SmallTest
+    @Test
+    public void testGetGuestUsers_guestDoesNotExist() throws Exception {
+        List<UserInfo> guestsFound = mUserManager.getGuestUsers();
+        assertThat(guestsFound).isEmpty();
+    }
+
     @MediumTest
     @Test
     public void testSetUserAdmin() throws Exception {