summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp3
-rw-r--r--framework-s/Android.bp6
-rw-r--r--framework-s/java/android/app/role/IRoleManager.aidl14
-rw-r--r--framework-s/java/android/app/role/RoleManager.java49
-rw-r--r--service/java/com/android/role/RoleService.java77
5 files changed, 116 insertions, 33 deletions
diff --git a/Android.bp b/Android.bp
index bf7437814..59742acc1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -21,6 +21,9 @@ apex {
name: "com.android.permission",
defaults: ["com.android.permission-defaults"],
manifest: "apex_manifest.json",
+ compat_configs: [
+ "framework-permission-s-compat-config"
+ ],
}
apex_defaults {
diff --git a/framework-s/Android.bp b/framework-s/Android.bp
index 076b497cb..096992362 100644
--- a/framework-s/Android.bp
+++ b/framework-s/Android.bp
@@ -56,6 +56,11 @@ java_library {
sdk_version: "module_current",
}
+platform_compat_config {
+ name: "framework-permission-s-compat-config",
+ src: ":framework-permission-s",
+}
+
java_sdk_library {
name: "framework-permission-s",
defaults: ["framework-module-defaults"],
@@ -64,6 +69,7 @@ java_sdk_library {
],
libs: [
"androidx.annotation_annotation",
+ "app-compat-annotations",
"framework-annotations-lib",
],
static_libs: [
diff --git a/framework-s/java/android/app/role/IRoleManager.aidl b/framework-s/java/android/app/role/IRoleManager.aidl
index 5bcda037e..581bb20fa 100644
--- a/framework-s/java/android/app/role/IRoleManager.aidl
+++ b/framework-s/java/android/app/role/IRoleManager.aidl
@@ -25,9 +25,9 @@ import android.os.RemoteCallback;
*/
interface IRoleManager {
- boolean isRoleAvailable(in String roleName);
+ boolean isRoleAvailableAsUser(in String roleName, int userId);
- boolean isRoleHeld(in String roleName, in String packageName);
+ boolean isRoleHeldAsUser(in String roleName, in String packageName, int userId);
List<String> getRoleHoldersAsUser(in String roleName, int userId);
@@ -58,13 +58,15 @@ interface IRoleManager {
void setRoleFallbackEnabledAsUser(in String roleName, boolean fallbackEnabled, int userId);
- void setRoleNamesFromController(in List<String> roleNames);
+ void setRoleNamesFromControllerAsUser(in List<String> roleNames, int userId);
- boolean addRoleHolderFromController(in String roleName, in String packageName);
+ boolean addRoleHolderFromControllerAsUser(in String roleName, in String packageName,
+ int userId);
- boolean removeRoleHolderFromController(in String roleName, in String packageName);
+ boolean removeRoleHolderFromControllerAsUser(in String roleName, in String packageName,
+ int userId);
- List<String> getHeldRolesFromController(in String packageName);
+ List<String> getHeldRolesFromControllerAsUser(in String packageName, int userId);
String getBrowserRoleHolder(int userId);
diff --git a/framework-s/java/android/app/role/RoleManager.java b/framework-s/java/android/app/role/RoleManager.java
index cb3ebfe3c..4d8e4a1d8 100644
--- a/framework-s/java/android/app/role/RoleManager.java
+++ b/framework-s/java/android/app/role/RoleManager.java
@@ -28,6 +28,9 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.UserHandleAware;
import android.annotation.UserIdInt;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
@@ -212,6 +215,17 @@ public final class RoleManager {
public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1;
/**
+ * For apps targeting Android V and above, several methods are now user-handle-aware, which
+ * means they use the user contained within the context. For apps targeting an SDK version
+ * <em>below</em> this, the user of the calling process will be used.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ public static final long ROLE_MANAGER_USER_HANDLE_AWARE = 303742236L;
+
+ /**
* The action used to request user approval of a role for an application.
*
* @hide
@@ -286,10 +300,12 @@ public final class RoleManager {
*
* @return whether the role is available in the system
*/
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public boolean isRoleAvailable(@NonNull String roleName) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
+ UserHandle user = getContextUserIfAppropriate();
try {
- return mService.isRoleAvailable(roleName);
+ return mService.isRoleAvailableAsUser(roleName, user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -302,10 +318,13 @@ public final class RoleManager {
*
* @return whether the calling application is holding the role
*/
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public boolean isRoleHeld(@NonNull String roleName) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
+ UserHandle user = getContextUserIfAppropriate();
try {
- return mService.isRoleHeld(roleName, mContext.getPackageName());
+ return mService.isRoleHeldAsUser(roleName, mContext.getPackageName(),
+ user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -328,8 +347,9 @@ public final class RoleManager {
@NonNull
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public List<String> getRoleHolders(@NonNull String roleName) {
- return getRoleHoldersAsUser(roleName, Process.myUserHandle());
+ return getRoleHoldersAsUser(roleName, getContextUserIfAppropriate());
}
/**
@@ -755,10 +775,12 @@ public final class RoleManager {
@Deprecated
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public void setRoleNamesFromController(@NonNull List<String> roleNames) {
Objects.requireNonNull(roleNames, "roleNames cannot be null");
+ UserHandle user = getContextUserIfAppropriate();
try {
- mService.setRoleNamesFromController(roleNames);
+ mService.setRoleNamesFromControllerAsUser(roleNames, user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -789,12 +811,15 @@ public final class RoleManager {
@Deprecated
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public boolean addRoleHolderFromController(@NonNull String roleName,
@NonNull String packageName) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
+ UserHandle user = getContextUserIfAppropriate();
try {
- return mService.addRoleHolderFromController(roleName, packageName);
+ return mService.addRoleHolderFromControllerAsUser(roleName, packageName,
+ user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -825,12 +850,15 @@ public final class RoleManager {
@Deprecated
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public boolean removeRoleHolderFromController(@NonNull String roleName,
@NonNull String packageName) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
+ UserHandle user = getContextUserIfAppropriate();
try {
- return mService.removeRoleHolderFromController(roleName, packageName);
+ return mService.removeRoleHolderFromControllerAsUser(roleName, packageName,
+ user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -851,15 +879,22 @@ public final class RoleManager {
@NonNull
@RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER)
@SystemApi
+ @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public List<String> getHeldRolesFromController(@NonNull String packageName) {
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
+ UserHandle user = getContextUserIfAppropriate();
try {
- return mService.getHeldRolesFromController(packageName);
+ return mService.getHeldRolesFromControllerAsUser(packageName, user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
+ private UserHandle getContextUserIfAppropriate() {
+ return CompatChanges.isChangeEnabled(ROLE_MANAGER_USER_HANDLE_AWARE) ? mContext.getUser()
+ : Process.myUserHandle();
+ }
+
/**
* Get the role holder of {@link #ROLE_BROWSER} without requiring
* {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in
diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java
index 6845d506b..189b61f3e 100644
--- a/service/java/com/android/role/RoleService.java
+++ b/service/java/com/android/role/RoleService.java
@@ -415,22 +415,33 @@ public class RoleService extends SystemService implements RoleUserState.Callback
private class Stub extends IRoleManager.Stub {
@Override
- public boolean isRoleAvailable(@NonNull String roleName) {
+ public boolean isRoleAvailableAsUser(@NonNull String roleName, @UserIdInt int userId) {
+ UserUtils.enforceCrossUserPermission(userId, false, "isRoleAvailableAsUser",
+ getContext());
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return false;
+ }
+
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
- int userId = UserHandleCompat.getUserId(getCallingUid());
return getOrCreateUserState(userId).isRoleAvailable(roleName);
}
@Override
- public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) {
- int callingUid = getCallingUid();
- mAppOpsManager.checkPackage(callingUid, packageName);
+ public boolean isRoleHeldAsUser(@NonNull String roleName, @NonNull String packageName,
+ @UserIdInt int userId) {
+ mAppOpsManager.checkPackage(getCallingUid(), packageName);
+
+ UserUtils.enforceCrossUserPermission(userId, false, "isRoleHeldAsUser", getContext());
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return false;
+ }
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
- int userId = UserHandleCompat.getUserId(callingUid);
ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
if (roleHolders == null) {
return false;
@@ -685,54 +696,80 @@ public class RoleService extends SystemService implements RoleUserState.Callback
}
@Override
- public void setRoleNamesFromController(@NonNull List<String> roleNames) {
+ public void setRoleNamesFromControllerAsUser(@NonNull List<String> roleNames,
+ @UserIdInt int userId) {
+ UserUtils.enforceCrossUserPermission(userId, false, "setRoleNamesFromControllerAsUser",
+ getContext());
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return;
+ }
+
getContext().enforceCallingOrSelfPermission(
RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
- "setRoleNamesFromController");
+ "setRoleNamesFromControllerAsUser");
Objects.requireNonNull(roleNames, "roleNames cannot be null");
- int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
getOrCreateUserState(userId).setRoleNames(roleNames);
}
@Override
- public boolean addRoleHolderFromController(@NonNull String roleName,
- @NonNull String packageName) {
+ public boolean addRoleHolderFromControllerAsUser(@NonNull String roleName,
+ @NonNull String packageName, @UserIdInt int userId) {
+ UserUtils.enforceCrossUserPermission(userId, false,
+ "addRoleHolderFromControllerAsUser", getContext());
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return false;
+ }
+
getContext().enforceCallingOrSelfPermission(
RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
- "addRoleHolderFromController");
+ "addRoleHolderFromControllerAsUser");
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
- int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
return getOrCreateUserState(userId).addRoleHolder(roleName, packageName);
}
@Override
- public boolean removeRoleHolderFromController(@NonNull String roleName,
- @NonNull String packageName) {
+ public boolean removeRoleHolderFromControllerAsUser(@NonNull String roleName,
+ @NonNull String packageName, @UserIdInt int userId) {
+ UserUtils.enforceCrossUserPermission(userId, false,
+ "removeRoleHolderFromControllerAsUser", getContext());
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return false;
+ }
+
getContext().enforceCallingOrSelfPermission(
RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
- "removeRoleHolderFromController");
+ "removeRoleHolderFromControllerAsUser");
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
- int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName);
}
@Override
- public List<String> getHeldRolesFromController(@NonNull String packageName) {
+ public List<String> getHeldRolesFromControllerAsUser(@NonNull String packageName,
+ @UserIdInt int userId) {
+ UserUtils.enforceCrossUserPermission(userId, false,
+ "getHeldRolesFromControllerAsUser", getContext());
+ if (!UserUtils.isUserExistent(userId, getContext())) {
+ Log.e(LOG_TAG, "user " + userId + " does not exist");
+ return Collections.emptyList();
+ }
+
getContext().enforceCallingOrSelfPermission(
RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
- "getRolesHeldFromController");
+ "getHeldRolesFromControllerAsUser");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
- int userId = UserHandleCompat.getUserId(Binder.getCallingUid());
return getOrCreateUserState(userId).getHeldRoles(packageName);
}