diff options
| author | 2023-11-09 19:40:17 -0800 | |
|---|---|---|
| committer | 2023-11-17 16:44:39 -0800 | |
| commit | d188c50e8d9b019ef1e46b327e8cde34822d3952 (patch) | |
| tree | 8e3e73c3c05a9551016113236837ddff2b9af8c8 | |
| parent | 7473cf54743e3a3315aed29de29739a98b13a0d3 (diff) | |
[Role Logic Move] Call SS, not PC
Currently, the methods:
- RoleManager::isRoleVisible
- RoleManager::isApplicationVisibleForRole
...directly call corresponding RoleControllerManager methods. These are
the only two methods in RoleManager that call RoleControllerManager.
But, RoleControllerManager calls the RoleControllerService API which
runs in PermissionController, and, we want to invoke this logic in
System Server.
So, call RoleService instead, and have RoleService conditionally route
to either System Server or PermissionController depending on the flag
state.
Bug: 309139048
Test: atest CtsRoleTestCases
Change-Id: I417637269d70e28bd2bebcabc85f9ac6a033b0f8
6 files changed, 106 insertions, 3 deletions
diff --git a/framework-s/java/android/app/role/IRoleManager.aidl b/framework-s/java/android/app/role/IRoleManager.aidl index 581bb20fa..0aef871e6 100644 --- a/framework-s/java/android/app/role/IRoleManager.aidl +++ b/framework-s/java/android/app/role/IRoleManager.aidl @@ -73,4 +73,9 @@ interface IRoleManager { boolean setBrowserRoleHolder(String packageName, int userId); String getSmsRoleHolder(int userId); + + boolean isRoleVisibleAsUser(in String roleName, int userId); + + boolean isApplicationVisibleForRoleAsUser(in String roleName, in String packageName, + int userId); } diff --git a/framework-s/java/android/app/role/RoleManager.java b/framework-s/java/android/app/role/RoleManager.java index c441d72b6..231c72c2c 100644 --- a/framework-s/java/android/app/role/RoleManager.java +++ b/framework-s/java/android/app/role/RoleManager.java @@ -47,6 +47,7 @@ import androidx.annotation.RequiresApi; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; +import com.android.modules.utils.build.SdkLevel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -975,10 +976,29 @@ public final class RoleManager { */ @RequiresApi(Build.VERSION_CODES.S) @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) + @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) @SystemApi public void isRoleVisible(@NonNull String roleName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - getRoleControllerManager().isRoleVisible(roleName, executor, callback); + if (SdkLevel.isAtLeastV() && Flags.roleControllerInSystemServer()) { + int userId = getContextUserIfAppropriate().getIdentifier(); + boolean visible; + try { + visible = mService.isRoleVisibleAsUser(roleName, userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + executor.execute(() -> { + final long token = Binder.clearCallingIdentity(); + try { + callback.accept(visible); + } finally { + Binder.restoreCallingIdentity(token); + } + }); + } else { + getRoleControllerManager().isRoleVisible(roleName, executor, callback); + } } /** @@ -997,11 +1017,21 @@ public final class RoleManager { */ @RequiresApi(Build.VERSION_CODES.S) @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) + @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) @SystemApi public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - getRoleControllerManager().isApplicationVisibleForRole(roleName, packageName, executor, - callback); + if (SdkLevel.isAtLeastV() && Flags.roleControllerInSystemServer()) { + int userId = getContextUserIfAppropriate().getIdentifier(); + try { + mService.isApplicationVisibleForRoleAsUser(roleName, packageName, userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } else { + getRoleControllerManager().isApplicationVisibleForRole(roleName, packageName, executor, + callback); + } } @NonNull diff --git a/service/java/com/android/role/LocalRoleController.java b/service/java/com/android/role/LocalRoleController.java index 9bac68f4d..6548aaa03 100644 --- a/service/java/com/android/role/LocalRoleController.java +++ b/service/java/com/android/role/LocalRoleController.java @@ -82,4 +82,15 @@ public class LocalRoleController implements RoleController { callback.sendResult(successful ? Bundle.EMPTY : null); }); } + + @Override + public boolean isRoleVisible(@NonNull String roleName) { + return mService.onIsRoleVisible(roleName); + } + + @Override + public boolean isApplicationVisibleForRole(@NonNull String roleName, + @NonNull String packageName) { + return mService.onIsApplicationVisibleForRole(roleName, packageName); + } } diff --git a/service/java/com/android/role/RemoteRoleController.java b/service/java/com/android/role/RemoteRoleController.java index 08854e118..cbf164d6d 100644 --- a/service/java/com/android/role/RemoteRoleController.java +++ b/service/java/com/android/role/RemoteRoleController.java @@ -62,4 +62,15 @@ public class RemoteRoleController implements RoleController { @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { mRoleControllerManager.onClearRoleHolders(roleName, flags, callback); } + + @Override + public boolean isRoleVisible(@NonNull String roleName) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isApplicationVisibleForRole(@NonNull String roleName, + @NonNull String packageName) { + throw new UnsupportedOperationException(); + } } diff --git a/service/java/com/android/role/RoleController.java b/service/java/com/android/role/RoleController.java index 4a5f2a8c2..8a7ef8646 100644 --- a/service/java/com/android/role/RoleController.java +++ b/service/java/com/android/role/RoleController.java @@ -48,4 +48,14 @@ public interface RoleController { */ void onClearRoleHolders(@NonNull String roleName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback); + + /** + * @see android.app.role.RoleControllerManager#isRoleVisible + */ + boolean isRoleVisible(@NonNull String roleName); + + /** + * @see android.app.role.RoleControllerManager#isApplicationVisibleForRole + */ + boolean isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName); } diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java index 9b733ab55..a282e67cf 100644 --- a/service/java/com/android/role/RoleService.java +++ b/service/java/com/android/role/RoleService.java @@ -893,6 +893,42 @@ public class RoleService extends SystemService implements RoleUserState.Callback } @Override + public boolean isRoleVisibleAsUser(@NonNull String roleName, @UserIdInt int userId) { + UserUtils.enforceCrossUserPermission(userId, false, "isRoleVisibleAsUser", + getContext()); + if (!UserUtils.isUserExistent(userId, getContext())) { + Log.e(LOG_TAG, "user " + userId + " does not exist"); + return false; + } + + getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, + "isRoleVisibleAsUser"); + + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + + return getOrCreateController(userId).isRoleVisible(roleName); + } + + @Override + public boolean isApplicationVisibleForRoleAsUser(@NonNull String roleName, + @NonNull String packageName, @UserIdInt int userId) { + UserUtils.enforceCrossUserPermission(userId, false, + "isApplicationVisibleForRoleAsUser", getContext()); + if (!UserUtils.isUserExistent(userId, getContext())) { + Log.e(LOG_TAG, "user " + userId + " does not exist"); + return false; + } + + getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, + "isApplicationVisibleForRoleAsUser"); + + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); + + return getOrCreateController(userId).isApplicationVisibleForRole(roleName, packageName); + } + + @Override protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args) { if (!checkDumpPermission("role", fout)) { |