Expose findCurrentGuestUser() to system apps

This CL exposes UserManager.findCurrentGuestUser() to system apps.
When switching to Guest user, User Picker needs to know whether or not a
Guest already exists since the system limits only 1 to exist.

Currently, implementations handle this by manually filtering through
getUsers() and checking for isGuest().  Unfortunately, this also means
that callers need to understand the other flags on the UserInfo such as
guestToRemove.

UserManagerService already has code to do this filtering, so expose it
there so there is only one place to handle this logic.

In addition to the above, cleaned up Android Auto uses to utilize the
new API that's available.

Bug: 144379962
Test: Open SysUI User Picker and ensure I could select Guest.  Selecting
a persistent Guest correctly loaded the existing Guest.  Selecting Guest
when one didn't exist correctly created a new Guest.
Change-Id: If877e1c49a751d024c881d1457bea19eefeb1caf
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 40048d9..e81a505 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -87,6 +87,7 @@
     void setDefaultGuestRestrictions(in Bundle restrictions);
     Bundle getDefaultGuestRestrictions();
     boolean markGuestForDeletion(int userId);
+    UserInfo findCurrentGuestUser();
     boolean isQuietModeEnabled(int userId);
     void setSeedAccountData(int userId, in String accountName,
             in String accountType, in PersistableBundle accountOptions, boolean persist);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index bb62eb2..1414fec 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2374,6 +2374,20 @@
     }
 
     /**
+     * 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
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+    public UserInfo findCurrentGuestUser() {
+        try {
+            return mService.findCurrentGuestUser();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Creates a user with the specified name and options as a profile of another user.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * The type of profile must be specified using the given flags.
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index fb1870a..4beca27 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -21,6 +21,7 @@
 import static android.os.UserManager.DISALLOW_ADD_USER;
 import static android.os.UserManager.SWITCHABILITY_STATUS_OK;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
@@ -266,7 +267,10 @@
 
                 if (userRecord.mIsStartGuestSession) {
                     notifyUserSelected(userRecord);
-                    mCarUserManagerHelper.startGuestSession(mGuestName);
+                    UserInfo guest = createNewOrFindExistingGuest(mContext);
+                    if (guest != null) {
+                        mCarUserManagerHelper.switchToUser(guest);
+                    }
                     return;
                 }
 
@@ -353,6 +357,24 @@
             return circleIcon;
         }
 
+        /**
+         * Finds the existing Guest user, or creates one if it doesn't exist.
+         * @param context App context
+         * @return UserInfo representing the Guest user
+         */
+        @Nullable
+        public UserInfo createNewOrFindExistingGuest(Context context) {
+            // CreateGuest will return null if a guest already exists.
+            UserInfo newGuest = mUserManager.createGuest(context, mGuestName);
+            if (newGuest != null) {
+                new UserIconProvider().assignDefaultIcon(
+                        mUserManager, context.getResources(), newGuest);
+                return newGuest;
+            }
+
+            return mUserManager.findCurrentGuestUser();
+        }
+
         @Override
         public void onClick(DialogInterface dialog, int which) {
             if (which == BUTTON_POSITIVE) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserIconProvider.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserIconProvider.java
index 9464eab..9018290 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserIconProvider.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserIconProvider.java
@@ -88,7 +88,7 @@
      * @param userInfo User whose avatar is set to default icon.
      * @return Bitmap of the user icon.
      */
-    private Bitmap assignDefaultIcon(
+    public Bitmap assignDefaultIcon(
             UserManager userManager, Resources resources, UserInfo userInfo) {
         Bitmap bitmap = userInfo.isGuest()
                 ? getGuestUserDefaultIcon(resources)
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8ddfad9..0b0a1b0 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3413,8 +3413,13 @@
     /**
      * Find the current guest user. If the 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
      */
-    private UserInfo findCurrentGuestUser() {
+    @Override
+    public UserInfo findCurrentGuestUser() {
+        checkManageUsersPermission("findCurrentGuestUser");
         synchronized (mUsersLock) {
             final int size = mUsers.size();
             for (int i = 0; i < size; i++) {
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 d071927..92f23ec 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -263,6 +263,19 @@
     }
 
     @MediumTest
+    public void testFindExistingGuest_guestExists() throws Exception {
+        UserInfo userInfo1 = createUser("Guest", UserInfo.FLAG_GUEST);
+        UserInfo foundGuest = mUserManager.findCurrentGuestUser();
+        assertNotNull(foundGuest);
+    }
+
+    @SmallTest
+    public void testFindExistingGuest_guestDoesNotExist() throws Exception {
+        UserInfo foundGuest = mUserManager.findCurrentGuestUser();
+        assertNull(foundGuest);
+    }
+
+    @MediumTest
     public void testSetUserAdmin() throws Exception {
         UserInfo userInfo = createUser("SecondaryUser", /*flags=*/ 0);