diff options
4 files changed, 35 insertions, 29 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 280a0dbfe239..540967b0948f 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -63,8 +63,8 @@ package android.app.admin { public class DevicePolicyManager { method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void acknowledgeNewUserDisclaimer(); - method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void clearLogoutUser(); - method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.UserHandle getLogoutUser(); + method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public android.os.UserHandle getLogoutUser(); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public int logoutUser(); field public static final String ACTION_SHOW_NEW_USER_DISCLAIMER = "android.app.action.SHOW_NEW_USER_DISCLAIMER"; } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 96d037c905aa..d74129382480 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -10018,36 +10018,35 @@ public class DevicePolicyManager { } /** - * Gets the user a {@link #logoutUser(ComponentName)} call would switch to, - * or {@code null} if the current user is not in a session. + * Same as {@link #logoutUser(ComponentName)}, but called by system (like Settings), not admin. * * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.CREATE_USERS}) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public @Nullable UserHandle getLogoutUser() { + public @UserOperationResult int logoutUser() { // TODO(b/214336184): add CTS test try { - int userId = mService.getLogoutUserId(); - return userId == UserHandle.USER_NULL ? null : UserHandle.of(userId); + return mService.logoutUserInternal(); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } - /** - * Clears the user that {@link #logoutUser(ComponentName)} would switch to. - * - * <p>Typically used by system UI after it logout a session. + * Gets the user a {@link #logoutUser(ComponentName)} call would switch to, + * or {@code null} if the current user is not in a session. * * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS}) @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public void clearLogoutUser() { + public @Nullable UserHandle getLogoutUser() { // TODO(b/214336184): add CTS test try { - mService.clearLogoutUser(); + int userId = mService.getLogoutUserId(); + return userId == UserHandle.USER_NULL ? null : UserHandle.of(userId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index f663c17c7884..0fc984b239f7 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -264,8 +264,8 @@ interface IDevicePolicyManager { int startUserInBackground(in ComponentName who, in UserHandle userHandle); int stopUser(in ComponentName who, in UserHandle userHandle); int logoutUser(in ComponentName who); + int logoutUserInternal(); // AIDL doesn't allow overloading name (logoutUser()) int getLogoutUserId(); - void clearLogoutUser(); List<UserHandle> getSecondaryUsers(in ComponentName who); void acknowledgeNewUserDisclaimer(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 40196dbbd8b5..b0106934c0e2 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -10977,7 +10977,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public int getLogoutUserId() { - Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())); + Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity()) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS)); return getLogoutUserIdUnchecked(); } @@ -10992,16 +10993,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - @Override - public void clearLogoutUser() { - CallerIdentity caller = getCallerIdentity(); - Preconditions.checkCallAuthorization(canManageUsers(caller)); - - Slogf.i(LOG_TAG, "Clearing logout user as requested by %s", caller); - clearLogoutUserUnchecked(); - } - - private void clearLogoutUserUnchecked() { + private void clearLogoutUser() { if (!mInjector.userManagerIsHeadlessSystemUserMode()) return; // ignore synchronized (getLockObject()) { @@ -11102,6 +11094,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return stopUserUnchecked(callingUserId); } + return logoutUserUnchecked(/* userIdToStop= */ callingUserId); + } + + @Override + public int logoutUserInternal() { + CallerIdentity caller = getCallerIdentity(); + Preconditions.checkCallAuthorization( + canManageUsers(caller) || hasCallingOrSelfPermission(permission.CREATE_USERS)); + + int result = logoutUserUnchecked(getCurrentForegroundUserId()); + Slogf.d(LOG_TAG, "logout called by uid %d. Result: %d", caller.getUid(), result); + return result; + } + + private int logoutUserUnchecked(@UserIdInt int userIdToStop) { int logoutUserId = getLogoutUserIdUnchecked(); if (logoutUserId == UserHandle.USER_NULL) { // Could happen on devices using headless system user mode when called before calling @@ -11117,7 +11124,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // This should never happen as target user is determined by getPreviousUserId() return UserManager.USER_OPERATION_ERROR_UNKNOWN; } - clearLogoutUserUnchecked(); + clearLogoutUser(); } catch (RemoteException e) { // Same process, should not happen. return UserManager.USER_OPERATION_ERROR_UNKNOWN; @@ -11125,7 +11132,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mInjector.binderRestoreCallingIdentity(id); } - return stopUserUnchecked(callingUserId); + return stopUserUnchecked(userIdToStop); } private int stopUserUnchecked(@UserIdInt int userId) { |