summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/module-lib-current.txt4
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java25
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java33
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) {