Loading api/system-current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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); Loading core/java/android/app/role/IRoleController.aidl +7 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app.role; import android.app.role.IRoleManagerCallback; import android.os.RemoteCallback; /** * @hide Loading @@ -34,4 +35,9 @@ oneway interface IRoleController { 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); } core/java/android/app/role/RoleControllerManager.java +139 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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. * Loading @@ -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}. Loading Loading @@ -118,6 +130,26 @@ public class RoleControllerManager { mRemoteService.scheduleAsyncRequest(new OnSmsKillSwitchToggledRequest(enabled)); } /** * @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. */ Loading Loading @@ -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); } } } } core/java/android/app/role/RoleControllerService.java +52 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }; } Loading Loading @@ -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; Loading core/java/android/permission/IPermissionController.aidl +0 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading
api/system-current.txt +2 −2 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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); Loading
core/java/android/app/role/IRoleController.aidl +7 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.app.role; import android.app.role.IRoleManagerCallback; import android.os.RemoteCallback; /** * @hide Loading @@ -34,4 +35,9 @@ oneway interface IRoleController { 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); }
core/java/android/app/role/RoleControllerManager.java +139 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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. * Loading @@ -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}. Loading Loading @@ -118,6 +130,26 @@ public class RoleControllerManager { mRemoteService.scheduleAsyncRequest(new OnSmsKillSwitchToggledRequest(enabled)); } /** * @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. */ Loading Loading @@ -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); } } } }
core/java/android/app/role/RoleControllerService.java +52 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }; } Loading Loading @@ -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; Loading
core/java/android/permission/IPermissionController.aidl +0 −3 Original line number Diff line number Diff line Loading @@ -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); }