Loading api/system-current.txt +8 −2 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,7 @@ package android { field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE"; field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE"; field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD"; field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD"; field public static final String RESTORE_RUNTIME_PERMISSIONS = "android.permission.RESTORE_RUNTIME_PERMISSIONS"; field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS"; field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS"; field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; Loading Loading @@ -5701,7 +5702,10 @@ package android.os.telephony { package android.permission { package android.permission { public final class PermissionControllerManager { public final class PermissionControllerManager { method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 Loading @@ -5715,17 +5719,19 @@ package android.permission { public abstract class PermissionControllerService extends android.app.Service { public abstract class PermissionControllerService extends android.app.Service { ctor public PermissionControllerService(); ctor public PermissionControllerService(); method @BinderThread public void onApplyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @NonNull public final android.os.IBinder onBind(android.content.Intent); method @NonNull public final android.os.IBinder onBind(android.content.Intent); method @BinderThread public abstract void onCountPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull java.util.function.IntConsumer); method @BinderThread public abstract void onCountPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull java.util.function.IntConsumer); method @BinderThread public abstract void onGetAppPermissions(@NonNull String, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionPresentationInfo>>); method @BinderThread public abstract void onGetAppPermissions(@NonNull String, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionPresentationInfo>>); method @BinderThread public abstract void onGetPermissionUsages(boolean, long, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionUsageInfo>>); method @BinderThread public abstract void onGetPermissionUsages(boolean, long, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionUsageInfo>>); method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable); method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable); method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable); method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable); method @BinderThread public abstract void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @Deprecated @BinderThread public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public abstract void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>); method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>); method @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @BinderThread public void onUpdateUserSensitive(); method @BinderThread public void onUpdateUserSensitive(); field public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService"; field public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService"; } } Loading api/test-current.txt +3 −0 Original line number Original line Diff line number Diff line Loading @@ -2253,8 +2253,11 @@ package android.os.strictmode { package android.permission { package android.permission { public final class PermissionControllerManager { public final class PermissionControllerManager { method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 Loading core/java/android/permission/IPermissionController.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -31,8 +31,8 @@ oneway interface IPermissionController { void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason, void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason, String callerPackageName, in AndroidFuture callback); String callerPackageName, in AndroidFuture callback); void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe); void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe); void restoreRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe); void stageAndApplyRuntimePermissionsBackup(in UserHandle user, in ParcelFileDescriptor pipe); void restoreDelayedRuntimePermissionBackup(String packageName, in UserHandle user, void applyStagedRuntimePermissionBackup(String packageName, in UserHandle user, in AndroidFuture callback); in AndroidFuture callback); void getAppPermissions(String packageName, in AndroidFuture callback); void getAppPermissions(String packageName, in AndroidFuture callback); void revokeRuntimePermission(String packageName, String permissionName); void revokeRuntimePermission(String packageName, String permissionName); Loading core/java/android/permission/PermissionControllerManager.java +71 −46 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,7 @@ import libcore.util.EmptyArray; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; Loading Loading @@ -138,20 +139,6 @@ public final class PermissionControllerManager { public abstract void onRevokeRuntimePermissions(@NonNull Map<String, List<String>> revoked); public abstract void onRevokeRuntimePermissions(@NonNull Map<String, List<String>> revoked); } } /** * Callback for delivering the result of {@link #getRuntimePermissionBackup}. * * @hide */ public interface OnGetRuntimePermissionBackupCallback { /** * The result for {@link #getRuntimePermissionBackup}. * * @param backup The backup file */ void onGetRuntimePermissionsBackup(@NonNull byte[] backup); } /** /** * Callback for delivering the result of {@link #getAppPermissions}. * Callback for delivering the result of {@link #getAppPermissions}. * * Loading Loading @@ -245,6 +232,24 @@ public final class PermissionControllerManager { mHandler = handler; mHandler = handler; } } /** * Throw a {@link SecurityException} if not at least one of the permissions is granted. * * @param requiredPermissions A list of permissions. Any of of them if sufficient to pass the * check */ private void enforceSomePermissionsGrantedToSelf(@NonNull String... requiredPermissions) { for (String requiredPermission : requiredPermissions) { if (mContext.checkSelfPermission(requiredPermission) == PackageManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("At lest one of the following permissions is required: " + Arrays.toString(requiredPermissions)); } /** /** * Revoke a set of runtime permissions for various apps. * Revoke a set of runtime permissions for various apps. * * Loading @@ -268,11 +273,7 @@ public final class PermissionControllerManager { } } // Check required permission to fail immediately instead of inside the oneway binder call // Check required permission to fail immediately instead of inside the oneway binder call if (mContext.checkSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) enforceSomePermissionsGrantedToSelf(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " required"); } mRemoteService.postAsync(service -> { mRemoteService.postAsync(service -> { Bundle bundledizedRequest = new Bundle(); Bundle bundledizedRequest = new Bundle(); Loading Loading @@ -358,46 +359,61 @@ public final class PermissionControllerManager { * * * @param user The user to be backed up * @param user The user to be backed up * @param executor Executor on which to invoke the callback * @param executor Executor on which to invoke the callback * @param callback Callback to receive the result * @param callback Callback to receive the result. The resulting backup-file is opaque and no * * guarantees are made other than that the file can be send to * @hide * {@link #restoreRuntimePermissionBackup} in this and future versions of * Android. */ */ @RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS) @RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getRuntimePermissionBackup(@NonNull UserHandle user, public void getRuntimePermissionBackup(@NonNull UserHandle user, @NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor, @NonNull OnGetRuntimePermissionBackupCallback callback) { @NonNull Consumer<byte[]> callback) { checkNotNull(user); checkNotNull(user); checkNotNull(executor); checkNotNull(executor); checkNotNull(callback); checkNotNull(callback); // Check required permission to fail immediately instead of inside the oneway binder call enforceSomePermissionsGrantedToSelf(Manifest.permission.GET_RUNTIME_PERMISSIONS); mRemoteService.postAsync(service -> RemoteStream.receiveBytes(remotePipe -> { mRemoteService.postAsync(service -> RemoteStream.receiveBytes(remotePipe -> { service.getRuntimePermissionBackup(user, remotePipe); service.getRuntimePermissionBackup(user, remotePipe); })).whenCompleteAsync((bytes, err) -> { })).whenCompleteAsync((bytes, err) -> { if (err != null) { if (err != null) { Log.e(TAG, "Error getting permission backup", err); Log.e(TAG, "Error getting permission backup", err); callback.onGetRuntimePermissionsBackup(EmptyArray.BYTE); callback.accept(EmptyArray.BYTE); } else { } else { callback.onGetRuntimePermissionsBackup(bytes); callback.accept(bytes); } } }, executor); }, executor); } } /** /** * Restore a backup of the runtime permissions. * Restore a {@link #getRuntimePermissionBackup backup-file} of the runtime permissions. * * * @param backup the backup to restore. The backup is sent asynchronously, hence it should not * <p>This might leave some part of the backup-file unapplied if an package mentioned in the * be modified after calling this method. * backup-file is not yet installed. It is required that * @param user The user to be restore * {@link #applyStagedRuntimePermissionBackup} is called after any package is installed to * apply the rest of the backup-file. * * * @hide * @param backup the backup-file to restore. The backup is sent asynchronously, hence it should * not be modified after calling this method. * @param user The user to be restore */ */ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @RequiresPermission(anyOf = { public void restoreRuntimePermissionBackup(@NonNull byte[] backup, @NonNull UserHandle user) { Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS }) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[] backup, @NonNull UserHandle user) { checkNotNull(backup); checkNotNull(backup); checkNotNull(user); checkNotNull(user); // Check required permission to fail immediately instead of inside the oneway binder call enforceSomePermissionsGrantedToSelf(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS); mRemoteService.postAsync(service -> RemoteStream.sendBytes(remotePipe -> { mRemoteService.postAsync(service -> RemoteStream.sendBytes(remotePipe -> { service.restoreRuntimePermissionBackup(user, remotePipe); service.stageAndApplyRuntimePermissionsBackup(user, remotePipe); }, backup)) }, backup)) .whenComplete((nullResult, err) -> { .whenComplete((nullResult, err) -> { if (err != null) { if (err != null) { Loading @@ -407,17 +423,22 @@ public final class PermissionControllerManager { } } /** /** * Restore a backup of the runtime permissions that has been delayed. * Restore unapplied parts of a {@link #stageAndApplyRuntimePermissionsBackup previously staged} * backup-file of the runtime permissions. * * <p>This should be called every time after a package is installed until the callback * reports that there is no more unapplied backup left. * * * @param packageName The package that is ready to have it's permissions restored. * @param packageName The package that is ready to have it's permissions restored. * @param user The user to restore * @param user The user the package belongs to * @param executor Executor to execute the callback on * @param executor Executor to execute the callback on * @param callback Is called with {@code true} iff there is still more delayed backup left * @param callback Is called with {@code true} iff there is still more unapplied backup left * * @hide */ */ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @RequiresPermission(anyOf = { public void restoreDelayedRuntimePermissionBackup(@NonNull String packageName, Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS }) public void applyStagedRuntimePermissionBackup(@NonNull String packageName, @NonNull UserHandle user, @NonNull UserHandle user, @NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { @NonNull Consumer<Boolean> callback) { Loading @@ -426,13 +447,17 @@ public final class PermissionControllerManager { checkNotNull(executor); checkNotNull(executor); checkNotNull(callback); checkNotNull(callback); // Check required permission to fail immediately instead of inside the oneway binder call enforceSomePermissionsGrantedToSelf(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS); mRemoteService.postAsync(service -> { mRemoteService.postAsync(service -> { AndroidFuture<Boolean> restoreDelayedRuntimePermissionBackupResult = AndroidFuture<Boolean> applyStagedRuntimePermissionBackupResult = new AndroidFuture<>(); new AndroidFuture<>(); service.restoreDelayedRuntimePermissionBackup(packageName, user, service.applyStagedRuntimePermissionBackup(packageName, user, restoreDelayedRuntimePermissionBackupResult); applyStagedRuntimePermissionBackupResult); return restoreDelayedRuntimePermissionBackupResult; return applyStagedRuntimePermissionBackupResult; }).whenCompleteAsync((restoreDelayedRuntimePermissionBackupResult, err) -> { }).whenCompleteAsync((applyStagedRuntimePermissionBackupResult, err) -> { long token = Binder.clearCallingIdentity(); long token = Binder.clearCallingIdentity(); try { try { if (err != null) { if (err != null) { Loading @@ -440,7 +465,7 @@ public final class PermissionControllerManager { callback.accept(true); callback.accept(true); } else { } else { callback.accept( callback.accept( Boolean.TRUE.equals(restoreDelayedRuntimePermissionBackupResult)); Boolean.TRUE.equals(applyStagedRuntimePermissionBackupResult)); } } } finally { } finally { Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token); Loading core/java/android/permission/PermissionControllerService.java +76 −24 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
api/system-current.txt +8 −2 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,7 @@ package android { field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE"; field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE"; field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD"; field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD"; field public static final String RESTORE_RUNTIME_PERMISSIONS = "android.permission.RESTORE_RUNTIME_PERMISSIONS"; field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS"; field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS"; field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; Loading Loading @@ -5701,7 +5702,10 @@ package android.os.telephony { package android.permission { package android.permission { public final class PermissionControllerManager { public final class PermissionControllerManager { method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 Loading @@ -5715,17 +5719,19 @@ package android.permission { public abstract class PermissionControllerService extends android.app.Service { public abstract class PermissionControllerService extends android.app.Service { ctor public PermissionControllerService(); ctor public PermissionControllerService(); method @BinderThread public void onApplyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @NonNull public final android.os.IBinder onBind(android.content.Intent); method @NonNull public final android.os.IBinder onBind(android.content.Intent); method @BinderThread public abstract void onCountPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull java.util.function.IntConsumer); method @BinderThread public abstract void onCountPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull java.util.function.IntConsumer); method @BinderThread public abstract void onGetAppPermissions(@NonNull String, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionPresentationInfo>>); method @BinderThread public abstract void onGetAppPermissions(@NonNull String, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionPresentationInfo>>); method @BinderThread public abstract void onGetPermissionUsages(boolean, long, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionUsageInfo>>); method @BinderThread public abstract void onGetPermissionUsages(boolean, long, @NonNull java.util.function.Consumer<java.util.List<android.permission.RuntimePermissionUsageInfo>>); method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable); method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable); method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable); method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable); method @BinderThread public abstract void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @Deprecated @BinderThread public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public abstract void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>); method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>); method @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @BinderThread public void onUpdateUserSensitive(); method @BinderThread public void onUpdateUserSensitive(); field public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService"; field public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService"; } } Loading
api/test-current.txt +3 −0 Original line number Original line Diff line number Diff line Loading @@ -2253,8 +2253,11 @@ package android.os.strictmode { package android.permission { package android.permission { public final class PermissionControllerManager { public final class PermissionControllerManager { method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 Loading
core/java/android/permission/IPermissionController.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -31,8 +31,8 @@ oneway interface IPermissionController { void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason, void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason, String callerPackageName, in AndroidFuture callback); String callerPackageName, in AndroidFuture callback); void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe); void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe); void restoreRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe); void stageAndApplyRuntimePermissionsBackup(in UserHandle user, in ParcelFileDescriptor pipe); void restoreDelayedRuntimePermissionBackup(String packageName, in UserHandle user, void applyStagedRuntimePermissionBackup(String packageName, in UserHandle user, in AndroidFuture callback); in AndroidFuture callback); void getAppPermissions(String packageName, in AndroidFuture callback); void getAppPermissions(String packageName, in AndroidFuture callback); void revokeRuntimePermission(String packageName, String permissionName); void revokeRuntimePermission(String packageName, String permissionName); Loading
core/java/android/permission/PermissionControllerManager.java +71 −46 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,7 @@ import libcore.util.EmptyArray; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; Loading Loading @@ -138,20 +139,6 @@ public final class PermissionControllerManager { public abstract void onRevokeRuntimePermissions(@NonNull Map<String, List<String>> revoked); public abstract void onRevokeRuntimePermissions(@NonNull Map<String, List<String>> revoked); } } /** * Callback for delivering the result of {@link #getRuntimePermissionBackup}. * * @hide */ public interface OnGetRuntimePermissionBackupCallback { /** * The result for {@link #getRuntimePermissionBackup}. * * @param backup The backup file */ void onGetRuntimePermissionsBackup(@NonNull byte[] backup); } /** /** * Callback for delivering the result of {@link #getAppPermissions}. * Callback for delivering the result of {@link #getAppPermissions}. * * Loading Loading @@ -245,6 +232,24 @@ public final class PermissionControllerManager { mHandler = handler; mHandler = handler; } } /** * Throw a {@link SecurityException} if not at least one of the permissions is granted. * * @param requiredPermissions A list of permissions. Any of of them if sufficient to pass the * check */ private void enforceSomePermissionsGrantedToSelf(@NonNull String... requiredPermissions) { for (String requiredPermission : requiredPermissions) { if (mContext.checkSelfPermission(requiredPermission) == PackageManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("At lest one of the following permissions is required: " + Arrays.toString(requiredPermissions)); } /** /** * Revoke a set of runtime permissions for various apps. * Revoke a set of runtime permissions for various apps. * * Loading @@ -268,11 +273,7 @@ public final class PermissionControllerManager { } } // Check required permission to fail immediately instead of inside the oneway binder call // Check required permission to fail immediately instead of inside the oneway binder call if (mContext.checkSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) enforceSomePermissionsGrantedToSelf(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); != PackageManager.PERMISSION_GRANTED) { throw new SecurityException(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " required"); } mRemoteService.postAsync(service -> { mRemoteService.postAsync(service -> { Bundle bundledizedRequest = new Bundle(); Bundle bundledizedRequest = new Bundle(); Loading Loading @@ -358,46 +359,61 @@ public final class PermissionControllerManager { * * * @param user The user to be backed up * @param user The user to be backed up * @param executor Executor on which to invoke the callback * @param executor Executor on which to invoke the callback * @param callback Callback to receive the result * @param callback Callback to receive the result. The resulting backup-file is opaque and no * * guarantees are made other than that the file can be send to * @hide * {@link #restoreRuntimePermissionBackup} in this and future versions of * Android. */ */ @RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS) @RequiresPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getRuntimePermissionBackup(@NonNull UserHandle user, public void getRuntimePermissionBackup(@NonNull UserHandle user, @NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor, @NonNull OnGetRuntimePermissionBackupCallback callback) { @NonNull Consumer<byte[]> callback) { checkNotNull(user); checkNotNull(user); checkNotNull(executor); checkNotNull(executor); checkNotNull(callback); checkNotNull(callback); // Check required permission to fail immediately instead of inside the oneway binder call enforceSomePermissionsGrantedToSelf(Manifest.permission.GET_RUNTIME_PERMISSIONS); mRemoteService.postAsync(service -> RemoteStream.receiveBytes(remotePipe -> { mRemoteService.postAsync(service -> RemoteStream.receiveBytes(remotePipe -> { service.getRuntimePermissionBackup(user, remotePipe); service.getRuntimePermissionBackup(user, remotePipe); })).whenCompleteAsync((bytes, err) -> { })).whenCompleteAsync((bytes, err) -> { if (err != null) { if (err != null) { Log.e(TAG, "Error getting permission backup", err); Log.e(TAG, "Error getting permission backup", err); callback.onGetRuntimePermissionsBackup(EmptyArray.BYTE); callback.accept(EmptyArray.BYTE); } else { } else { callback.onGetRuntimePermissionsBackup(bytes); callback.accept(bytes); } } }, executor); }, executor); } } /** /** * Restore a backup of the runtime permissions. * Restore a {@link #getRuntimePermissionBackup backup-file} of the runtime permissions. * * * @param backup the backup to restore. The backup is sent asynchronously, hence it should not * <p>This might leave some part of the backup-file unapplied if an package mentioned in the * be modified after calling this method. * backup-file is not yet installed. It is required that * @param user The user to be restore * {@link #applyStagedRuntimePermissionBackup} is called after any package is installed to * apply the rest of the backup-file. * * * @hide * @param backup the backup-file to restore. The backup is sent asynchronously, hence it should * not be modified after calling this method. * @param user The user to be restore */ */ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @RequiresPermission(anyOf = { public void restoreRuntimePermissionBackup(@NonNull byte[] backup, @NonNull UserHandle user) { Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS }) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[] backup, @NonNull UserHandle user) { checkNotNull(backup); checkNotNull(backup); checkNotNull(user); checkNotNull(user); // Check required permission to fail immediately instead of inside the oneway binder call enforceSomePermissionsGrantedToSelf(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS); mRemoteService.postAsync(service -> RemoteStream.sendBytes(remotePipe -> { mRemoteService.postAsync(service -> RemoteStream.sendBytes(remotePipe -> { service.restoreRuntimePermissionBackup(user, remotePipe); service.stageAndApplyRuntimePermissionsBackup(user, remotePipe); }, backup)) }, backup)) .whenComplete((nullResult, err) -> { .whenComplete((nullResult, err) -> { if (err != null) { if (err != null) { Loading @@ -407,17 +423,22 @@ public final class PermissionControllerManager { } } /** /** * Restore a backup of the runtime permissions that has been delayed. * Restore unapplied parts of a {@link #stageAndApplyRuntimePermissionsBackup previously staged} * backup-file of the runtime permissions. * * <p>This should be called every time after a package is installed until the callback * reports that there is no more unapplied backup left. * * * @param packageName The package that is ready to have it's permissions restored. * @param packageName The package that is ready to have it's permissions restored. * @param user The user to restore * @param user The user the package belongs to * @param executor Executor to execute the callback on * @param executor Executor to execute the callback on * @param callback Is called with {@code true} iff there is still more delayed backup left * @param callback Is called with {@code true} iff there is still more unapplied backup left * * @hide */ */ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @RequiresPermission(anyOf = { public void restoreDelayedRuntimePermissionBackup(@NonNull String packageName, Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS }) public void applyStagedRuntimePermissionBackup(@NonNull String packageName, @NonNull UserHandle user, @NonNull UserHandle user, @NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { @NonNull Consumer<Boolean> callback) { Loading @@ -426,13 +447,17 @@ public final class PermissionControllerManager { checkNotNull(executor); checkNotNull(executor); checkNotNull(callback); checkNotNull(callback); // Check required permission to fail immediately instead of inside the oneway binder call enforceSomePermissionsGrantedToSelf(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.RESTORE_RUNTIME_PERMISSIONS); mRemoteService.postAsync(service -> { mRemoteService.postAsync(service -> { AndroidFuture<Boolean> restoreDelayedRuntimePermissionBackupResult = AndroidFuture<Boolean> applyStagedRuntimePermissionBackupResult = new AndroidFuture<>(); new AndroidFuture<>(); service.restoreDelayedRuntimePermissionBackup(packageName, user, service.applyStagedRuntimePermissionBackup(packageName, user, restoreDelayedRuntimePermissionBackupResult); applyStagedRuntimePermissionBackupResult); return restoreDelayedRuntimePermissionBackupResult; return applyStagedRuntimePermissionBackupResult; }).whenCompleteAsync((restoreDelayedRuntimePermissionBackupResult, err) -> { }).whenCompleteAsync((applyStagedRuntimePermissionBackupResult, err) -> { long token = Binder.clearCallingIdentity(); long token = Binder.clearCallingIdentity(); try { try { if (err != null) { if (err != null) { Loading @@ -440,7 +465,7 @@ public final class PermissionControllerManager { callback.accept(true); callback.accept(true); } else { } else { callback.accept( callback.accept( Boolean.TRUE.equals(restoreDelayedRuntimePermissionBackupResult)); Boolean.TRUE.equals(applyStagedRuntimePermissionBackupResult)); } } } finally { } finally { Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token); Loading
core/java/android/permission/PermissionControllerService.java +76 −24 File changed.Preview size limit exceeded, changes collapsed. Show changes