diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 40048d9154deb..e81a505a17154 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -87,6 +87,7 @@ interface IUserManager { 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 dbe8dc3e38e20..9e9cd9218a0f5 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -2374,6 +2374,20 @@ public class UserManager { return guest; } + /** + * 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. 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 7500bcd9b8f75..0a5f80f4f95e9 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.content.DialogInterface.BUTTON_POSITIVE; 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 @@ public class UserGridRecyclerView extends RecyclerView { if (userRecord.mIsStartGuestSession) { notifyUserSelected(userRecord); - mCarUserManagerHelper.startGuestSession(mGuestName); + UserInfo guest = createNewOrFindExistingGuest(mContext); + if (guest != null) { + mCarUserManagerHelper.switchToUser(guest); + } return; } @@ -381,6 +385,24 @@ public class UserGridRecyclerView extends RecyclerView { 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 9464eab2085b4..9018290f49556 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 @@ public class UserIconProvider { * @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 14cbe758cd6ab..ad4411c0da4d8 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -3452,8 +3452,13 @@ public class UserManagerService extends IUserManager.Stub { /** * 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 313afbb4ca4c9..dee79bb7b501a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -262,6 +262,19 @@ public class UserManagerTest extends AndroidTestCase { assertNull(userInfo2); } + @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);