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 e501864f2ec4..81b8817bac3f 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"; @@ -5688,8 +5690,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) {  |