From 3e93b16fd13dc116e16c9ba077947e72082bff32 Mon Sep 17 00:00:00 2001 From: Jay Thomas Sullivan Date: Sun, 22 Oct 2023 22:08:05 -0700 Subject: [Role Logic Move] Make RoleManager methods user-aware Some RoleManager API methods are not multi-user-aware; for example, the methods named "...FromController", among others. These methods lead to Binder.getCallingUid(). And, many of those methods are called from the role-controller business logic. But, that business logic will will be moving from a per-user app into SystemServer. So, we need to make these methods multi-user-aware to support the Role Business Logic Move project. To do so, modify these methods to receive the user from the context, and mark the APIs as @UserHandleAware. For compatibility reasons, use CompatChanges, which will only enable this change for callers with targetSdk V+. Since this is the first time we've used CompatChanges in the Permission APEX, this involves updating Android.bp files. Test: atest CtsRoleTestCases Bug: 303742236 Change-Id: I8efae9ffe083f8e33ea1bd221bc1ed05c1100a13 --- .../java/android/app/role/IRoleManager.aidl | 14 ++++--- framework-s/java/android/app/role/RoleManager.java | 49 ++++++++++++++++++---- 2 files changed, 50 insertions(+), 13 deletions(-) (limited to 'framework-s/java') 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 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 roleNames); + void setRoleNamesFromControllerAsUser(in List 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 getHeldRolesFromController(in String packageName); + List 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; @@ -211,6 +214,17 @@ public final class RoleManager { @SystemApi 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 + * below 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. * @@ -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 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 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 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 -- cgit v1.2.3-59-g8ed1b