1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.permission; 18 19 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED; 20 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED; 21 import static android.permission.PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED; 22 import static android.permission.PermissionControllerManager.COUNT_WHEN_SYSTEM; 23 24 import static com.android.internal.util.Preconditions.checkArgument; 25 import static com.android.internal.util.Preconditions.checkArgumentNonnegative; 26 import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull; 27 import static com.android.internal.util.Preconditions.checkFlagsArgument; 28 import static com.android.internal.util.Preconditions.checkNotNull; 29 import static com.android.internal.util.Preconditions.checkStringNotEmpty; 30 31 import android.Manifest; 32 import android.annotation.BinderThread; 33 import android.annotation.FlaggedApi; 34 import android.annotation.NonNull; 35 import android.annotation.RequiresPermission; 36 import android.annotation.SystemApi; 37 import android.app.Service; 38 import android.app.admin.DevicePolicyManager.PermissionGrantState; 39 import android.compat.annotation.ChangeId; 40 import android.compat.annotation.Disabled; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.pm.PackageInfo; 44 import android.content.pm.PackageManager; 45 import android.os.Binder; 46 import android.os.Bundle; 47 import android.os.IBinder; 48 import android.os.ParcelFileDescriptor; 49 import android.os.UserHandle; 50 import android.permission.PermissionControllerManager.CountPermissionAppsFlag; 51 import android.permission.flags.Flags; 52 import android.util.ArrayMap; 53 import android.util.Log; 54 55 import com.android.internal.infra.AndroidFuture; 56 import com.android.internal.util.CollectionUtils; 57 import com.android.internal.util.Preconditions; 58 59 import java.io.FileDescriptor; 60 import java.io.IOException; 61 import java.io.InputStream; 62 import java.io.OutputStream; 63 import java.io.PrintWriter; 64 import java.util.ArrayList; 65 import java.util.Arrays; 66 import java.util.List; 67 import java.util.Map; 68 import java.util.Objects; 69 import java.util.concurrent.CountDownLatch; 70 import java.util.concurrent.Executor; 71 import java.util.function.Consumer; 72 import java.util.function.IntConsumer; 73 74 /** 75 * This service is meant to be implemented by the app controlling permissions. 76 * 77 * @see PermissionControllerManager 78 * 79 * @hide 80 */ 81 @SystemApi 82 public abstract class PermissionControllerService extends Service { 83 private static final String LOG_TAG = PermissionControllerService.class.getSimpleName(); 84 85 /** 86 * The {@link Intent} action that must be declared as handled by a service 87 * in its manifest for the system to recognize it as a runtime permission 88 * presenter service. 89 */ 90 public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService"; 91 92 /** 93 * A ChangeId indicating that this device supports camera and mic indicators. Will be "false" 94 * if present, because the CompatChanges#isChangeEnabled method returns true if the change id 95 * is not present. 96 */ 97 @ChangeId 98 @Disabled 99 private static final long CAMERA_MIC_INDICATORS_NOT_PRESENT = 162547999L; 100 101 /** 102 * Revoke a set of runtime permissions for various apps. 103 * 104 * @param requests The permissions to revoke as {@code Map<packageName, List<permission>>} 105 * @param doDryRun Compute the permissions that would be revoked, but not actually revoke them 106 * @param reason Why the permission should be revoked 107 * @param callerPackageName The package name of the calling app 108 * @param callback Callback waiting for the actually removed permissions as 109 * {@code Map<packageName, List<permission>>} 110 */ 111 @BinderThread onRevokeRuntimePermissions( @onNull Map<String, List<String>> requests, boolean doDryRun, @PermissionControllerManager.Reason int reason, @NonNull String callerPackageName, @NonNull Consumer<Map<String, List<String>>> callback)112 public abstract void onRevokeRuntimePermissions( 113 @NonNull Map<String, List<String>> requests, boolean doDryRun, 114 @PermissionControllerManager.Reason int reason, @NonNull String callerPackageName, 115 @NonNull Consumer<Map<String, List<String>>> callback); 116 117 /** 118 * Create a backup of the runtime permissions. 119 * 120 * @param user The user to back up 121 * @param backup The stream to write the backup to 122 * @param callback Callback waiting for operation to be complete 123 */ 124 @BinderThread onGetRuntimePermissionsBackup(@onNull UserHandle user, @NonNull OutputStream backup, @NonNull Runnable callback)125 public abstract void onGetRuntimePermissionsBackup(@NonNull UserHandle user, 126 @NonNull OutputStream backup, @NonNull Runnable callback); 127 128 129 /** 130 * @deprecated Implement {@link #onStageAndApplyRuntimePermissionsBackup} instead 131 */ 132 @Deprecated 133 @BinderThread onRestoreRuntimePermissionsBackup(@onNull UserHandle user, @NonNull InputStream backup, @NonNull Runnable callback)134 public void onRestoreRuntimePermissionsBackup(@NonNull UserHandle user, 135 @NonNull InputStream backup, @NonNull Runnable callback) { 136 } 137 138 /** 139 * Restore a backup of the runtime permissions. 140 * 141 * <p>If an app mentioned in the backup is not installed the state should be saved to later 142 * be restored via {@link #onApplyStagedRuntimePermissionBackup}. 143 * 144 * @param user The user to restore 145 * @param backup The stream to read the backup from 146 * @param callback Callback waiting for operation to be complete 147 */ 148 @BinderThread onStageAndApplyRuntimePermissionsBackup(@onNull UserHandle user, @NonNull InputStream backup, @NonNull Runnable callback)149 public void onStageAndApplyRuntimePermissionsBackup(@NonNull UserHandle user, 150 @NonNull InputStream backup, @NonNull Runnable callback) { 151 onRestoreRuntimePermissionsBackup(user, backup, callback); 152 } 153 154 /** 155 * @deprecated Implement {@link #onApplyStagedRuntimePermissionBackup} instead 156 */ 157 @Deprecated 158 @BinderThread onRestoreDelayedRuntimePermissionsBackup(@onNull String packageName, @NonNull UserHandle user, @NonNull Consumer<Boolean> callback)159 public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String packageName, 160 @NonNull UserHandle user, @NonNull Consumer<Boolean> callback) { 161 } 162 163 /** 164 * Restore the permission state of an app that was provided in 165 * {@link #onStageAndApplyRuntimePermissionsBackup} but could not be restored back then. 166 * 167 * @param packageName The app to restore 168 * @param user The user to restore 169 * @param callback Callback waiting for whether there is still delayed backup left 170 */ 171 @BinderThread onApplyStagedRuntimePermissionBackup(@onNull String packageName, @NonNull UserHandle user, @NonNull Consumer<Boolean> callback)172 public void onApplyStagedRuntimePermissionBackup(@NonNull String packageName, 173 @NonNull UserHandle user, @NonNull Consumer<Boolean> callback) { 174 onRestoreDelayedRuntimePermissionsBackup(packageName, user, callback); 175 } 176 177 /** 178 * Gets the runtime permissions for an app. 179 * 180 * @param packageName The package for which to query. 181 * @param callback Callback waiting for the descriptions of the runtime permissions of the app 182 */ 183 @BinderThread onGetAppPermissions(@onNull String packageName, @NonNull Consumer<List<RuntimePermissionPresentationInfo>> callback)184 public abstract void onGetAppPermissions(@NonNull String packageName, 185 @NonNull Consumer<List<RuntimePermissionPresentationInfo>> callback); 186 187 /** 188 * Revokes the permission {@code permissionName} for app {@code packageName} 189 * 190 * @param packageName The package for which to revoke 191 * @param permissionName The permission to revoke 192 * @param callback Callback waiting for operation to be complete 193 */ 194 @BinderThread onRevokeRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull Runnable callback)195 public abstract void onRevokeRuntimePermission(@NonNull String packageName, 196 @NonNull String permissionName, @NonNull Runnable callback); 197 198 /** 199 * Count how many apps have one of a set of permissions. 200 * 201 * @param permissionNames The permissions the app might have 202 * @param flags Modify which apps to count. By default all non-system apps that request a 203 * permission are counted 204 * @param callback Callback waiting for the number of apps that have one of the permissions 205 */ 206 @BinderThread onCountPermissionApps(@onNull List<String> permissionNames, @CountPermissionAppsFlag int flags, @NonNull IntConsumer callback)207 public abstract void onCountPermissionApps(@NonNull List<String> permissionNames, 208 @CountPermissionAppsFlag int flags, @NonNull IntConsumer callback); 209 210 /** 211 * Count how many apps have used permissions. 212 * 213 * @param countSystem Also count system apps 214 * @param numMillis The number of milliseconds in the past to check for uses 215 * @param callback Callback waiting for the descriptions of the users of permissions 216 */ 217 @BinderThread onGetPermissionUsages(boolean countSystem, long numMillis, @NonNull Consumer<List<RuntimePermissionUsageInfo>> callback)218 public abstract void onGetPermissionUsages(boolean countSystem, long numMillis, 219 @NonNull Consumer<List<RuntimePermissionUsageInfo>> callback); 220 221 /** 222 * Grant or upgrade runtime permissions. The upgrade could be performed 223 * based on whether the device upgraded, whether the permission database 224 * version is old, because the permission policy changed, or because the 225 * permission controller has updated. 226 * 227 * @param callback Callback waiting for operation to be complete 228 * 229 * @see PackageManager#isDeviceUpgrading() 230 * @see PermissionManager#getRuntimePermissionsVersion() 231 * @see PermissionManager#setRuntimePermissionsVersion(int) 232 */ 233 @BinderThread onGrantOrUpgradeDefaultRuntimePermissions(@onNull Runnable callback)234 public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable callback); 235 236 237 /** 238 * Called by system to update the 239 * {@link PackageManager}{@code .FLAG_PERMISSION_USER_SENSITIVE_WHEN_*} flags for permissions. 240 * <p> 241 * 242 * If uid is -1, updates the permission flags for all packages. 243 * 244 * Typically called by the system when a new app is installed or updated or when creating a 245 * new user or upgrading either system or permission controller package. 246 * 247 * The callback will be executed by the provided Executor. 248 */ 249 @BinderThread onUpdateUserSensitivePermissionFlags(int uid, @NonNull Executor executor, @NonNull Runnable callback)250 public void onUpdateUserSensitivePermissionFlags(int uid, @NonNull Executor executor, 251 @NonNull Runnable callback) { 252 throw new AbstractMethodError("Must be overridden in implementing class"); 253 } 254 255 /** 256 * Runs {@link #onUpdateUserSensitivePermissionFlags(int, Executor, Runnable)} with the main 257 * executor. 258 */ 259 @BinderThread onUpdateUserSensitivePermissionFlags(int uid, @NonNull Runnable callback)260 public void onUpdateUserSensitivePermissionFlags(int uid, @NonNull Runnable callback) { 261 onUpdateUserSensitivePermissionFlags(uid, getMainExecutor(), callback); 262 } 263 264 /** 265 * @deprecated See {@link #onSetRuntimePermissionGrantStateByDeviceAdmin(String, 266 * AdminPermissionControlParams, Consumer)}. 267 * Set the runtime permission state from a device admin. 268 * 269 * @param callerPackageName The package name of the admin requesting the change 270 * @param packageName Package the permission belongs to 271 * @param permission Permission to change 272 * @param grantState State to set the permission into 273 * @param callback Callback waiting for whether the state could be set or not 274 */ 275 @Deprecated 276 @BinderThread onSetRuntimePermissionGrantStateByDeviceAdmin( @onNull String callerPackageName, @NonNull String packageName, @NonNull String permission, @PermissionGrantState int grantState, @NonNull Consumer<Boolean> callback)277 public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin( 278 @NonNull String callerPackageName, @NonNull String packageName, 279 @NonNull String permission, @PermissionGrantState int grantState, 280 @NonNull Consumer<Boolean> callback); 281 282 /** 283 * Set the runtime permission state from a device admin. 284 * 285 * @param callerPackageName The package name of the admin requesting the change 286 * @param params Parameters of admin request. 287 * @param callback Callback waiting for whether the state could be set or not 288 */ 289 @BinderThread onSetRuntimePermissionGrantStateByDeviceAdmin( @onNull String callerPackageName, @NonNull AdminPermissionControlParams params, @NonNull Consumer<Boolean> callback)290 public void onSetRuntimePermissionGrantStateByDeviceAdmin( 291 @NonNull String callerPackageName, @NonNull AdminPermissionControlParams params, 292 @NonNull Consumer<Boolean> callback) { 293 throw new AbstractMethodError("Must be overridden in implementing class"); 294 } 295 296 /** 297 * Called when a package is considered inactive based on the criteria given by 298 * {@link PermissionManager#startOneTimePermissionSession(String, long, long, int, int)}. 299 * This method is called at the end of a one-time permission session 300 * 301 * @param packageName The package that has been inactive 302 * 303 * @deprecated Implement {@link #onOneTimePermissionSessionTimeout(String, int)} instead. 304 */ 305 @Deprecated 306 @BinderThread onOneTimePermissionSessionTimeout(@onNull String packageName)307 public void onOneTimePermissionSessionTimeout(@NonNull String packageName) { 308 throw new AbstractMethodError("Must be overridden in implementing class"); 309 } 310 311 /** 312 * Called when a package is considered inactive based on the criteria given by 313 * {@link PermissionManager#startOneTimePermissionSession(String, long, long, int, int)}. 314 * This method is called at the end of a one-time permission session 315 * 316 * @param packageName The package that has been inactive 317 * @param deviceId The device ID refers either the primary device i.e. the phone or 318 * a virtual device. See {@link Context#DEVICE_ID_DEFAULT} 319 */ 320 @BinderThread 321 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) onOneTimePermissionSessionTimeout(@onNull String packageName, int deviceId)322 public void onOneTimePermissionSessionTimeout(@NonNull String packageName, 323 int deviceId) { 324 onOneTimePermissionSessionTimeout(packageName); 325 } 326 327 /** 328 * Get the platform permissions which belong to a particular permission group 329 * 330 * @param permissionGroupName The permission group whose permissions are desired 331 * @param callback A callback the permission names will be passed to 332 */ 333 @BinderThread onGetPlatformPermissionsForGroup(@onNull String permissionGroupName, @NonNull Consumer<List<String>> callback)334 public void onGetPlatformPermissionsForGroup(@NonNull String permissionGroupName, 335 @NonNull Consumer<List<String>> callback) { 336 throw new AbstractMethodError("Must be overridden in implementing class"); 337 } 338 339 /** 340 * Get the platform group of a particular permission, if the permission is a platform permission 341 * 342 * @param permissionName The permission name whose group is desired 343 * @param callback A callback the group name will be passed to 344 */ 345 @BinderThread onGetGroupOfPlatformPermission(@onNull String permissionName, @NonNull Consumer<String> callback)346 public void onGetGroupOfPlatformPermission(@NonNull String permissionName, 347 @NonNull Consumer<String> callback) { 348 throw new AbstractMethodError("Must be overridden in implementing class"); 349 } 350 351 /** 352 * Triggers the revocation of one or more permissions for a package. This should only be called 353 * at the request of {@code packageName}. 354 * <p> 355 * Background permissions which have no corresponding foreground permission still granted once 356 * the revocation is effective will also be revoked. 357 * <p> 358 * This revocation happens asynchronously and kills all processes running in the same UID as 359 * {@code packageName}. It will be triggered once it is safe to do so. 360 * 361 * @param packageName The name of the package for which the permissions will be revoked. 362 * @param permissions List of permissions to be revoked. 363 * @param callback Callback waiting for operation to be complete. 364 * 365 * @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection) 366 * 367 * @deprecated Implement {@link #onRevokeSelfPermissionsOnKill(String, List, int, Runnable)} 368 * instead. 369 */ 370 @Deprecated 371 @BinderThread onRevokeSelfPermissionsOnKill(@onNull String packageName, @NonNull List<String> permissions, @NonNull Runnable callback)372 public void onRevokeSelfPermissionsOnKill(@NonNull String packageName, 373 @NonNull List<String> permissions, @NonNull Runnable callback) { 374 throw new AbstractMethodError("Must be overridden in implementing class"); 375 } 376 377 /** 378 * Triggers the revocation of one or more permissions for a package and device. 379 * This should only be called at the request of {@code packageName}. 380 * <p> 381 * Background permissions which have no corresponding foreground permission still granted once 382 * the revocation is effective will also be revoked. 383 * <p> 384 * This revocation happens asynchronously and kills all processes running in the same UID as 385 * {@code packageName}. It will be triggered once it is safe to do so. 386 * 387 * @param packageName The name of the package for which the permissions will be revoked. 388 * @param permissions List of permissions to be revoked. 389 * @param deviceId The device ID refers either the primary device i.e. the phone or 390 * a virtual device. See {@link Context#DEVICE_ID_DEFAULT} 391 * @param callback Callback waiting for operation to be complete. 392 * 393 * @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection) 394 */ 395 @BinderThread 396 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) onRevokeSelfPermissionsOnKill(@onNull String packageName, @NonNull List<String> permissions, int deviceId, @NonNull Runnable callback)397 public void onRevokeSelfPermissionsOnKill(@NonNull String packageName, 398 @NonNull List<String> permissions, int deviceId, @NonNull Runnable callback) { 399 onRevokeSelfPermissionsOnKill(packageName, permissions, callback); 400 } 401 402 // TODO(b/272129940): Remove this API and device profile role description when we drop T 403 // support. 404 /** 405 * Get a user-readable sentence, describing the set of privileges that are to be granted to a 406 * companion app managing a device of the given profile. 407 * 408 * @param deviceProfileName the 409 * {@link android.companion.AssociationRequest.DeviceProfile device profile} name 410 * 411 * @deprecated Device profile privilege descriptions have been bundled in CDM APK since T. 412 * 413 * @hide 414 */ 415 @Deprecated 416 @SystemApi 417 @RequiresPermission(Manifest.permission.MANAGE_COMPANION_DEVICES) 418 @NonNull getPrivilegesDescriptionStringForProfile(@onNull String deviceProfileName)419 public String getPrivilegesDescriptionStringForProfile(@NonNull String deviceProfileName) { 420 throw new AbstractMethodError("Must be overridden in implementing class"); 421 } 422 423 /** 424 * Get the count of unused, hibernating apps on the device. 425 * 426 * @param callback callback after count is retrieved 427 * 428 * @hide 429 */ 430 @SystemApi 431 @RequiresPermission(Manifest.permission.MANAGE_APP_HIBERNATION) 432 @NonNull onGetUnusedAppCount(@onNull IntConsumer callback)433 public void onGetUnusedAppCount(@NonNull IntConsumer callback) { 434 throw new AbstractMethodError("Must be overridden in implementing class"); 435 } 436 437 /** 438 * Get the hibernation eligibility of the app. See 439 * {@link android.permission.PermissionControllerManager.HibernationEligibilityFlag}. 440 * 441 * @param packageName package to check eligibility 442 * @param callback callback after eligibility is returned 443 * 444 * @hide 445 */ 446 @SystemApi 447 @RequiresPermission(Manifest.permission.MANAGE_APP_HIBERNATION) onGetHibernationEligibility(@onNull String packageName, @NonNull IntConsumer callback)448 public void onGetHibernationEligibility(@NonNull String packageName, 449 @NonNull IntConsumer callback) { 450 throw new AbstractMethodError("Must be overridden in implementing class"); 451 } 452 453 @Override onBind(Intent intent)454 public final @NonNull IBinder onBind(Intent intent) { 455 return new IPermissionController.Stub() { 456 @Override 457 public void revokeRuntimePermissions( 458 Bundle bundleizedRequest, boolean doDryRun, int reason, 459 String callerPackageName, AndroidFuture callback) { 460 checkNotNull(bundleizedRequest, "bundleizedRequest"); 461 checkNotNull(callerPackageName); 462 checkNotNull(callback); 463 464 Map<String, List<String>> request = new ArrayMap<>(); 465 for (String packageName : bundleizedRequest.keySet()) { 466 Preconditions.checkNotNull(packageName); 467 468 ArrayList<String> permissions = 469 bundleizedRequest.getStringArrayList(packageName); 470 Preconditions.checkCollectionElementsNotNull(permissions, "permissions"); 471 472 request.put(packageName, permissions); 473 } 474 475 enforceSomePermissionsGrantedToCaller( 476 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 477 478 // Verify callerPackageName 479 try { 480 PackageInfo pkgInfo = getPackageManager().getPackageInfo(callerPackageName, 0); 481 checkArgument(getCallingUid() == pkgInfo.applicationInfo.uid); 482 } catch (PackageManager.NameNotFoundException e) { 483 throw new RuntimeException(e); 484 } 485 486 onRevokeRuntimePermissions(request, 487 doDryRun, reason, callerPackageName, revoked -> { 488 CollectionUtils.forEach(revoked, (pkg, perms) -> { 489 Preconditions.checkNotNull(pkg); 490 Preconditions.checkCollectionElementsNotNull(perms, "permissions"); 491 }); 492 callback.complete(revoked); 493 }); 494 } 495 496 /** 497 * Throw a {@link SecurityException} if not at least one of the permissions is granted. 498 * 499 * @param requiredPermissions A list of permissions. Any of of them if sufficient to 500 * pass the check 501 */ 502 private void enforceSomePermissionsGrantedToCaller( 503 @NonNull String... requiredPermissions) { 504 for (String requiredPermission : requiredPermissions) { 505 if (checkCallingPermission(requiredPermission) 506 == PackageManager.PERMISSION_GRANTED) { 507 return; 508 } 509 } 510 511 throw new SecurityException( 512 "At lest one of the following permissions is required: " + Arrays.toString( 513 requiredPermissions)); 514 } 515 516 517 @Override 518 public void getRuntimePermissionBackup(UserHandle user, ParcelFileDescriptor pipe) { 519 checkNotNull(user); 520 checkNotNull(pipe); 521 522 enforceSomePermissionsGrantedToCaller(Manifest.permission.GET_RUNTIME_PERMISSIONS); 523 524 try (OutputStream backup = new ParcelFileDescriptor.AutoCloseOutputStream(pipe)) { 525 CountDownLatch latch = new CountDownLatch(1); 526 onGetRuntimePermissionsBackup(user, backup, latch::countDown); 527 latch.await(); 528 } catch (IOException e) { 529 Log.e(LOG_TAG, "Could not open pipe to write backup to", e); 530 } catch (InterruptedException e) { 531 Log.e(LOG_TAG, "getRuntimePermissionBackup timed out", e); 532 } 533 } 534 535 @Override 536 public void stageAndApplyRuntimePermissionsBackup(UserHandle user, 537 ParcelFileDescriptor pipe) { 538 checkNotNull(user); 539 checkNotNull(pipe); 540 541 enforceSomePermissionsGrantedToCaller(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 542 Manifest.permission.RESTORE_RUNTIME_PERMISSIONS); 543 544 try (InputStream backup = new ParcelFileDescriptor.AutoCloseInputStream(pipe)) { 545 CountDownLatch latch = new CountDownLatch(1); 546 onStageAndApplyRuntimePermissionsBackup(user, backup, latch::countDown); 547 latch.await(); 548 } catch (IOException e) { 549 Log.e(LOG_TAG, "Could not open pipe to read backup from", e); 550 } catch (InterruptedException e) { 551 Log.e(LOG_TAG, "restoreRuntimePermissionBackup timed out", e); 552 } 553 } 554 555 @Override 556 public void applyStagedRuntimePermissionBackup(String packageName, UserHandle user, 557 AndroidFuture callback) { 558 checkNotNull(packageName); 559 checkNotNull(user); 560 checkNotNull(callback); 561 562 enforceSomePermissionsGrantedToCaller(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 563 Manifest.permission.RESTORE_RUNTIME_PERMISSIONS); 564 565 onApplyStagedRuntimePermissionBackup(packageName, user, callback::complete); 566 } 567 568 @Override 569 public void getAppPermissions(String packageName, AndroidFuture callback) { 570 checkNotNull(packageName, "packageName"); 571 checkNotNull(callback, "callback"); 572 573 enforceSomePermissionsGrantedToCaller(Manifest.permission.GET_RUNTIME_PERMISSIONS); 574 575 onGetAppPermissions(packageName, callback::complete); 576 } 577 578 @Override 579 public void revokeRuntimePermission(String packageName, String permissionName) { 580 checkNotNull(packageName, "packageName"); 581 checkNotNull(permissionName, "permissionName"); 582 583 enforceSomePermissionsGrantedToCaller( 584 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 585 586 CountDownLatch latch = new CountDownLatch(1); 587 PermissionControllerService.this.onRevokeRuntimePermission(packageName, 588 permissionName, latch::countDown); 589 try { 590 latch.await(); 591 } catch (InterruptedException e) { 592 Log.e(LOG_TAG, "revokeRuntimePermission timed out", e); 593 } 594 } 595 596 @Override 597 public void countPermissionApps(List<String> permissionNames, int flags, 598 AndroidFuture callback) { 599 checkCollectionElementsNotNull(permissionNames, "permissionNames"); 600 checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED); 601 checkNotNull(callback, "callback"); 602 603 enforceSomePermissionsGrantedToCaller(Manifest.permission.GET_RUNTIME_PERMISSIONS); 604 605 onCountPermissionApps(permissionNames, flags, callback::complete); 606 } 607 608 @Override 609 public void getPermissionUsages(boolean countSystem, long numMillis, 610 AndroidFuture callback) { 611 checkArgumentNonnegative(numMillis); 612 checkNotNull(callback, "callback"); 613 614 enforceSomePermissionsGrantedToCaller(Manifest.permission.GET_RUNTIME_PERMISSIONS); 615 616 onGetPermissionUsages(countSystem, numMillis, callback::complete); 617 } 618 619 @Override 620 public void setRuntimePermissionGrantStateByDeviceAdminFromParams( 621 String callerPackageName, AdminPermissionControlParams params, 622 AndroidFuture callback) { 623 checkStringNotEmpty(callerPackageName); 624 if (params.getGrantState() == PERMISSION_GRANT_STATE_GRANTED) { 625 enforceSomePermissionsGrantedToCaller( 626 Manifest.permission.GRANT_RUNTIME_PERMISSIONS); 627 } 628 629 if (params.getGrantState() == PERMISSION_GRANT_STATE_DENIED) { 630 enforceSomePermissionsGrantedToCaller( 631 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 632 } 633 634 enforceSomePermissionsGrantedToCaller( 635 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); 636 checkNotNull(callback); 637 638 onSetRuntimePermissionGrantStateByDeviceAdmin(callerPackageName, 639 params, callback::complete); 640 } 641 642 @Override 643 public void grantOrUpgradeDefaultRuntimePermissions(@NonNull AndroidFuture callback) { 644 checkNotNull(callback, "callback"); 645 646 enforceSomePermissionsGrantedToCaller( 647 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); 648 649 onGrantOrUpgradeDefaultRuntimePermissions(() -> callback.complete(true)); 650 } 651 652 @Override 653 public void updateUserSensitiveForApp(int uid, @NonNull AndroidFuture callback) { 654 Preconditions.checkNotNull(callback, "callback cannot be null"); 655 656 enforceSomePermissionsGrantedToCaller( 657 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); 658 659 try { 660 onUpdateUserSensitivePermissionFlags(uid, () -> callback.complete(null)); 661 } catch (Exception e) { 662 callback.completeExceptionally(e); 663 } 664 } 665 666 @Override 667 public void notifyOneTimePermissionSessionTimeout(String packageName, int deviceId) { 668 enforceSomePermissionsGrantedToCaller( 669 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 670 packageName = Preconditions.checkNotNull(packageName, 671 "packageName cannot be null"); 672 onOneTimePermissionSessionTimeout(packageName, deviceId); 673 } 674 675 @Override 676 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 677 checkNotNull(fd, "fd"); 678 checkNotNull(writer, "writer"); 679 680 enforceSomePermissionsGrantedToCaller(Manifest.permission.GET_RUNTIME_PERMISSIONS); 681 682 PermissionControllerService.this.dump(fd, writer, args); 683 } 684 685 @Override 686 public void getPrivilegesDescriptionStringForProfile( 687 @NonNull String deviceProfileName, 688 @NonNull AndroidFuture<String> callback) { 689 try { 690 checkStringNotEmpty(deviceProfileName); 691 Objects.requireNonNull(callback); 692 693 enforceSomePermissionsGrantedToCaller( 694 Manifest.permission.MANAGE_COMPANION_DEVICES); 695 696 callback.complete(PermissionControllerService 697 .this 698 .getPrivilegesDescriptionStringForProfile(deviceProfileName)); 699 } catch (Throwable t) { 700 callback.completeExceptionally(t); 701 } 702 } 703 704 @Override 705 public void getPlatformPermissionsForGroup( 706 @NonNull String permissionName, 707 @NonNull AndroidFuture<List<String>> callback) { 708 try { 709 Objects.requireNonNull(permissionName); 710 Objects.requireNonNull(callback); 711 PermissionControllerService.this.onGetPlatformPermissionsForGroup( 712 permissionName, callback::complete); 713 } catch (Throwable t) { 714 callback.completeExceptionally(t); 715 } 716 } 717 718 @Override 719 public void getGroupOfPlatformPermission( 720 @NonNull String permissionGroupName, 721 @NonNull AndroidFuture<String> callback) { 722 try { 723 Objects.requireNonNull(permissionGroupName); 724 Objects.requireNonNull(callback); 725 PermissionControllerService.this.onGetGroupOfPlatformPermission( 726 permissionGroupName, callback::complete); 727 } catch (Throwable t) { 728 callback.completeExceptionally(t); 729 } 730 } 731 732 @Override 733 public void getUnusedAppCount(@NonNull AndroidFuture callback) { 734 try { 735 Objects.requireNonNull(callback); 736 737 enforceSomePermissionsGrantedToCaller( 738 Manifest.permission.MANAGE_APP_HIBERNATION); 739 740 PermissionControllerService.this.onGetUnusedAppCount(callback::complete); 741 } catch (Throwable t) { 742 callback.completeExceptionally(t); 743 } 744 } 745 746 @Override 747 public void getHibernationEligibility(@NonNull String packageName, 748 @NonNull AndroidFuture callback) { 749 try { 750 Objects.requireNonNull(callback); 751 752 enforceSomePermissionsGrantedToCaller( 753 Manifest.permission.MANAGE_APP_HIBERNATION); 754 755 PermissionControllerService.this.onGetHibernationEligibility(packageName, 756 callback::complete); 757 } catch (Throwable t) { 758 callback.completeExceptionally(t); 759 } 760 } 761 762 @Override 763 public void revokeSelfPermissionsOnKill(@NonNull String packageName, 764 @NonNull List<String> permissions, int deviceId, 765 @NonNull AndroidFuture callback) { 766 try { 767 Objects.requireNonNull(callback); 768 769 final int callingUid = Binder.getCallingUid(); 770 int targetPackageUid = getPackageManager().getPackageUid(packageName, 771 PackageManager.PackageInfoFlags.of(0)); 772 if (targetPackageUid != callingUid) { 773 enforceSomePermissionsGrantedToCaller( 774 Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 775 } 776 onRevokeSelfPermissionsOnKill(packageName, permissions, deviceId, 777 () -> callback.complete(null)); 778 } catch (Throwable t) { 779 callback.completeExceptionally(t); 780 } 781 } 782 }; 783 } 784 } 785