From 5d7f9056ee8d817832625da43ce47611c082c44e Mon Sep 17 00:00:00 2001 From: Anthony Hugh Date: Wed, 13 Nov 2019 16:48:28 -0800 Subject: [PATCH] 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 --- core/java/android/os/IUserManager.aidl | 1 + core/java/android/os/UserManager.java | 14 +++++++++++ .../statusbar/car/UserGridRecyclerView.java | 24 ++++++++++++++++++- .../statusbar/car/UserIconProvider.java | 2 +- .../android/server/pm/UserManagerService.java | 7 +++++- .../android/server/pm/UserManagerTest.java | 13 ++++++++++ 6 files changed, 58 insertions(+), 3 deletions(-) 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 bb62eb25b1a43..1414fecae348b 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -2373,6 +2373,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 fb1870a6ea42e..4beca2743808f 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; } @@ -353,6 +357,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 8ddfad9ec81c8..0b0a1b06c2e28 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 @@ 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 d071927681820..92f23ec6518f8 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);