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";
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);
package android.app.role;
import android.app.role.IRoleManagerCallback;
+import android.os.RemoteCallback;
/**
* @hide
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);
}
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;
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;
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.
*
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}.
}
/**
+ * @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<
}
}
}
+
+ /**
+ * 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);
+ }
+ }
+ }
}
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;
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);
+ }
};
}
//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;
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);
}
}
/**
- * 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
}
}
}
-
- /**
- * 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);
- }
- }
- }
}
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
}
@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) {
}
}
- 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) {