From 910c700b3405abe394cbe3d9f4726e044c9d2f79 Mon Sep 17 00:00:00 2001 From: Mayank Garg Date: Thu, 7 Oct 2021 15:08:22 -0700 Subject: [PATCH] Added removeUserWhenPossible API as SystemAPI Also converted following APIs to SystemAPI: android.os.UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED android.os.UserManager.REMOVE_RESULT_ERROR android.os.UserManager.REMOVE_RESULT_DEFERRED android.os.UserManager.REMOVE_RESULT_REMOVED Remaining task: remove all occurance of UserManager.removeUserOrSetEphemeral Bug: 197181121 Bug: 199446770 Bug: 199446810 CTS-Coverage-Bug: 199446770 Test: m system-api-stubs-docs-non-updatable-update-current-api m module-lib-api-stubs-docs-non-updatable-update-current-api Change-Id: Iea7867268950050f90d8509d7f3d09725d850a5e --- core/api/system-current.txt | 5 ++ core/java/android/os/UserManager.java | 64 +++++++++++++++---- .../server/pm/PackageManagerShellCommand.java | 2 +- .../android/server/pm/UserManagerService.java | 2 +- .../android/server/pm/UserManagerTest.java | 2 +- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 75c9be966f816..92e1da0b44402 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9323,6 +9323,7 @@ package android.os { method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isUserOfType(@NonNull String); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isUserUnlockingOrUnlocked(@NonNull android.os.UserHandle); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean removeUser(@NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public int removeUserWhenPossible(@NonNull android.os.UserHandle, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap) throws android.os.UserManager.UserOperationException; method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean someUserHasAccount(@NonNull String, @NonNull String); @@ -9330,6 +9331,10 @@ package android.os { field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED"; field @Deprecated public static final String DISALLOW_OEM_UNLOCK = "no_oem_unlock"; field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background"; + field public static final int REMOVE_RESULT_ALREADY_BEING_REMOVED = 2; // 0x2 + field public static final int REMOVE_RESULT_DEFERRED = 1; // 0x1 + field public static final int REMOVE_RESULT_ERROR = 3; // 0x3 + field public static final int REMOVE_RESULT_REMOVED = 0; // 0x0 field public static final int RESTRICTION_NOT_SET = 0; // 0x0 field public static final int RESTRICTION_SOURCE_DEVICE_OWNER = 2; // 0x2 field public static final int RESTRICTION_SOURCE_PROFILE_OWNER = 4; // 0x4 diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index b3639e419a563..9d22f8ad4bf2b 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1657,41 +1657,49 @@ public class UserManager { public @interface UserSwitchabilityResult {} /** - * A response code from {@link #removeUserOrSetEphemeral(int)} indicating that the specified - * user has been successfully removed. + * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that + * the specified user has been successfully removed. + * * @hide */ + @SystemApi public static final int REMOVE_RESULT_REMOVED = 0; /** - * A response code from {@link #removeUserOrSetEphemeral(int)} indicating that the specified - * user has had its {@link UserInfo#FLAG_EPHEMERAL} flag set to {@code true}, so that it will be - * removed when the user is stopped or on boot. + * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that + * the specified user is marked so that it will be removed when the user is stopped or on boot. + * * @hide */ - public static final int REMOVE_RESULT_SET_EPHEMERAL = 1; + @SystemApi + public static final int REMOVE_RESULT_DEFERRED = 1; /** - * A response code from {@link #removeUserOrSetEphemeral(int)} indicating that the specified - * user is already in the process of being removed. + * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that + * the specified user is already in the process of being removed. + * * @hide */ + @SystemApi public static final int REMOVE_RESULT_ALREADY_BEING_REMOVED = 2; /** - * A response code from {@link #removeUserOrSetEphemeral(int)} indicating that an error occurred - * that prevented the user from being removed or set as ephemeral. + * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that + * an error occurred that prevented the user from being removed or set as ephemeral. + * * @hide */ + @SystemApi public static final int REMOVE_RESULT_ERROR = 3; /** - * Possible response codes from {@link #removeUserOrSetEphemeral(int)}. + * Possible response codes from {@link #removeUserWhenPossible(UserHandle, boolean)}. + * * @hide */ @IntDef(prefix = { "REMOVE_RESULT_" }, value = { REMOVE_RESULT_REMOVED, - REMOVE_RESULT_SET_EPHEMERAL, + REMOVE_RESULT_DEFERRED, REMOVE_RESULT_ALREADY_BEING_REMOVED, REMOVE_RESULT_ERROR, }) @@ -4728,12 +4736,42 @@ public class UserManager { * the current user, then set the user as ephemeral so that it will be removed when it is * stopped. * - * @param evenWhenDisallowed when {@code true}, user is removed even if the caller user has the + * @param overrideDevicePolicy when {@code true}, user is removed even if the caller has + * the {@link #DISALLOW_REMOVE_USER} or {@link #DISALLOW_REMOVE_MANAGED_PROFILE} restriction + * + * @return the result code {@link #REMOVE_RESULT_REMOVED}, {@link #REMOVE_RESULT_DEFERRED}, + * {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED}, or {@link #REMOVE_RESULT_ERROR}. + * + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, + Manifest.permission.CREATE_USERS}) + public int removeUserWhenPossible(@NonNull UserHandle user, + boolean overrideDevicePolicy) { + try { + return mService.removeUserOrSetEphemeral(user.getIdentifier(), overrideDevicePolicy); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * Immediately removes the user or, if the user cannot be removed, such as when the user is + * the current user, then set the user as ephemeral so that it will be removed when it is + * stopped. + * + * @param evenWhenDisallowed when {@code true}, user is removed even if the caller has the * {@link #DISALLOW_REMOVE_USER} or {@link #DISALLOW_REMOVE_MANAGED_PROFILE} restriction * * @return the {@link RemoveResult} code + * + * @deprecated TODO(b/199446770): remove this call after converting all calls to + * removeUserWhenPossible(UserHandle, boolean) + * * @hide */ + @Deprecated @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) public @RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId, diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 0564e858c84c5..be2bdaac13e47 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -2816,7 +2816,7 @@ class PackageManagerShellCommand extends ShellCommand { case UserManager.REMOVE_RESULT_REMOVED: getOutPrintWriter().printf("Success: user %d removed\n", userId); return 0; - case UserManager.REMOVE_RESULT_SET_EPHEMERAL: + case UserManager.REMOVE_RESULT_DEFERRED: getOutPrintWriter().printf("Success: user %d set as ephemeral\n", userId); return 0; case UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED: diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 167ad3ba7d0e3..543e8a9009fd2 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -4478,7 +4478,7 @@ public class UserManagerService extends IUserManager.Stub { userData.info.flags |= UserInfo.FLAG_EPHEMERAL; writeUserLP(userData); - return UserManager.REMOVE_RESULT_SET_EPHEMERAL; + return UserManager.REMOVE_RESULT_DEFERRED; } } finally { Binder.restoreCallingIdentity(ident); 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 cf6165fdbd796..e4273dce78931 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -375,7 +375,7 @@ public final class UserManagerTest { switchUser(user1.id, null, /* ignoreHandle= */ true); assertThat(mUserManager.removeUserOrSetEphemeral(user1.id, /* evenWhenDisallowed= */ false)) - .isEqualTo(UserManager.REMOVE_RESULT_SET_EPHEMERAL); + .isEqualTo(UserManager.REMOVE_RESULT_DEFERRED); assertThat(hasUser(user1.id)).isTrue(); assertThat(getUser(user1.id).isEphemeral()).isTrue();