diff options
| -rw-r--r-- | api/system-current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/app/role/IRoleController.aidl | 8 | ||||
| -rw-r--r-- | core/java/android/app/role/RoleControllerManager.java | 139 | ||||
| -rw-r--r-- | core/java/android/app/role/RoleControllerService.java | 52 | ||||
| -rw-r--r-- | core/java/android/permission/IPermissionController.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/permission/PermissionControllerManager.java | 147 | ||||
| -rw-r--r-- | core/java/android/permission/PermissionControllerService.java | 61 |
7 files changed, 200 insertions, 214 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 906c062c31e8..0f1ab294c67a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1122,6 +1122,8 @@ package android.app.role { method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent); method public abstract void onClearRoleHolders(@NonNull String, int, @NonNull android.app.role.RoleManagerCallback); method public abstract void onGrantDefaultRoles(@NonNull android.app.role.RoleManagerCallback); + method public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String); + method public abstract boolean onIsRoleVisible(@NonNull String); method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback); method public abstract void onSmsKillSwitchToggled(boolean); field public static final String SERVICE_INTERFACE = "android.app.role.RoleControllerService"; @@ -5699,8 +5701,6 @@ package android.permission { method @NonNull public abstract java.util.List<android.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(@NonNull String); method @NonNull public abstract java.util.List<android.permission.RuntimePermissionUsageInfo> onGetPermissionUsages(boolean, long); method public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream); - method public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String); - method public abstract boolean onIsRoleVisible(@NonNull String); method @BinderThread public abstract boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle); method @BinderThread public abstract void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream); method public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String); diff --git a/core/java/android/app/role/IRoleController.aidl b/core/java/android/app/role/IRoleController.aidl index 07a4161af771..e8f6ce2780b2 100644 --- a/core/java/android/app/role/IRoleController.aidl +++ b/core/java/android/app/role/IRoleController.aidl @@ -17,6 +17,7 @@ package android.app.role; import android.app.role.IRoleManagerCallback; +import android.os.RemoteCallback; /** * @hide @@ -29,9 +30,14 @@ oneway interface IRoleController { in IRoleManagerCallback callback); void onRemoveRoleHolder(in String roleName, in String packageName, int flags, - in IRoleManagerCallback callback); + in IRoleManagerCallback callback); void onClearRoleHolders(in String roleName, int flags, in IRoleManagerCallback callback); void onSmsKillSwitchToggled(boolean enabled); + + void isApplicationQualifiedForRole(in String roleName, in String packageName, + in RemoteCallback callback); + + void isRoleVisible(in String roleName, in RemoteCallback callback); } diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java index a9b13ee8c2fc..2edc526ff261 100644 --- a/core/java/android/app/role/RoleControllerManager.java +++ b/core/java/android/app/role/RoleControllerManager.java @@ -16,7 +16,10 @@ package android.app.role; +import android.Manifest; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.UserIdInt; import android.content.ComponentName; @@ -27,6 +30,7 @@ import android.content.pm.ResolveInfo; import android.os.Binder; import android.os.Handler; import android.os.IBinder; +import android.os.RemoteCallback; import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; @@ -35,6 +39,9 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService; import com.android.internal.infra.AbstractRemoteService; +import java.util.concurrent.Executor; +import java.util.function.Consumer; + /** * Interface for communicating with the role controller. * @@ -45,6 +52,11 @@ public class RoleControllerManager { private static final String LOG_TAG = RoleControllerManager.class.getSimpleName(); + /** + * The key for retrieving the result from a bundle. + */ + public static final String KEY_RESULT = "android.app.role.RoleControllerManager.key.RESULT"; + private static final Object sRemoteServicesLock = new Object(); /** * Global remote services (per user) used by all {@link RoleControllerManager managers}. @@ -119,6 +131,26 @@ public class RoleControllerManager { } /** + * @see RoleControllerService#onIsApplicationQualifiedForRole(String, String) + */ + @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) + public void isApplicationQualifiedForRole(@NonNull String roleName, @NonNull String packageName, + @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { + mRemoteService.scheduleRequest(new IsApplicationQualifiedForRoleRequest(mRemoteService, + roleName, packageName, executor, callback)); + } + + /** + * @see RoleControllerService#onIsRoleVisible(String) + */ + @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) + public void isRoleVisible(@NonNull String roleName, + @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { + mRemoteService.scheduleRequest(new IsRoleVisibleRequest(mRemoteService, roleName, executor, + callback)); + } + + /** * Connection to the remote service. */ private static final class RemoteService extends AbstractMultiplePendingRequestsRemoteService< @@ -471,4 +503,111 @@ public class RoleControllerManager { } } } + + /** + * Request for {@link #isApplicationQualifiedForRole(String, String, Executor, Consumer)} + */ + private static final class IsApplicationQualifiedForRoleRequest extends + AbstractRemoteService.PendingRequest<RemoteService, IRoleController> { + + @NonNull + private final String mRoleName; + @NonNull + private final String mPackageName; + @NonNull + private final Executor mExecutor; + @NonNull + private final Consumer<Boolean> mCallback; + + @NonNull + private final RemoteCallback mRemoteCallback; + + private IsApplicationQualifiedForRoleRequest(@NonNull RemoteService service, + @NonNull String roleName, @NonNull String packageName, + @CallbackExecutor @NonNull Executor executor, @NonNull Consumer<Boolean> callback) { + super(service); + + mRoleName = roleName; + mPackageName = packageName; + mExecutor = executor; + mCallback = callback; + + mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> { + long token = Binder.clearCallingIdentity(); + try { + boolean qualified = result != null && result.getBoolean(KEY_RESULT); + mCallback.accept(qualified); + } finally { + Binder.restoreCallingIdentity(token); + finish(); + } + })); + } + + @Override + protected void onTimeout(RemoteService remoteService) { + mExecutor.execute(() -> mCallback.accept(false)); + } + + @Override + public void run() { + try { + getService().getServiceInterface().isApplicationQualifiedForRole(mRoleName, + mPackageName, mRemoteCallback); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Error calling isApplicationQualifiedForRole()", e); + } + } + } + + /** + * Request for {@link #isRoleVisible(String, Executor, Consumer)} + */ + private static final class IsRoleVisibleRequest + extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> { + + @NonNull + private final String mRoleName; + @NonNull + private final Executor mExecutor; + @NonNull + private final Consumer<Boolean> mCallback; + + @NonNull + private final RemoteCallback mRemoteCallback; + + private IsRoleVisibleRequest(@NonNull RemoteService service, @NonNull String roleName, + @CallbackExecutor @NonNull Executor executor, @NonNull Consumer<Boolean> callback) { + super(service); + + mRoleName = roleName; + mExecutor = executor; + mCallback = callback; + + mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> { + long token = Binder.clearCallingIdentity(); + try { + boolean visible = result != null && result.getBoolean(KEY_RESULT); + mCallback.accept(visible); + } finally { + Binder.restoreCallingIdentity(token); + finish(); + } + })); + } + + @Override + protected void onTimeout(RemoteService remoteService) { + mExecutor.execute(() -> mCallback.accept(false)); + } + + @Override + public void run() { + try { + getService().getServiceInterface().isRoleVisible(mRoleName, mRemoteCallback); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Error calling isRoleVisible()", e); + } + } + } } diff --git a/core/java/android/app/role/RoleControllerService.java b/core/java/android/app/role/RoleControllerService.java index f3da3580cbc6..47be38561b45 100644 --- a/core/java/android/app/role/RoleControllerService.java +++ b/core/java/android/app/role/RoleControllerService.java @@ -16,12 +16,15 @@ package android.app.role; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; +import android.os.Bundle; import android.os.IBinder; +import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; @@ -96,6 +99,35 @@ public abstract class RoleControllerService extends Service { public void onSmsKillSwitchToggled(boolean smsRestrictionEnabled) { RoleControllerService.this.onSmsKillSwitchToggled(smsRestrictionEnabled); } + + @Override + public void isApplicationQualifiedForRole(String roleName, String packageName, + RemoteCallback callback) { + enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); + + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkStringNotEmpty(packageName, + "packageName cannot be null or empty"); + Preconditions.checkNotNull(callback, "callback cannot be null"); + + boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName); + Bundle result = new Bundle(); + result.putBoolean(RoleControllerManager.KEY_RESULT, qualified); + callback.sendResult(result); + } + + @Override + public void isRoleVisible(String roleName, RemoteCallback callback) { + enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); + + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkNotNull(callback, "callback cannot be null"); + + boolean visible = onIsRoleVisible(roleName); + Bundle result = new Bundle(); + result.putBoolean(RoleControllerManager.KEY_RESULT, visible); + callback.sendResult(result); + } }; } @@ -162,6 +194,26 @@ public abstract class RoleControllerService extends Service { //STOPSHIP: remove this api before shipping a final version public abstract void onSmsKillSwitchToggled(boolean enabled); + /** + * Check whether an application is qualified for a role. + * + * @param roleName name of the role to check for + * @param packageName package name of the application to check for + * + * @return whether the application is qualified for the role + */ + public abstract boolean onIsApplicationQualifiedForRole(@NonNull String roleName, + @NonNull String packageName); + + /** + * Check whether a role should be visible to user. + * + * @param roleName name of the role to check for + * + * @return whether the role should be visible to user + */ + public abstract boolean onIsRoleVisible(@NonNull String roleName); + private static class RoleManagerCallbackDelegate implements RoleManagerCallback { private IRoleManagerCallback mCallback; diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl index 76e911ddaf5a..4f65d244d3c1 100644 --- a/core/java/android/permission/IPermissionController.aidl +++ b/core/java/android/permission/IPermissionController.aidl @@ -38,9 +38,6 @@ oneway interface IPermissionController { void countPermissionApps(in List<String> permissionNames, int flags, in RemoteCallback callback); void getPermissionUsages(boolean countSystem, long numMillis, in RemoteCallback callback); - void isApplicationQualifiedForRole(String roleName, String packageName, - in RemoteCallback callback); - void isRoleVisible(String roleName, in RemoteCallback callback); void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName, String packageName, String permission, int grantState, in RemoteCallback callback); } diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java index 2379928f8946..61511aa509b1 100644 --- a/core/java/android/permission/PermissionControllerManager.java +++ b/core/java/android/permission/PermissionControllerManager.java @@ -454,48 +454,6 @@ public final class PermissionControllerManager { } /** - * Check whether an application is qualified for a role. - * - * @param roleName name of the role to check for - * @param packageName package name of the application to check for - * @param executor Executor on which to invoke the callback - * @param callback Callback to receive the result - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - public void isApplicationQualifiedForRole(@NonNull String roleName, @NonNull String packageName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - checkStringNotEmpty(roleName); - checkStringNotEmpty(packageName); - checkNotNull(executor); - checkNotNull(callback); - - mRemoteService.scheduleRequest(new PendingIsApplicationQualifiedForRoleRequest( - mRemoteService, roleName, packageName, executor, callback)); - } - - /** - * Check whether a role should be visible to user. - * - * @param roleName name of the role to check for - * @param executor Executor on which to invoke the callback - * @param callback Callback to receive the result - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - public void isRoleVisible(@NonNull String roleName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - checkStringNotEmpty(roleName); - checkNotNull(executor); - checkNotNull(callback); - - mRemoteService.scheduleRequest(new PendingIsRoleVisibleRequest(mRemoteService, roleName, - executor, callback)); - } - - /** * A connection to the remote service */ static final class RemoteService extends @@ -1189,109 +1147,4 @@ public final class PermissionControllerManager { } } } - - /** - * Request for {@link #isApplicationQualifiedForRole}. - */ - private static final class PendingIsApplicationQualifiedForRoleRequest extends - AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> { - - private final @NonNull String mRoleName; - private final @NonNull String mPackageName; - private final @NonNull Consumer<Boolean> mCallback; - - private final @NonNull RemoteCallback mRemoteCallback; - - private PendingIsApplicationQualifiedForRoleRequest(@NonNull RemoteService service, - @NonNull String roleName, @NonNull String packageName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - super(service); - - mRoleName = roleName; - mPackageName = packageName; - mCallback = callback; - - mRemoteCallback = new RemoteCallback(result -> executor.execute(() -> { - long token = Binder.clearCallingIdentity(); - try { - boolean qualified; - if (result != null) { - qualified = result.getBoolean(KEY_RESULT); - } else { - qualified = false; - } - callback.accept(qualified); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } - }), null); - } - - @Override - protected void onTimeout(RemoteService remoteService) { - mCallback.accept(false); - } - - @Override - public void run() { - try { - getService().getServiceInterface().isApplicationQualifiedForRole(mRoleName, - mPackageName, mRemoteCallback); - } catch (RemoteException e) { - Log.e(TAG, "Error checking whether application qualifies for role", e); - } - } - } - - /** - * Request for {@link #isRoleVisible}. - */ - private static final class PendingIsRoleVisibleRequest extends - AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> { - - private final @NonNull String mRoleName; - private final @NonNull Consumer<Boolean> mCallback; - - private final @NonNull RemoteCallback mRemoteCallback; - - private PendingIsRoleVisibleRequest(@NonNull RemoteService service, - @NonNull String roleName, @NonNull @CallbackExecutor Executor executor, - @NonNull Consumer<Boolean> callback) { - super(service); - - mRoleName = roleName; - mCallback = callback; - - mRemoteCallback = new RemoteCallback(result -> executor.execute(() -> { - long token = Binder.clearCallingIdentity(); - try { - boolean visible; - if (result != null) { - visible = result.getBoolean(KEY_RESULT); - } else { - visible = false; - } - callback.accept(visible); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } - }), null); - } - - @Override - protected void onTimeout(RemoteService remoteService) { - mCallback.accept(false); - } - - @Override - public void run() { - try { - getService().getServiceInterface().isRoleVisible(mRoleName, mRemoteCallback); - } catch (RemoteException e) { - Log.e(TAG, "Error checking whether role should be visible", e); - } - } - } } diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java index d375c10e6d4c..bd4a6ff196b0 100644 --- a/core/java/android/permission/PermissionControllerService.java +++ b/core/java/android/permission/PermissionControllerService.java @@ -174,26 +174,6 @@ public abstract class PermissionControllerService extends Service { boolean countSystem, long numMillis); /** - * Check whether an application is qualified for a role. - * - * @param roleName name of the role to check for - * @param packageName package name of the application to check for - * - * @return whether the application is qualified for the role - */ - public abstract boolean onIsApplicationQualifiedForRole(@NonNull String roleName, - @NonNull String packageName); - - /** - * Check whether a role should be visible to user. - * - * @param roleName name of the role to check for - * - * @return whether the role should be visible to user - */ - public abstract boolean onIsRoleVisible(@NonNull String roleName); - - /** * Set the runtime permission state from a device admin. * * @param callerPackageName The package name of the admin requesting the change @@ -339,32 +319,6 @@ public abstract class PermissionControllerService extends Service { } @Override - public void isApplicationQualifiedForRole(String roleName, String packageName, - RemoteCallback callback) { - checkStringNotEmpty(roleName); - checkStringNotEmpty(packageName); - checkNotNull(callback, "callback"); - - enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - mHandler.sendMessage(obtainMessage( - PermissionControllerService::isApplicationQualifiedForRole, - PermissionControllerService.this, roleName, packageName, callback)); - } - - @Override - public void isRoleVisible(String roleName, RemoteCallback callback) { - checkStringNotEmpty(roleName); - checkNotNull(callback, "callback"); - - enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - mHandler.sendMessage(obtainMessage( - PermissionControllerService::isRoleVisible, - PermissionControllerService.this, roleName, callback)); - } - - @Override public void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName, String packageName, String permission, int grantState, RemoteCallback callback) { @@ -458,21 +412,6 @@ public abstract class PermissionControllerService extends Service { } } - private void isApplicationQualifiedForRole(@NonNull String roleName, - @NonNull String packageName, @NonNull RemoteCallback callback) { - boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName); - Bundle result = new Bundle(); - result.putBoolean(PermissionControllerManager.KEY_RESULT, qualified); - callback.sendResult(result); - } - - private void isRoleVisible(@NonNull String roleName, @NonNull RemoteCallback callback) { - boolean visible = onIsRoleVisible(roleName); - Bundle result = new Bundle(); - result.putBoolean(PermissionControllerManager.KEY_RESULT, visible); - callback.sendResult(result); - } - private void setRuntimePermissionGrantStateByDeviceAdmin(@NonNull String callerPackageName, @NonNull String packageName, @NonNull String permission, @PermissionGrantState int grantState, @NonNull RemoteCallback callback) { |