1 /* 2 * Copyright (C) 2018 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.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 20 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE; 21 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 22 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 23 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 24 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 25 import static android.os.Build.VERSION_CODES.S; 26 import static android.permission.flags.Flags.FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE; 27 import static android.permission.flags.Flags.serverSideAttributionRegistration; 28 29 import android.Manifest; 30 import android.annotation.CheckResult; 31 import android.annotation.DurationMillisLong; 32 import android.annotation.FlaggedApi; 33 import android.annotation.IntDef; 34 import android.annotation.IntRange; 35 import android.annotation.NonNull; 36 import android.annotation.Nullable; 37 import android.annotation.RequiresPermission; 38 import android.annotation.SdkConstant; 39 import android.annotation.SdkConstant.SdkConstantType; 40 import android.annotation.SystemApi; 41 import android.annotation.SystemService; 42 import android.annotation.TestApi; 43 import android.annotation.UserIdInt; 44 import android.app.ActivityManager; 45 import android.app.ActivityThread; 46 import android.app.AppGlobals; 47 import android.app.AppOpsManager; 48 import android.app.IActivityManager; 49 import android.app.PropertyInvalidatedCache; 50 import android.companion.virtual.VirtualDevice; 51 import android.companion.virtual.VirtualDeviceManager; 52 import android.compat.annotation.ChangeId; 53 import android.compat.annotation.EnabledAfter; 54 import android.content.AttributionSource; 55 import android.content.Context; 56 import android.content.PermissionChecker; 57 import android.content.pm.IPackageManager; 58 import android.content.pm.PackageManager; 59 import android.content.pm.ParceledListSlice; 60 import android.content.pm.PermissionGroupInfo; 61 import android.content.pm.PermissionInfo; 62 import android.content.pm.permission.SplitPermissionInfoParcelable; 63 import android.media.AudioManager; 64 import android.os.Binder; 65 import android.os.Build; 66 import android.os.Handler; 67 import android.os.IBinder; 68 import android.os.Looper; 69 import android.os.Message; 70 import android.os.Parcel; 71 import android.os.Parcelable; 72 import android.os.Process; 73 import android.os.RemoteException; 74 import android.os.ServiceManager; 75 import android.os.SystemClock; 76 import android.os.UserHandle; 77 import android.permission.flags.Flags; 78 import android.text.TextUtils; 79 import android.util.ArrayMap; 80 import android.util.ArraySet; 81 import android.util.DebugUtils; 82 import android.util.Log; 83 import android.util.Slog; 84 85 import com.android.internal.R; 86 import com.android.internal.annotations.Immutable; 87 import com.android.internal.util.CollectionUtils; 88 import com.android.modules.utils.build.SdkLevel; 89 90 import java.lang.annotation.Retention; 91 import java.lang.annotation.RetentionPolicy; 92 import java.util.ArrayList; 93 import java.util.Collections; 94 import java.util.List; 95 import java.util.Map; 96 import java.util.Objects; 97 import java.util.Set; 98 99 /** 100 * System level service for accessing the permission capabilities of the platform. 101 * 102 * @hide 103 */ 104 @SystemApi 105 @SystemService(Context.PERMISSION_SERVICE) 106 public final class PermissionManager { 107 private static final String LOG_TAG = PermissionManager.class.getName(); 108 109 /** 110 * The permission is granted. 111 */ 112 public static final int PERMISSION_GRANTED = 0; 113 114 /** 115 * The permission is denied. Applicable only to runtime permissions. 116 * <p> 117 * The app isn't expecting the permission to be denied so that a "no-op" action should be taken, 118 * such as returning an empty result. 119 */ 120 public static final int PERMISSION_SOFT_DENIED = 1; 121 122 /** 123 * The permission is denied. 124 * <p> 125 * The app should receive a {@code SecurityException}, or an error through a relevant callback. 126 */ 127 public static final int PERMISSION_HARD_DENIED = 2; 128 129 /** @hide */ 130 @IntDef(prefix = { "PERMISSION_" }, value = { 131 PERMISSION_GRANTED, 132 PERMISSION_SOFT_DENIED, 133 PERMISSION_HARD_DENIED 134 }) 135 @Retention(RetentionPolicy.SOURCE) 136 public @interface PermissionResult {} 137 138 /** 139 * The set of flags that indicate that a permission state has been explicitly set 140 * 141 * @hide 142 */ 143 public static final int EXPLICIT_SET_FLAGS = FLAG_PERMISSION_USER_SET 144 | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_POLICY_FIXED 145 | FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_GRANTED_BY_DEFAULT 146 | FLAG_PERMISSION_GRANTED_BY_ROLE; 147 148 /** 149 * Activity action: Launch UI to review permission decisions. 150 * <p> 151 * <strong>Important:</strong>You must protect the activity that handles this action with the 152 * {@link android.Manifest.permission#START_REVIEW_PERMISSION_DECISIONS} permission to ensure 153 * that only the system can launch this activity. The system will not launch activities that are 154 * not properly protected. 155 * <p> 156 * Input: Nothing. 157 * </p> 158 * <p> 159 * Output: Nothing. 160 * </p> 161 */ 162 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 163 @RequiresPermission(android.Manifest.permission.START_REVIEW_PERMISSION_DECISIONS) 164 public static final String ACTION_REVIEW_PERMISSION_DECISIONS = 165 "android.permission.action.REVIEW_PERMISSION_DECISIONS"; 166 167 168 /** @hide */ 169 public static final String LOG_TAG_TRACE_GRANTS = "PermissionGrantTrace"; 170 171 /** @hide */ 172 public static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 173 "permissions revoked"; 174 /** @hide */ 175 public static final String KILL_APP_REASON_GIDS_CHANGED = 176 "permission grant or revoke changed gids"; 177 178 private static final String SYSTEM_PKG = "android"; 179 180 /** 181 * Refuse to install package if groups of permissions are bad 182 * - Permission groups should only be shared between apps sharing a certificate 183 * - If a permission belongs to a group that group should be defined 184 * 185 * @hide 186 */ 187 @ChangeId 188 @EnabledAfter(targetSdkVersion = S) 189 public static final long CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS = 146211400; 190 191 /** 192 * Whether to use the new {@link com.android.server.permission.access.AccessCheckingService}. 193 * 194 * @hide 195 */ 196 public static final boolean USE_ACCESS_CHECKING_SERVICE = SdkLevel.isAtLeastV(); 197 198 /** 199 * The time to wait in between refreshing the exempted indicator role packages 200 */ 201 private static final long EXEMPTED_INDICATOR_ROLE_UPDATE_FREQUENCY_MS = 15000; 202 203 private static long sLastIndicatorUpdateTime = -1; 204 205 private static final int[] EXEMPTED_ROLES = {R.string.config_systemAmbientAudioIntelligence, 206 R.string.config_systemUiIntelligence, R.string.config_systemAudioIntelligence, 207 R.string.config_systemNotificationIntelligence, R.string.config_systemTextIntelligence, 208 R.string.config_systemVisualIntelligence}; 209 210 private static final String[] INDICATOR_EXEMPTED_PACKAGES = new String[EXEMPTED_ROLES.length]; 211 212 /** 213 * Note: Changing this won't do anything on its own - you should also change the filtering in 214 * {@link #shouldTraceGrant}. 215 * 216 * See log output for tag {@link #LOG_TAG_TRACE_GRANTS} 217 * 218 * @hide 219 */ 220 public static final boolean DEBUG_TRACE_GRANTS = false; 221 /** 222 * @hide 223 */ 224 public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false; 225 226 /** 227 * Additional debug log for virtual device permissions. 228 * @hide 229 */ 230 public static final boolean DEBUG_DEVICE_PERMISSIONS = false; 231 232 /** 233 * Intent extra: List of PermissionGroupUsages 234 * <p> 235 * Type: {@code List<PermissionGroupUsage>} 236 * </p> 237 * @hide 238 */ 239 @SystemApi 240 public static final String EXTRA_PERMISSION_USAGES = 241 "android.permission.extra.PERMISSION_USAGES"; 242 243 /** 244 * Specify what permissions are device aware. Only device aware permissions can be granted to 245 * a remote device. 246 * @hide 247 */ 248 public static final Set<String> DEVICE_AWARE_PERMISSIONS = 249 Flags.deviceAwarePermissionsEnabled() 250 ? Set.of(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) 251 : Collections.emptySet(); 252 253 private final @NonNull Context mContext; 254 255 private final IPackageManager mPackageManager; 256 257 private final IPermissionManager mPermissionManager; 258 259 private final LegacyPermissionManager mLegacyPermissionManager; 260 261 private final ArrayMap<PackageManager.OnPermissionsChangedListener, 262 IOnPermissionsChangeListener> mPermissionListeners = new ArrayMap<>(); 263 private PermissionUsageHelper mUsageHelper; 264 265 private List<SplitPermissionInfo> mSplitPermissionInfos; 266 267 /** 268 * Creates a new instance. 269 * 270 * @param context The current context in which to operate 271 * 272 * @hide 273 */ PermissionManager(@onNull Context context)274 public PermissionManager(@NonNull Context context) 275 throws ServiceManager.ServiceNotFoundException { 276 mContext = context; 277 mPackageManager = AppGlobals.getPackageManager(); 278 mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow( 279 "permissionmgr")); 280 mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class); 281 } 282 283 /** 284 * Checks whether a given data access chain described by the given {@link AttributionSource} 285 * has a given permission. 286 * 287 * <strong>NOTE:</strong> Use this method only for permission checks at the 288 * point where you will deliver the permission protected data to clients. 289 * 290 * <p>For example, if an app registers a location listener it should have the location 291 * permission but no data is actually sent to the app at the moment of registration 292 * and you should use {@link #checkPermissionForPreflight(String, AttributionSource)} 293 * to determine if the app has or may have location permission (if app has only foreground 294 * location the grant state depends on the app's fg/gb state) and this check will not 295 * leave a trace that permission protected data was delivered. When you are about to 296 * deliver the location data to a registered listener you should use this method which 297 * will evaluate the permission access based on the current fg/bg state of the app and 298 * leave a record that the data was accessed. 299 * 300 * <p>Requires the start of the AttributionSource chain to have the UPDATE_APP_OPS_STATS 301 * permission for the app op accesses to be given the TRUSTED_PROXY/PROXIED flags, otherwise the 302 * accesses will have the UNTRUSTED flags. 303 * 304 * @param permission The permission to check. 305 * @param attributionSource the permission identity 306 * @param message A message describing the reason the permission was checked 307 * @return The permission check result which is either {@link #PERMISSION_GRANTED} 308 * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}. 309 * 310 * @see #checkPermissionForPreflight(String, AttributionSource) 311 */ 312 @PermissionResult 313 @RequiresPermission(value = Manifest.permission.UPDATE_APP_OPS_STATS, conditional = true) checkPermissionForDataDelivery(@onNull String permission, @NonNull AttributionSource attributionSource, @Nullable String message)314 public int checkPermissionForDataDelivery(@NonNull String permission, 315 @NonNull AttributionSource attributionSource, @Nullable String message) { 316 return PermissionChecker.checkPermissionForDataDelivery(mContext, permission, 317 // FIXME(b/199526514): PID should be passed inside AttributionSource. 318 PermissionChecker.PID_UNKNOWN, attributionSource, message); 319 } 320 321 /** 322 * 323 * Similar to checkPermissionForDataDelivery, except it results in an app op start, rather than 324 * a note. If this method is used, then {@link #finishDataDelivery(String, AttributionSource)} 325 * must be used when access is finished. 326 * 327 * @param permission The permission to check. 328 * @param attributionSource the permission identity 329 * @param message A message describing the reason the permission was checked 330 * @return The permission check result which is either {@link #PERMISSION_GRANTED} 331 * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}. 332 * 333 * <p>Requires the start of the AttributionSource chain to have the UPDATE_APP_OPS_STATS 334 * permission for the app op accesses to be given the TRUSTED_PROXY/PROXIED flags, otherwise the 335 * accesses will have the UNTRUSTED flags. 336 * 337 * @see #checkPermissionForDataDelivery(String, AttributionSource, String) 338 */ 339 @PermissionResult 340 @RequiresPermission(value = Manifest.permission.UPDATE_APP_OPS_STATS, conditional = true) checkPermissionForStartDataDelivery(@onNull String permission, @NonNull AttributionSource attributionSource, @Nullable String message)341 public int checkPermissionForStartDataDelivery(@NonNull String permission, 342 @NonNull AttributionSource attributionSource, @Nullable String message) { 343 return PermissionChecker.checkPermissionForDataDelivery(mContext, permission, 344 // FIXME(b/199526514): PID should be passed inside AttributionSource. 345 PermissionChecker.PID_UNKNOWN, attributionSource, message, true); 346 } 347 348 /** 349 * Indicate that usage has finished for an {@link AttributionSource} started with 350 * {@link #checkPermissionForStartDataDelivery(String, AttributionSource, String)} 351 * 352 * @param permission The permission to check. 353 * @param attributionSource the permission identity to finish 354 */ finishDataDelivery(@onNull String permission, @NonNull AttributionSource attributionSource)355 public void finishDataDelivery(@NonNull String permission, 356 @NonNull AttributionSource attributionSource) { 357 PermissionChecker.finishDataDelivery(mContext, AppOpsManager.permissionToOp(permission), 358 attributionSource); 359 } 360 361 /** 362 * Checks whether a given data access chain described by the given {@link AttributionSource} 363 * has a given permission. Call this method if you are the datasource which would not blame you 364 * for access to the data since you are the data. Use this API if you are the datasource of the 365 * protected state. 366 * 367 * <strong>NOTE:</strong> Use this method only for permission checks at the 368 * point where you will deliver the permission protected data to clients. 369 * 370 * <p>For example, if an app registers a location listener it should have the location 371 * permission but no data is actually sent to the app at the moment of registration 372 * and you should use {@link #checkPermissionForPreflight(String, AttributionSource)} 373 * to determine if the app has or may have location permission (if app has only foreground 374 * location the grant state depends on the app's fg/gb state) and this check will not 375 * leave a trace that permission protected data was delivered. When you are about to 376 * deliver the location data to a registered listener you should use this method which 377 * will evaluate the permission access based on the current fg/bg state of the app and 378 * leave a record that the data was accessed. 379 * 380 * <p>Requires the start of the AttributionSource chain to have the UPDATE_APP_OPS_STATS 381 * permission for the app op accesses to be given the TRUSTED_PROXY/PROXIED flags, otherwise the 382 * accesses will have the UNTRUSTED flags. 383 * 384 * @param permission The permission to check. 385 * @param attributionSource the permission identity 386 * @param message A message describing the reason the permission was checked 387 * @return The permission check result which is either {@link #PERMISSION_GRANTED} 388 * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}. 389 * 390 * @see #checkPermissionForPreflight(String, AttributionSource) 391 */ 392 @PermissionResult 393 @RequiresPermission(value = Manifest.permission.UPDATE_APP_OPS_STATS, conditional = true) checkPermissionForDataDeliveryFromDataSource(@onNull String permission, @NonNull AttributionSource attributionSource, @Nullable String message)394 public int checkPermissionForDataDeliveryFromDataSource(@NonNull String permission, 395 @NonNull AttributionSource attributionSource, @Nullable String message) { 396 return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(mContext, permission, 397 PermissionChecker.PID_UNKNOWN, attributionSource, message); 398 } 399 400 /** 401 * Checks whether a given data access chain described by the given {@link AttributionSource} 402 * has a given permission. 403 * 404 * <strong>NOTE:</strong> Use this method only for permission checks at the 405 * preflight point where you will not deliver the permission protected data 406 * to clients but schedule permission data delivery, apps register listeners, 407 * etc. 408 * 409 * <p>For example, if an app registers a data listener it should have the required 410 * permission but no data is actually sent to the app at the moment of registration 411 * and you should use this method to determine if the app has or may have the 412 * permission and this check will not leave a trace that permission protected data 413 * was delivered. When you are about to deliver the protected data to a registered 414 * listener you should use {@link #checkPermissionForDataDelivery(String, 415 * AttributionSource, String)} which will evaluate the permission access based 416 * on the current fg/bg state of the app and leave a record that the data was accessed. 417 * 418 * @param permission The permission to check. 419 * @param attributionSource The identity for which to check the permission. 420 * @return The permission check result which is either {@link #PERMISSION_GRANTED} 421 * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}. 422 */ 423 @PermissionResult checkPermissionForPreflight(@onNull String permission, @NonNull AttributionSource attributionSource)424 public int checkPermissionForPreflight(@NonNull String permission, 425 @NonNull AttributionSource attributionSource) { 426 return PermissionChecker.checkPermissionForPreflight(mContext, permission, 427 attributionSource); 428 } 429 430 /** 431 * Retrieve all of the information we know about a particular permission. 432 * 433 * @param permissionName the fully qualified name (e.g. com.android.permission.LOGIN) of the 434 * permission you are interested in 435 * @param flags additional option flags to modify the data returned 436 * @return a {@link PermissionInfo} containing information about the permission, or {@code null} 437 * if not found 438 * 439 * @hide Pending API 440 */ 441 @Nullable getPermissionInfo(@onNull String permissionName, @PackageManager.PermissionInfoFlags int flags)442 public PermissionInfo getPermissionInfo(@NonNull String permissionName, 443 @PackageManager.PermissionInfoFlags int flags) { 444 try { 445 final String packageName = mContext.getOpPackageName(); 446 return mPermissionManager.getPermissionInfo(permissionName, packageName, flags); 447 } catch (RemoteException e) { 448 throw e.rethrowFromSystemServer(); 449 } 450 } 451 452 /** 453 * Query for all of the permissions associated with a particular group. 454 * 455 * @param groupName the fully qualified name (e.g. com.android.permission.LOGIN) of the 456 * permission group you are interested in. Use {@code null} to find all of the 457 * permissions not associated with a group 458 * @param flags additional option flags to modify the data returned 459 * @return a list of {@link PermissionInfo} containing information about all of the permissions 460 * in the given group, or {@code null} if the group is not found 461 * 462 * @hide Pending API 463 */ 464 @Nullable queryPermissionsByGroup(@ullable String groupName, @PackageManager.PermissionInfoFlags int flags)465 public List<PermissionInfo> queryPermissionsByGroup(@Nullable String groupName, 466 @PackageManager.PermissionInfoFlags int flags) { 467 try { 468 final ParceledListSlice<PermissionInfo> parceledList = 469 mPermissionManager.queryPermissionsByGroup(groupName, flags); 470 if (parceledList == null) { 471 return null; 472 } 473 return parceledList.getList(); 474 } catch (RemoteException e) { 475 throw e.rethrowFromSystemServer(); 476 } 477 } 478 479 /** 480 * Add a new dynamic permission to the system. For this to work, your package must have defined 481 * a permission tree through the 482 * {@link android.R.styleable#AndroidManifestPermissionTree <permission-tree>} tag in its 483 * manifest. A package can only add permissions to trees that were defined by either its own 484 * package or another with the same user id; a permission is in a tree if it matches the name of 485 * the permission tree + ".": for example, "com.foo.bar" is a member of the permission tree 486 * "com.foo". 487 * <p> 488 * It is good to make your permission tree name descriptive, because you are taking possession 489 * of that entire set of permission names. Thus, it must be under a domain you control, with a 490 * suffix that will not match any normal permissions that may be declared in any applications 491 * that are part of that domain. 492 * <p> 493 * New permissions must be added before any .apks are installed that use those permissions. 494 * Permissions you add through this method are remembered across reboots of the device. If the 495 * given permission already exists, the info you supply here will be used to update it. 496 * 497 * @param permissionInfo description of the permission to be added 498 * @param async whether the persistence of the permission should be asynchronous, allowing it to 499 * return quicker and batch a series of adds, at the expense of no guarantee the 500 * added permission will be retained if the device is rebooted before it is 501 * written. 502 * @return {@code true} if a new permission was created, {@code false} if an existing one was 503 * updated 504 * @throws SecurityException if you are not allowed to add the given permission name 505 * 506 * @see #removePermission(String) 507 * 508 * @hide Pending API 509 */ addPermission(@onNull PermissionInfo permissionInfo, boolean async)510 public boolean addPermission(@NonNull PermissionInfo permissionInfo, boolean async) { 511 try { 512 return mPermissionManager.addPermission(permissionInfo, async); 513 } catch (RemoteException e) { 514 throw e.rethrowFromSystemServer(); 515 } 516 } 517 518 /** 519 * Removes a permission that was previously added with 520 * {@link #addPermission(PermissionInfo, boolean)}. The same ownership rules apply -- you are 521 * only allowed to remove permissions that you are allowed to add. 522 * 523 * @param permissionName the name of the permission to remove 524 * @throws SecurityException if you are not allowed to remove the given permission name 525 * 526 * @see #addPermission(PermissionInfo, boolean) 527 * 528 * @hide Pending API 529 */ removePermission(@onNull String permissionName)530 public void removePermission(@NonNull String permissionName) { 531 try { 532 mPermissionManager.removePermission(permissionName); 533 } catch (RemoteException e) { 534 throw e.rethrowFromSystemServer(); 535 } 536 } 537 538 /** 539 * Retrieve all of the information we know about a particular group of permissions. 540 * 541 * @param groupName the fully qualified name (e.g. com.android.permission_group.APPS) of the 542 * permission you are interested in 543 * @param flags additional option flags to modify the data returned 544 * @return a {@link PermissionGroupInfo} containing information about the permission, or 545 * {@code null} if not found 546 * 547 * @hide Pending API 548 */ 549 @Nullable getPermissionGroupInfo(@onNull String groupName, @PackageManager.PermissionGroupInfoFlags int flags)550 public PermissionGroupInfo getPermissionGroupInfo(@NonNull String groupName, 551 @PackageManager.PermissionGroupInfoFlags int flags) { 552 try { 553 return mPermissionManager.getPermissionGroupInfo(groupName, flags); 554 } catch (RemoteException e) { 555 throw e.rethrowFromSystemServer(); 556 } 557 } 558 559 /** 560 * Retrieve all of the known permission groups in the system. 561 * 562 * @param flags additional option flags to modify the data returned 563 * @return a list of {@link PermissionGroupInfo} containing information about all of the known 564 * permission groups 565 * 566 * @hide Pending API 567 */ 568 @NonNull getAllPermissionGroups( @ackageManager.PermissionGroupInfoFlags int flags)569 public List<PermissionGroupInfo> getAllPermissionGroups( 570 @PackageManager.PermissionGroupInfoFlags int flags) { 571 try { 572 final ParceledListSlice<PermissionGroupInfo> parceledList = 573 mPermissionManager.getAllPermissionGroups(flags); 574 if (parceledList == null) { 575 return Collections.emptyList(); 576 } 577 return parceledList.getList(); 578 } catch (RemoteException e) { 579 throw e.rethrowFromSystemServer(); 580 } 581 } 582 583 /** 584 * Checks whether a particular permissions has been revoked for a package by policy. Typically 585 * the device owner or the profile owner may apply such a policy. The user cannot grant policy 586 * revoked permissions, hence the only way for an app to get such a permission is by a policy 587 * change. 588 * 589 * @param packageName the name of the package you are checking against 590 * @param permissionName the name of the permission you are checking for 591 * 592 * @return whether the permission is restricted by policy 593 * 594 * @hide Pending API 595 */ 596 @CheckResult isPermissionRevokedByPolicy(@onNull String packageName, @NonNull String permissionName)597 public boolean isPermissionRevokedByPolicy(@NonNull String packageName, 598 @NonNull String permissionName) { 599 try { 600 return mPermissionManager.isPermissionRevokedByPolicy(packageName, permissionName, 601 mContext.getDeviceId(), mContext.getUserId()); 602 } catch (RemoteException e) { 603 throw e.rethrowFromSystemServer(); 604 } 605 } 606 607 /** @hide */ shouldTraceGrant( @onNull String packageName, @NonNull String permissionName, int userId)608 public static boolean shouldTraceGrant( 609 @NonNull String packageName, @NonNull String permissionName, int userId) { 610 // To be modified when debugging 611 // template: if ("".equals(packageName) && "".equals(permissionName)) return true; 612 return false; 613 } 614 615 /** 616 * Grant a runtime permission to an application which the application does not already have. The 617 * permission must have been requested by the application. If the application is not allowed to 618 * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or 619 * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown. 620 * <p> 621 * <strong>Note: </strong>Using this API requires holding 622 * {@code android.permission.GRANT_RUNTIME_PERMISSIONS} and if the user ID is not the current 623 * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}. 624 * 625 * @param packageName the package to which to grant the permission 626 * @param permissionName the permission name to grant 627 * @param user the user for which to grant the permission 628 * 629 * @see #revokeRuntimePermission(String, String, android.os.UserHandle, String) 630 * 631 * @hide 632 */ 633 @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 634 //@SystemApi grantRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull UserHandle user)635 public void grantRuntimePermission(@NonNull String packageName, 636 @NonNull String permissionName, @NonNull UserHandle user) { 637 String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId()); 638 if (persistentDeviceId == null) { 639 return; 640 } 641 642 grantRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, user); 643 } 644 645 /** 646 * Grant a runtime permission to an application which the application does not already have. The 647 * permission must have been requested by the application. If the application is not allowed to 648 * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or 649 * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown. 650 * 651 * @param packageName the package to which to grant the permission 652 * @param permissionName the permission name to grant 653 * @param persistentDeviceId the device Id to which to grant the permission 654 * 655 * @see #revokeRuntimePermission(String, String, String, String) 656 * 657 * @hide 658 */ 659 @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 660 @SystemApi 661 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) grantRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId)662 public void grantRuntimePermission(@NonNull String packageName, 663 @NonNull String permissionName, @NonNull String persistentDeviceId) { 664 grantRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, 665 mContext.getUser()); 666 } 667 grantRuntimePermissionInternal(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull UserHandle user)668 private void grantRuntimePermissionInternal(@NonNull String packageName, 669 @NonNull String permissionName, @NonNull String persistentDeviceId, 670 @NonNull UserHandle user) { 671 if (DEBUG_TRACE_GRANTS 672 && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) { 673 Log.i(LOG_TAG_TRACE_GRANTS, "App " + mContext.getPackageName() + " is granting " 674 + packageName + " " 675 + permissionName + " for user " + user.getIdentifier() 676 + " for persistent device " + persistentDeviceId, new RuntimeException()); 677 } 678 try { 679 mPermissionManager.grantRuntimePermission(packageName, permissionName, 680 persistentDeviceId, user.getIdentifier()); 681 } catch (RemoteException e) { 682 throw e.rethrowFromSystemServer(); 683 } 684 } 685 686 /** 687 * Revoke a runtime permission that was previously granted by 688 * {@link #grantRuntimePermission(String, String, android.os.UserHandle)}. The permission must 689 * have been requested by and granted to the application. If the application is not allowed to 690 * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or 691 * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown. 692 * <p> 693 * <strong>Note: </strong>Using this API requires holding 694 * {@code android.permission.REVOKE_RUNTIME_PERMISSIONS} and if the user ID is not the current 695 * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}. 696 * 697 * @param packageName the package from which to revoke the permission 698 * @param permissionName the permission name to revoke 699 * @param user the user for which to revoke the permission 700 * @param reason the reason for the revoke, or {@code null} for unspecified 701 * 702 * @see #grantRuntimePermission(String, String, android.os.UserHandle) 703 * 704 * @hide 705 */ 706 @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 707 //@SystemApi revokeRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull UserHandle user, @Nullable String reason)708 public void revokeRuntimePermission(@NonNull String packageName, 709 @NonNull String permissionName, @NonNull UserHandle user, @Nullable String reason) { 710 String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId()); 711 if (persistentDeviceId == null) { 712 return; 713 } 714 715 revokeRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, user, 716 reason); 717 } 718 719 /** 720 * Revoke a runtime permission that was previously granted by 721 * {@link #grantRuntimePermission(String, String, String)}. The permission must 722 * have been requested by and granted to the application. If the application is not allowed to 723 * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or 724 * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown. 725 * 726 * @param packageName the package from which to revoke the permission 727 * @param permissionName the permission name to revoke 728 * @param persistentDeviceId the persistent device id for which to revoke the permission 729 * @param reason the reason for the revoke, or {@code null} for unspecified 730 * 731 * @see #grantRuntimePermission(String, String, String) 732 * 733 * @hide 734 */ 735 @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 736 @SystemApi 737 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) revokeRuntimePermission(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @Nullable String reason)738 public void revokeRuntimePermission(@NonNull String packageName, 739 @NonNull String permissionName, @NonNull String persistentDeviceId, 740 @Nullable String reason) { 741 revokeRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, 742 mContext.getUser(), reason); 743 } 744 revokeRuntimePermissionInternal(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull UserHandle user, @Nullable String reason)745 private void revokeRuntimePermissionInternal(@NonNull String packageName, 746 @NonNull String permissionName, @NonNull String persistentDeviceId, 747 @NonNull UserHandle user, @Nullable String reason) { 748 if (DEBUG_TRACE_PERMISSION_UPDATES 749 && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) { 750 Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " " 751 + permissionName + " for user " + user.getIdentifier() 752 + " for persistent device " 753 + persistentDeviceId + " with reason " 754 + reason, new RuntimeException()); 755 } 756 try { 757 mPermissionManager.revokeRuntimePermission(packageName, permissionName, 758 persistentDeviceId, user.getIdentifier(), reason); 759 } catch (RemoteException e) { 760 throw e.rethrowFromSystemServer(); 761 } 762 } 763 764 /** 765 * Gets the state flags associated with a permission. 766 * 767 * @param packageName the package name for which to get the flags 768 * @param permissionName the permission for which to get the flags 769 * @param user the user for which to get permission flags 770 * @return the permission flags 771 * 772 * @hide 773 */ 774 @PackageManager.PermissionFlags 775 @RequiresPermission(anyOf = { 776 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 777 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 778 android.Manifest.permission.GET_RUNTIME_PERMISSIONS 779 }) 780 //@SystemApi getPermissionFlags(@onNull String packageName, @NonNull String permissionName, @NonNull UserHandle user)781 public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName, 782 @NonNull UserHandle user) { 783 String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId()); 784 if (persistentDeviceId == null) { 785 return 0; 786 } 787 788 return getPermissionFlagsInternal(packageName, permissionName, persistentDeviceId, user); 789 } 790 791 /** 792 * Gets the state flags associated with a permission. 793 * 794 * @param packageName the package name for which to get the flags 795 * @param permissionName the permission for which to get the flags 796 * @param persistentDeviceId the persistent device Id for which to get permission flags 797 * @return the permission flags 798 * 799 * @hide 800 */ 801 @PackageManager.PermissionFlags 802 @RequiresPermission(anyOf = { 803 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 804 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 805 android.Manifest.permission.GET_RUNTIME_PERMISSIONS 806 }) 807 @SystemApi 808 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) getPermissionFlags(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId)809 public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName, 810 @NonNull String persistentDeviceId) { 811 return getPermissionFlagsInternal(packageName, permissionName, persistentDeviceId, 812 mContext.getUser()); 813 } 814 getPermissionFlagsInternal(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @NonNull UserHandle user)815 private int getPermissionFlagsInternal(@NonNull String packageName, 816 @NonNull String permissionName, @NonNull String persistentDeviceId, 817 @NonNull UserHandle user) { 818 try { 819 return mPermissionManager.getPermissionFlags(packageName, permissionName, 820 persistentDeviceId, user.getIdentifier()); 821 } catch (RemoteException e) { 822 throw e.rethrowFromSystemServer(); 823 } 824 } 825 826 /** 827 * Updates the flags associated with a permission by replacing the flags in the specified mask 828 * with the provided flag values. 829 * 830 * @param packageName The package name for which to update the flags 831 * @param permissionName The permission for which to update the flags 832 * @param flagMask The flags which to replace 833 * @param flagValues The flags with which to replace 834 * @param user The user for which to update the permission flags 835 * 836 * @hide 837 */ 838 @RequiresPermission(anyOf = { 839 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 840 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS 841 }) 842 //@SystemApi updatePermissionFlags(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionFlags int flagMask, @PackageManager.PermissionFlags int flagValues, @NonNull UserHandle user)843 public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName, 844 @PackageManager.PermissionFlags int flagMask, 845 @PackageManager.PermissionFlags int flagValues, @NonNull UserHandle user) { 846 String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId()); 847 if (persistentDeviceId == null) { 848 return; 849 } 850 851 updatePermissionFlagsInternal(packageName, permissionName, flagMask, flagValues, 852 persistentDeviceId, user); 853 } 854 855 /** 856 * Updates the flags associated with a permission by replacing the flags in the specified mask 857 * with the provided flag values. 858 * 859 * @param packageName The package name for which to update the flags 860 * @param permissionName The permission for which to update the flags 861 * @param persistentDeviceId The persistent device for which to update the permission flags 862 * @param flagMask The flags which to replace 863 * @param flagValues The flags with which to replace 864 * 865 * @hide 866 */ 867 @RequiresPermission(anyOf = { 868 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 869 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS 870 }) 871 @SystemApi 872 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) updatePermissionFlags(@onNull String packageName, @NonNull String permissionName, @NonNull String persistentDeviceId, @PackageManager.PermissionFlags int flagMask, @PackageManager.PermissionFlags int flagValues )873 public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName, 874 @NonNull String persistentDeviceId, 875 @PackageManager.PermissionFlags int flagMask, 876 @PackageManager.PermissionFlags int flagValues 877 ) { 878 updatePermissionFlagsInternal(packageName, permissionName, flagMask, flagValues, 879 persistentDeviceId, mContext.getUser()); 880 } 881 updatePermissionFlagsInternal(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionFlags int flagMask, @PackageManager.PermissionFlags int flagValues, @NonNull String persistentDeviceId, @NonNull UserHandle user )882 private void updatePermissionFlagsInternal(@NonNull String packageName, 883 @NonNull String permissionName, 884 @PackageManager.PermissionFlags int flagMask, 885 @PackageManager.PermissionFlags int flagValues, @NonNull String persistentDeviceId, 886 @NonNull UserHandle user 887 ) { 888 if (DEBUG_TRACE_PERMISSION_UPDATES && shouldTraceGrant(packageName, permissionName, 889 user.getIdentifier())) { 890 Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is updating flags for " 891 + packageName + " " + permissionName + " for user " 892 + user.getIdentifier() + " for persistentDeviceId " + persistentDeviceId + ": " 893 + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask) 894 + " := " + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", 895 flagValues), new RuntimeException()); 896 } 897 try { 898 final boolean checkAdjustPolicyFlagPermission = 899 mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q; 900 mPermissionManager.updatePermissionFlags(packageName, permissionName, flagMask, 901 flagValues, checkAdjustPolicyFlagPermission, 902 persistentDeviceId, user.getIdentifier()); 903 } catch (RemoteException e) { 904 throw e.rethrowFromSystemServer(); 905 } 906 } 907 908 /** 909 * Gets the restricted permissions that have been allowlisted and the app is allowed to have 910 * them granted in their full form. 911 * <p> 912 * Permissions can be hard restricted which means that the app cannot hold them or soft 913 * restricted where the app can hold the permission but in a weaker form. Whether a permission 914 * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or 915 * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission 916 * declaration. Allowlisting a hard restricted permission allows for the to hold that permission 917 * and allowlisting a soft restricted permission allows the app to hold the permission in its 918 * full, unrestricted form. 919 * <p> 920 * There are four allowlists: 921 * <ol> 922 * <li> 923 * One for cases where the system permission policy allowlists a permission. This list 924 * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be 925 * accessed by pre-installed holders of a dedicated permission. 926 * <li> 927 * One for cases where the system allowlists the permission when upgrading from an OS version in 928 * which the permission was not restricted to an OS version in which the permission is 929 * restricted. This list corresponds to the 930 * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by 931 * pre-installed holders of a dedicated permission or the installer on record. 932 * <li> 933 * One for cases where the installer of the package allowlists a permission. This list 934 * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be 935 * accessed by pre-installed holders of a dedicated permission or the installer on record. 936 * </ol> 937 * 938 * @param packageName the app for which to get allowlisted permissions 939 * @param allowlistFlag the flag to determine which allowlist to query. Only one flag can be 940 * passed. 941 * @return the allowlisted permissions that are on any of the allowlists you query for 942 * @throws SecurityException if you try to access a allowlist that you have no access to 943 * 944 * @see #addAllowlistedRestrictedPermission(String, String, int) 945 * @see #removeAllowlistedRestrictedPermission(String, String, int) 946 * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM 947 * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE 948 * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER 949 * 950 * @hide Pending API 951 */ 952 @NonNull 953 @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS, 954 conditional = true) getAllowlistedRestrictedPermissions(@onNull String packageName, @PackageManager.PermissionWhitelistFlags int allowlistFlag)955 public Set<String> getAllowlistedRestrictedPermissions(@NonNull String packageName, 956 @PackageManager.PermissionWhitelistFlags int allowlistFlag) { 957 try { 958 final List<String> allowlist = mPermissionManager.getAllowlistedRestrictedPermissions( 959 packageName, allowlistFlag, mContext.getUserId()); 960 if (allowlist == null) { 961 return Collections.emptySet(); 962 } 963 return new ArraySet<>(allowlist); 964 } catch (RemoteException e) { 965 throw e.rethrowFromSystemServer(); 966 } 967 } 968 969 /** 970 * Adds a allowlisted restricted permission for an app. 971 * <p> 972 * Permissions can be hard restricted which means that the app cannot hold them or soft 973 * restricted where the app can hold the permission but in a weaker form. Whether a permission 974 * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or 975 * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission 976 * declaration. Allowlisting a hard restricted permission allows for the to hold that permission 977 * and allowlisting a soft restricted permission allows the app to hold the permission in its 978 * full, unrestricted form. 979 * <p>There are four allowlists: 980 * <ol> 981 * <li> 982 * One for cases where the system permission policy allowlists a permission. This list 983 * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be 984 * accessed by pre-installed holders of a dedicated permission. 985 * <li> 986 * One for cases where the system allowlists the permission when upgrading from an OS version in 987 * which the permission was not restricted to an OS version in which the permission is 988 * restricted. This list corresponds to the 989 * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by 990 * pre-installed holders of a dedicated permission or the installer on record. 991 * <li> 992 * One for cases where the installer of the package allowlists a permission. This list 993 * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be 994 * accessed by pre-installed holders of a dedicated permission or the installer on record. 995 * </ol> 996 * <p> 997 * You need to specify the allowlists for which to set the allowlisted permissions which will 998 * clear the previous allowlisted permissions and replace them with the provided ones. 999 * 1000 * @param packageName the app for which to get allowlisted permissions 1001 * @param permissionName the allowlisted permission to add 1002 * @param allowlistFlags the allowlists to which to add. Passing multiple flags updates all 1003 * specified allowlists. 1004 * @return whether the permission was added to the allowlist 1005 * @throws SecurityException if you try to modify a allowlist that you have no access to. 1006 * 1007 * @see #getAllowlistedRestrictedPermissions(String, int) 1008 * @see #removeAllowlistedRestrictedPermission(String, String, int) 1009 * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM 1010 * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE 1011 * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER 1012 * 1013 * @hide Pending API 1014 */ 1015 @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS, 1016 conditional = true) addAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionWhitelistFlags int allowlistFlags)1017 public boolean addAllowlistedRestrictedPermission(@NonNull String packageName, 1018 @NonNull String permissionName, 1019 @PackageManager.PermissionWhitelistFlags int allowlistFlags) { 1020 try { 1021 return mPermissionManager.addAllowlistedRestrictedPermission(packageName, 1022 permissionName, allowlistFlags, mContext.getUserId()); 1023 } catch (RemoteException e) { 1024 throw e.rethrowFromSystemServer(); 1025 } 1026 } 1027 1028 /** 1029 * Removes a allowlisted restricted permission for an app. 1030 * <p> 1031 * Permissions can be hard restricted which means that the app cannot hold them or soft 1032 * restricted where the app can hold the permission but in a weaker form. Whether a permission 1033 * is {@link PermissionInfo#FLAG_HARD_RESTRICTED hard restricted} or 1034 * {@link PermissionInfo#FLAG_SOFT_RESTRICTED soft restricted} depends on the permission 1035 * declaration. Allowlisting a hard restricted permission allows for the to hold that permission 1036 * and allowlisting a soft restricted permission allows the app to hold the permission in its 1037 * full, unrestricted form. 1038 * <p>There are four allowlists: 1039 * <ol> 1040 * <li> 1041 * One for cases where the system permission policy allowlists a permission. This list 1042 * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM} flag. Can only be 1043 * accessed by pre-installed holders of a dedicated permission. 1044 * <li> 1045 * One for cases where the system allowlists the permission when upgrading from an OS version in 1046 * which the permission was not restricted to an OS version in which the permission is 1047 * restricted. This list corresponds to the 1048 * {@link PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE} flag. Can be accessed by 1049 * pre-installed holders of a dedicated permission or the installer on record. 1050 * <li> 1051 * One for cases where the installer of the package allowlists a permission. This list 1052 * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be 1053 * accessed by pre-installed holders of a dedicated permission or the installer on record. 1054 * </ol> 1055 * <p> 1056 * You need to specify the allowlists for which to set the allowlisted permissions which will 1057 * clear the previous allowlisted permissions and replace them with the provided ones. 1058 * 1059 * @param packageName the app for which to get allowlisted permissions 1060 * @param permissionName the allowlisted permission to remove 1061 * @param allowlistFlags the allowlists from which to remove. Passing multiple flags updates all 1062 * specified allowlists. 1063 * @return whether the permission was removed from the allowlist 1064 * @throws SecurityException if you try to modify a allowlist that you have no access to. 1065 * 1066 * @see #getAllowlistedRestrictedPermissions(String, int) 1067 * @see #addAllowlistedRestrictedPermission(String, String, int) 1068 * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM 1069 * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE 1070 * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER 1071 * 1072 * @hide Pending API 1073 */ 1074 @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS, 1075 conditional = true) removeAllowlistedRestrictedPermission(@onNull String packageName, @NonNull String permissionName, @PackageManager.PermissionWhitelistFlags int allowlistFlags)1076 public boolean removeAllowlistedRestrictedPermission(@NonNull String packageName, 1077 @NonNull String permissionName, 1078 @PackageManager.PermissionWhitelistFlags int allowlistFlags) { 1079 try { 1080 return mPermissionManager.removeAllowlistedRestrictedPermission(packageName, 1081 permissionName, allowlistFlags, mContext.getUserId()); 1082 } catch (RemoteException e) { 1083 throw e.rethrowFromSystemServer(); 1084 } 1085 } 1086 1087 /** 1088 * Checks whether an application is exempted from having its permissions be automatically 1089 * revoked when the app is unused for an extended period of time. 1090 * <p> 1091 * Only the installer on record that installed the given package, or a holder of 1092 * {@code WHITELIST_AUTO_REVOKE_PERMISSIONS} is allowed to call this. 1093 * 1094 * @param packageName the app for which to set exemption 1095 * @return whether the app is exempted 1096 * @throws SecurityException if you you have no access to this 1097 * 1098 * @see #setAutoRevokeExempted 1099 * 1100 * @hide Pending API 1101 */ 1102 @RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS, 1103 conditional = true) isAutoRevokeExempted(@onNull String packageName)1104 public boolean isAutoRevokeExempted(@NonNull String packageName) { 1105 try { 1106 return mPermissionManager.isAutoRevokeExempted(packageName, mContext.getUserId()); 1107 } catch (RemoteException e) { 1108 throw e.rethrowFromSystemServer(); 1109 } 1110 } 1111 1112 /** 1113 * Marks an application exempted from having its permissions be automatically revoked when the 1114 * app is unused for an extended period of time. 1115 * <p> 1116 * Only the installer on record that installed the given package is allowed to call this. 1117 * <p> 1118 * Packages start in exempted state, and it is the installer's responsibility to un-exempt the 1119 * packages it installs, unless auto-revoking permissions from that package would cause 1120 * breakages beyond having to re-request the permission(s). 1121 * 1122 * @param packageName the app for which to set exemption 1123 * @param exempted whether the app should be exempted 1124 * @return whether any change took effect 1125 * @throws SecurityException if you you have no access to modify this 1126 * 1127 * @see #isAutoRevokeExempted 1128 * 1129 * @hide Pending API 1130 */ 1131 @RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS, 1132 conditional = true) setAutoRevokeExempted(@onNull String packageName, boolean exempted)1133 public boolean setAutoRevokeExempted(@NonNull String packageName, boolean exempted) { 1134 try { 1135 return mPermissionManager.setAutoRevokeExempted(packageName, exempted, 1136 mContext.getUserId()); 1137 } catch (RemoteException e) { 1138 throw e.rethrowFromSystemServer(); 1139 } 1140 } 1141 1142 /** 1143 * Get whether you should show UI with rationale for requesting a permission. You should do this 1144 * only if you do not have the permission and the context in which the permission is requested 1145 * does not clearly communicate to the user what would be the benefit from grating this 1146 * permission. 1147 * 1148 * @param permissionName a permission your app wants to request 1149 * @return whether you can show permission rationale UI 1150 * 1151 * @hide 1152 */ 1153 //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) shouldShowRequestPermissionRationale(@onNull String permissionName)1154 public boolean shouldShowRequestPermissionRationale(@NonNull String permissionName) { 1155 try { 1156 final String packageName = mContext.getPackageName(); 1157 return mPermissionManager.shouldShowRequestPermissionRationale(packageName, 1158 permissionName, mContext.getDeviceId(), mContext.getUserId()); 1159 } catch (RemoteException e) { 1160 throw e.rethrowFromSystemServer(); 1161 } 1162 } 1163 1164 /** 1165 * Add a listener for permission changes for installed packages. 1166 * 1167 * @param listener the listener to add 1168 * 1169 * @hide 1170 */ 1171 //@SystemApi 1172 @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) addOnPermissionsChangeListener( @onNull PackageManager.OnPermissionsChangedListener listener)1173 public void addOnPermissionsChangeListener( 1174 @NonNull PackageManager.OnPermissionsChangedListener listener) { 1175 synchronized (mPermissionListeners) { 1176 if (mPermissionListeners.get(listener) != null) { 1177 return; 1178 } 1179 final OnPermissionsChangeListenerDelegate delegate = 1180 new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper()); 1181 try { 1182 mPermissionManager.addOnPermissionsChangeListener(delegate); 1183 mPermissionListeners.put(listener, delegate); 1184 } catch (RemoteException e) { 1185 throw e.rethrowFromSystemServer(); 1186 } 1187 } 1188 } 1189 1190 /** 1191 * Remove a listener for permission changes for installed packages. 1192 * 1193 * @param listener the listener to remove 1194 * 1195 * @hide 1196 */ 1197 //@SystemApi 1198 @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) removeOnPermissionsChangeListener( @onNull PackageManager.OnPermissionsChangedListener listener)1199 public void removeOnPermissionsChangeListener( 1200 @NonNull PackageManager.OnPermissionsChangedListener listener) { 1201 synchronized (mPermissionListeners) { 1202 final IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener); 1203 if (delegate != null) { 1204 try { 1205 mPermissionManager.removeOnPermissionsChangeListener(delegate); 1206 mPermissionListeners.remove(listener); 1207 } catch (RemoteException e) { 1208 throw e.rethrowFromSystemServer(); 1209 } 1210 } 1211 } 1212 } 1213 1214 /** 1215 * Gets the version of the runtime permission database. 1216 * 1217 * @return The database version, -1 when this is an upgrade from pre-Q, 0 when this is a fresh 1218 * install. 1219 * 1220 * @hide 1221 */ 1222 @SystemApi 1223 @RequiresPermission(anyOf = { 1224 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, 1225 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS 1226 }) getRuntimePermissionsVersion()1227 public @IntRange(from = 0) int getRuntimePermissionsVersion() { 1228 try { 1229 return mPackageManager.getRuntimePermissionsVersion(mContext.getUserId()); 1230 } catch (RemoteException e) { 1231 throw e.rethrowFromSystemServer(); 1232 } 1233 } 1234 1235 /** 1236 * Sets the version of the runtime permission database. 1237 * 1238 * @param version The new version. 1239 * 1240 * @hide 1241 */ 1242 @SystemApi 1243 @RequiresPermission(anyOf = { 1244 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, 1245 Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS 1246 }) setRuntimePermissionsVersion(@ntRangefrom = 0) int version)1247 public void setRuntimePermissionsVersion(@IntRange(from = 0) int version) { 1248 try { 1249 mPackageManager.setRuntimePermissionsVersion(version, mContext.getUserId()); 1250 } catch (RemoteException e) { 1251 throw e.rethrowFromSystemServer(); 1252 } 1253 } 1254 1255 /** 1256 * Get set of permissions that have been split into more granular or dependent permissions. 1257 * 1258 * <p>E.g. before {@link android.os.Build.VERSION_CODES#Q} an app that was granted 1259 * {@link Manifest.permission#ACCESS_COARSE_LOCATION} could access the location while it was in 1260 * foreground and background. On platforms after {@link android.os.Build.VERSION_CODES#Q} 1261 * the location permission only grants location access while the app is in foreground. This 1262 * would break apps that target before {@link android.os.Build.VERSION_CODES#Q}. Hence whenever 1263 * such an old app asks for a location permission (i.e. the 1264 * {@link SplitPermissionInfo#getSplitPermission()}), then the 1265 * {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside 1266 * {@link SplitPermissionInfo#getNewPermissions}) is added. 1267 * 1268 * <p>Note: Regular apps do not have to worry about this. The platform and permission controller 1269 * automatically add the new permissions where needed. 1270 * 1271 * @return All permissions that are split. 1272 */ getSplitPermissions()1273 public @NonNull List<SplitPermissionInfo> getSplitPermissions() { 1274 if (mSplitPermissionInfos != null) { 1275 return mSplitPermissionInfos; 1276 } 1277 1278 List<SplitPermissionInfoParcelable> parcelableList; 1279 try { 1280 parcelableList = ActivityThread.getPermissionManager().getSplitPermissions(); 1281 } catch (RemoteException e) { 1282 Slog.e(LOG_TAG, "Error getting split permissions", e); 1283 return Collections.emptyList(); 1284 } 1285 1286 mSplitPermissionInfos = splitPermissionInfoListToNonParcelableList(parcelableList); 1287 1288 return mSplitPermissionInfos; 1289 } 1290 1291 /** 1292 * Initialize the PermissionUsageHelper, which will register active app op listeners 1293 * 1294 * @hide 1295 */ initializeUsageHelper()1296 public void initializeUsageHelper() { 1297 if (mUsageHelper == null) { 1298 mUsageHelper = new PermissionUsageHelper(mContext); 1299 } 1300 } 1301 1302 /** 1303 * Teardown the PermissionUsageHelper, removing listeners 1304 * 1305 * @hide 1306 */ tearDownUsageHelper()1307 public void tearDownUsageHelper() { 1308 if (mUsageHelper != null) { 1309 mUsageHelper.tearDown(); 1310 mUsageHelper = null; 1311 } 1312 } 1313 1314 /** 1315 * @return A list of permission groups currently or recently used by all apps by all users in 1316 * the current profile group. 1317 * 1318 * @hide 1319 */ 1320 @TestApi 1321 @NonNull 1322 @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS) getIndicatorAppOpUsageData()1323 public List<PermissionGroupUsage> getIndicatorAppOpUsageData() { 1324 return getIndicatorAppOpUsageData(new AudioManager().isMicrophoneMute()); 1325 } 1326 1327 /** 1328 * @param micMuted whether to consider the microphone muted when retrieving audio ops 1329 * @return A list of permission groups currently or recently used by all apps by all users in 1330 * the current profile group. 1331 * 1332 * @hide 1333 */ 1334 @TestApi 1335 @NonNull 1336 @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS) getIndicatorAppOpUsageData(boolean micMuted)1337 public List<PermissionGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) { 1338 // Lazily initialize the usage helper 1339 initializeUsageHelper(); 1340 boolean includeMicrophoneUsage = !micMuted; 1341 return mUsageHelper.getOpUsageDataByDevice(includeMicrophoneUsage, 1342 VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); 1343 } 1344 1345 /** 1346 * Determine if a package should be shown in indicators. Only a select few roles, and the 1347 * system app itself, are hidden. These values are updated at most every 15 seconds. 1348 * @hide 1349 */ shouldShowPackageForIndicatorCached(@onNull Context context, @NonNull String packageName)1350 public static boolean shouldShowPackageForIndicatorCached(@NonNull Context context, 1351 @NonNull String packageName) { 1352 return !getIndicatorExemptedPackages(context).contains(packageName); 1353 } 1354 1355 /** 1356 * Get the list of packages that are not shown by the indicators. Only a select few roles, and 1357 * the system app itself, are hidden. These values are updated at most every 15 seconds. 1358 * @hide 1359 */ getIndicatorExemptedPackages(@onNull Context context)1360 public static Set<String> getIndicatorExemptedPackages(@NonNull Context context) { 1361 updateIndicatorExemptedPackages(context); 1362 ArraySet<String> pkgNames = new ArraySet<>(); 1363 pkgNames.add(SYSTEM_PKG); 1364 for (int i = 0; i < INDICATOR_EXEMPTED_PACKAGES.length; i++) { 1365 String exemptedPackage = INDICATOR_EXEMPTED_PACKAGES[i]; 1366 if (exemptedPackage != null) { 1367 pkgNames.add(exemptedPackage); 1368 } 1369 } 1370 return pkgNames; 1371 } 1372 1373 /** 1374 * Update the cached indicator exempted packages 1375 * @hide 1376 */ updateIndicatorExemptedPackages(@onNull Context context)1377 public static void updateIndicatorExemptedPackages(@NonNull Context context) { 1378 long now = SystemClock.elapsedRealtime(); 1379 if (sLastIndicatorUpdateTime == -1 1380 || (now - sLastIndicatorUpdateTime) > EXEMPTED_INDICATOR_ROLE_UPDATE_FREQUENCY_MS) { 1381 sLastIndicatorUpdateTime = now; 1382 for (int i = 0; i < EXEMPTED_ROLES.length; i++) { 1383 INDICATOR_EXEMPTED_PACKAGES[i] = context.getString(EXEMPTED_ROLES[i]); 1384 } 1385 } 1386 } 1387 /** 1388 * Gets the list of packages that have permissions that specified 1389 * {@code requestDontAutoRevokePermissions=true} in their 1390 * {@code application} manifest declaration. 1391 * 1392 * @return the list of packages for current user 1393 * @hide 1394 */ 1395 @SystemApi 1396 @NonNull 1397 @RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) getAutoRevokeExemptionRequestedPackages()1398 public Set<String> getAutoRevokeExemptionRequestedPackages() { 1399 try { 1400 return CollectionUtils.toSet(mPermissionManager.getAutoRevokeExemptionRequestedPackages( 1401 mContext.getUser().getIdentifier())); 1402 } catch (RemoteException e) { 1403 throw e.rethrowFromSystemServer(); 1404 } 1405 } 1406 1407 /** 1408 * Gets the list of packages that have permissions that specified 1409 * {@code autoRevokePermissions=disallowed} in their 1410 * {@code application} manifest declaration. 1411 * 1412 * @return the list of packages for current user 1413 * @hide 1414 */ 1415 @SystemApi 1416 @NonNull 1417 @RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) getAutoRevokeExemptionGrantedPackages()1418 public Set<String> getAutoRevokeExemptionGrantedPackages() { 1419 try { 1420 return CollectionUtils.toSet(mPermissionManager.getAutoRevokeExemptionGrantedPackages( 1421 mContext.getUser().getIdentifier())); 1422 } catch (RemoteException e) { 1423 throw e.rethrowFromSystemServer(); 1424 } 1425 } 1426 splitPermissionInfoListToNonParcelableList( List<SplitPermissionInfoParcelable> parcelableList)1427 private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList( 1428 List<SplitPermissionInfoParcelable> parcelableList) { 1429 final int size = parcelableList.size(); 1430 List<SplitPermissionInfo> list = new ArrayList<>(size); 1431 for (int i = 0; i < size; i++) { 1432 list.add(new SplitPermissionInfo(parcelableList.get(i))); 1433 } 1434 return list; 1435 } 1436 1437 /** 1438 * Converts a {@link List} of {@link SplitPermissionInfo} into a List of 1439 * {@link SplitPermissionInfoParcelable} and returns it. 1440 * @hide 1441 */ splitPermissionInfoListToParcelableList( List<SplitPermissionInfo> splitPermissionsList)1442 public static List<SplitPermissionInfoParcelable> splitPermissionInfoListToParcelableList( 1443 List<SplitPermissionInfo> splitPermissionsList) { 1444 final int size = splitPermissionsList.size(); 1445 List<SplitPermissionInfoParcelable> outList = new ArrayList<>(size); 1446 for (int i = 0; i < size; i++) { 1447 SplitPermissionInfo info = splitPermissionsList.get(i); 1448 outList.add(new SplitPermissionInfoParcelable( 1449 info.getSplitPermission(), info.getNewPermissions(), info.getTargetSdk())); 1450 } 1451 return outList; 1452 } 1453 1454 /** 1455 * A permission that was added in a previous API level might have split into several 1456 * permissions. This object describes one such split. 1457 */ 1458 @Immutable 1459 public static final class SplitPermissionInfo { 1460 private @NonNull final SplitPermissionInfoParcelable mSplitPermissionInfoParcelable; 1461 1462 @Override equals(@ullable Object o)1463 public boolean equals(@Nullable Object o) { 1464 if (this == o) return true; 1465 if (o == null || getClass() != o.getClass()) return false; 1466 SplitPermissionInfo that = (SplitPermissionInfo) o; 1467 return mSplitPermissionInfoParcelable.equals(that.mSplitPermissionInfoParcelable); 1468 } 1469 1470 @Override hashCode()1471 public int hashCode() { 1472 return mSplitPermissionInfoParcelable.hashCode(); 1473 } 1474 1475 /** 1476 * Get the permission that is split. 1477 */ getSplitPermission()1478 public @NonNull String getSplitPermission() { 1479 return mSplitPermissionInfoParcelable.getSplitPermission(); 1480 } 1481 1482 /** 1483 * Get the permissions that are added. 1484 */ getNewPermissions()1485 public @NonNull List<String> getNewPermissions() { 1486 return mSplitPermissionInfoParcelable.getNewPermissions(); 1487 } 1488 1489 /** 1490 * Get the target API level when the permission was split. 1491 */ getTargetSdk()1492 public int getTargetSdk() { 1493 return mSplitPermissionInfoParcelable.getTargetSdk(); 1494 } 1495 1496 /** 1497 * Constructs a split permission. 1498 * 1499 * @param splitPerm old permission that will be split 1500 * @param newPerms list of new permissions that {@code rootPerm} will be split into 1501 * @param targetSdk apps targetting SDK versions below this will have {@code rootPerm} 1502 * split into {@code newPerms} 1503 * @hide 1504 */ SplitPermissionInfo(@onNull String splitPerm, @NonNull List<String> newPerms, int targetSdk)1505 public SplitPermissionInfo(@NonNull String splitPerm, @NonNull List<String> newPerms, 1506 int targetSdk) { 1507 this(new SplitPermissionInfoParcelable(splitPerm, newPerms, targetSdk)); 1508 } 1509 SplitPermissionInfo(@onNull SplitPermissionInfoParcelable parcelable)1510 private SplitPermissionInfo(@NonNull SplitPermissionInfoParcelable parcelable) { 1511 mSplitPermissionInfoParcelable = parcelable; 1512 } 1513 } 1514 1515 /** 1516 * Starts a one-time permission session for a given package. 1517 * @see #startOneTimePermissionSession(String, long, long, int, int) 1518 * @hide 1519 * @deprecated Use {@link #startOneTimePermissionSession(String, long, long, int, int)} instead 1520 */ 1521 @Deprecated 1522 @SystemApi 1523 @RequiresPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) startOneTimePermissionSession(@onNull String packageName, long timeoutMillis, @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive)1524 public void startOneTimePermissionSession(@NonNull String packageName, long timeoutMillis, 1525 @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, 1526 @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) { 1527 startOneTimePermissionSession(packageName, timeoutMillis, -1, 1528 importanceToResetTimer, importanceToKeepSessionAlive); 1529 } 1530 1531 /** 1532 * Starts a one-time permission session for a given package. A one-time permission session is 1533 * ended if app becomes inactive. Inactivity is defined as the package's uid importance level 1534 * staying > importanceToResetTimer for timeoutMillis milliseconds. If the package's uid 1535 * importance level goes <= importanceToResetTimer then the timer is reset and doesn't start 1536 * until going > importanceToResetTimer. 1537 * <p> 1538 * When this timeoutMillis is reached if the importance level is <= importanceToKeepSessionAlive 1539 * then the session is extended until either the importance goes above 1540 * importanceToKeepSessionAlive which will end the session or <= importanceToResetTimer which 1541 * will continue the session and reset the timer. 1542 * </p> 1543 * <p> 1544 * Importance levels are defined in {@link android.app.ActivityManager.RunningAppProcessInfo}. 1545 * </p> 1546 * <p> 1547 * Once the session ends 1548 * {@link PermissionControllerService#onOneTimePermissionSessionTimeout(String)} is invoked. 1549 * </p> 1550 * <p> 1551 * Note that if there is currently an active session for a package a new one isn't created but 1552 * each parameter of the existing one will be updated to the more aggressive of both sessions. 1553 * This means that durations will be set to the shortest parameter and importances will be set 1554 * to the lowest one. 1555 * </p> 1556 * @param packageName The package to start a one-time permission session for 1557 * @param timeoutMillis Number of milliseconds for an app to be in an inactive state 1558 * @param revokeAfterKilledDelayMillis Number of milliseconds to wait before revoking on the 1559 * event an app is terminated. Set to -1 to use default 1560 * value for the device. 1561 * @param importanceToResetTimer The least important level to uid must be to reset the timer 1562 * @param importanceToKeepSessionAlive The least important level the uid must be to keep the 1563 * session alive 1564 * 1565 * @hide 1566 */ 1567 @SystemApi 1568 @RequiresPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) startOneTimePermissionSession(@onNull String packageName, @DurationMillisLong long timeoutMillis, @DurationMillisLong long revokeAfterKilledDelayMillis, @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive)1569 public void startOneTimePermissionSession(@NonNull String packageName, 1570 @DurationMillisLong long timeoutMillis, 1571 @DurationMillisLong long revokeAfterKilledDelayMillis, 1572 @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, 1573 @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) { 1574 try { 1575 mPermissionManager.startOneTimePermissionSession(packageName, mContext.getDeviceId(), 1576 mContext.getUserId(), timeoutMillis, revokeAfterKilledDelayMillis); 1577 } catch (RemoteException e) { 1578 e.rethrowFromSystemServer(); 1579 } 1580 } 1581 1582 /** 1583 * Stops the one-time permission session for the package. The callback to the end of session is 1584 * not invoked. If there is no one-time session for the package then nothing happens. 1585 * 1586 * @param packageName Package to stop the one-time permission session for 1587 * 1588 * @hide 1589 */ 1590 @SystemApi 1591 @RequiresPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) stopOneTimePermissionSession(@onNull String packageName)1592 public void stopOneTimePermissionSession(@NonNull String packageName) { 1593 try { 1594 mPermissionManager.stopOneTimePermissionSession(packageName, 1595 mContext.getUserId()); 1596 } catch (RemoteException e) { 1597 e.rethrowFromSystemServer(); 1598 } 1599 } 1600 1601 /** 1602 * Checks whether the package with the given pid/uid can read device identifiers. 1603 * 1604 * @param packageName the name of the package to be checked for identifier access 1605 * @param message the message to be used for logging during identifier access 1606 * verification 1607 * @param callingFeatureId the feature in the package 1608 * @param pid the process id of the package to be checked 1609 * @param uid the uid of the package to be checked 1610 * @return {@link PackageManager#PERMISSION_GRANTED} if the package is allowed identifier 1611 * access, {@link PackageManager#PERMISSION_DENIED} otherwise 1612 * @hide 1613 */ 1614 @SystemApi checkDeviceIdentifierAccess(@ullable String packageName, @Nullable String message, @Nullable String callingFeatureId, int pid, int uid)1615 public int checkDeviceIdentifierAccess(@Nullable String packageName, @Nullable String message, 1616 @Nullable String callingFeatureId, int pid, int uid) { 1617 return mLegacyPermissionManager.checkDeviceIdentifierAccess(packageName, message, 1618 callingFeatureId, pid, uid); 1619 } 1620 1621 /** 1622 * Registers an attribution source with the OS. An app can only register an attribution 1623 * source for itself. Once an attribution source has been registered another app can 1624 * check whether this registration exists and thus trust the payload in the source 1625 * object. This is important for permission checking and specifically for app op blaming 1626 * since a malicious app should not be able to force the OS to blame another app 1627 * that doesn't participate in an attribution chain. 1628 * 1629 * @param source The attribution source to register. 1630 * @return The registered new attribution source. 1631 * 1632 * @see #isRegisteredAttributionSource(AttributionSource) 1633 * 1634 * @hide 1635 */ 1636 @TestApi registerAttributionSource(@onNull AttributionSource source)1637 public @NonNull AttributionSource registerAttributionSource(@NonNull AttributionSource source) { 1638 // We use a shared static token for sources that are not registered since the token's 1639 // only used for process death detection. If we are about to use the source for security 1640 // enforcement we need to replace the binder with a unique one. 1641 try { 1642 if (serverSideAttributionRegistration()) { 1643 IBinder newToken = mPermissionManager.registerAttributionSource(source.asState()); 1644 return source.withToken(newToken); 1645 } else { 1646 AttributionSource registeredSource = source.withToken(new Binder()); 1647 mPermissionManager.registerAttributionSource(registeredSource.asState()); 1648 return registeredSource; 1649 } 1650 } catch (RemoteException e) { 1651 e.rethrowFromSystemServer(); 1652 } 1653 return source; 1654 } 1655 1656 /** 1657 * Checks whether an attribution source is registered. 1658 * 1659 * @param source The attribution source to check. 1660 * @return Whether this is a registered source. 1661 * 1662 * @see #registerAttributionSource(AttributionSource) 1663 * 1664 * @hide 1665 */ 1666 @TestApi 1667 @FlaggedApi(FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE) isRegisteredAttributionSource(@onNull AttributionSource source)1668 public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) { 1669 try { 1670 return mPermissionManager.isRegisteredAttributionSource(source.asState()); 1671 } catch (RemoteException e) { 1672 e.rethrowFromSystemServer(); 1673 } 1674 return false; 1675 } 1676 1677 /** 1678 * Gets the number of currently registered attribution sources for a particular UID. This should 1679 * only be used for testing purposes. 1680 * @hide 1681 */ 1682 @RequiresPermission(Manifest.permission.UPDATE_APP_OPS_STATS) getRegisteredAttributionSourceCountForTest(int uid)1683 public int getRegisteredAttributionSourceCountForTest(int uid) { 1684 try { 1685 return mPermissionManager.getRegisteredAttributionSourceCount(uid); 1686 } catch (RemoteException e) { 1687 e.rethrowFromSystemServer(); 1688 } 1689 return -1; 1690 } 1691 1692 /** 1693 * Revoke the POST_NOTIFICATIONS permission, without killing the app. This method must ONLY BE 1694 * USED in CTS or local tests. 1695 * 1696 * @param packageName The package to be revoked 1697 * @param userId The user for which to revoke 1698 * 1699 * @hide 1700 */ 1701 @TestApi 1702 @RequiresPermission(Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL) revokePostNotificationPermissionWithoutKillForTest(@onNull String packageName, int userId)1703 public void revokePostNotificationPermissionWithoutKillForTest(@NonNull String packageName, 1704 int userId) { 1705 try { 1706 mPermissionManager.revokePostNotificationPermissionWithoutKillForTest(packageName, 1707 userId); 1708 } catch (RemoteException e) { 1709 e.rethrowFromSystemServer(); 1710 } 1711 } 1712 1713 // Only warn once for assuming that root or system UID has a permission 1714 // to reduce duplicate logcat output. 1715 private static volatile boolean sShouldWarnMissingActivityManager = true; 1716 checkPermissionUncached(@ullable String permission, int pid, int uid, int deviceId)1717 private static int checkPermissionUncached(@Nullable String permission, int pid, int uid, 1718 int deviceId) { 1719 final IActivityManager am = ActivityManager.getService(); 1720 if (am == null) { 1721 // Well this is super awkward; we somehow don't have an active ActivityManager 1722 // instance. If we're testing a root or system UID, then they totally have whatever 1723 // permission this is. 1724 final int appId = UserHandle.getAppId(uid); 1725 if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) { 1726 if (sShouldWarnMissingActivityManager) { 1727 Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " holds " 1728 + permission); 1729 sShouldWarnMissingActivityManager = false; 1730 } 1731 return PackageManager.PERMISSION_GRANTED; 1732 } 1733 Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " does not hold " 1734 + permission); 1735 return PackageManager.PERMISSION_DENIED; 1736 } 1737 try { 1738 sShouldWarnMissingActivityManager = true; 1739 return am.checkPermissionForDevice(permission, pid, uid, deviceId); 1740 } catch (RemoteException e) { 1741 throw e.rethrowFromSystemServer(); 1742 } 1743 } 1744 1745 /** 1746 * Identifies a permission query. 1747 * 1748 * N.B. we include the checking pid for tracking purposes but don't include it in the equality 1749 * comparison: we use only uid for the actual security check, so comparing pid would result 1750 * in spurious misses. 1751 * 1752 * @hide 1753 */ 1754 @Immutable 1755 private static final class PermissionQuery { 1756 final String permission; 1757 final int pid; 1758 final int uid; 1759 final int deviceId; 1760 PermissionQuery(@ullable String permission, int pid, int uid, int deviceId)1761 PermissionQuery(@Nullable String permission, int pid, int uid, int deviceId) { 1762 this.permission = permission; 1763 this.pid = pid; 1764 this.uid = uid; 1765 this.deviceId = deviceId; 1766 } 1767 1768 @Override toString()1769 public String toString() { 1770 return TextUtils.formatSimple("PermissionQuery(permission=\"%s\", pid=%d, uid=%d, " 1771 + "deviceId=%d)", permission, pid, uid, deviceId); 1772 } 1773 1774 @Override hashCode()1775 public int hashCode() { 1776 // N.B. pid doesn't count toward equality and therefore shouldn't count for 1777 // hashing either. 1778 return Objects.hash(permission, uid, deviceId); 1779 } 1780 1781 @Override equals(@ullable Object rval)1782 public boolean equals(@Nullable Object rval) { 1783 // N.B. pid doesn't count toward equality! 1784 if (rval == null) { 1785 return false; 1786 } 1787 PermissionQuery other; 1788 try { 1789 other = (PermissionQuery) rval; 1790 } catch (ClassCastException ex) { 1791 return false; 1792 } 1793 return uid == other.uid && deviceId == other.deviceId 1794 && Objects.equals(permission, other.permission); 1795 } 1796 } 1797 1798 /** @hide */ 1799 public static final String CACHE_KEY_PACKAGE_INFO = "cache_key.package_info"; 1800 1801 /** @hide */ 1802 private static final PropertyInvalidatedCache<PermissionQuery, Integer> sPermissionCache = 1803 new PropertyInvalidatedCache<PermissionQuery, Integer>( 1804 2048, CACHE_KEY_PACKAGE_INFO, "checkPermission") { 1805 @Override 1806 public Integer recompute(PermissionQuery query) { 1807 return checkPermissionUncached(query.permission, query.pid, query.uid, 1808 query.deviceId); 1809 } 1810 }; 1811 1812 /** @hide */ checkPermission(@ullable String permission, int pid, int uid, int deviceId)1813 public static int checkPermission(@Nullable String permission, int pid, int uid, int deviceId) { 1814 return sPermissionCache.query(new PermissionQuery(permission, pid, uid, deviceId)); 1815 } 1816 1817 /** 1818 * Gets the permission states for requested package and persistent device. 1819 * <p> 1820 * <strong>Note: </strong>Default device permissions are not inherited in this API. Returns the 1821 * exact permission states for the requested device. 1822 * 1823 * @param packageName name of the package you are checking against 1824 * @param persistentDeviceId id of the persistent device you are checking against 1825 * @return mapping of all permission states keyed by their permission names 1826 * 1827 * @hide 1828 */ 1829 @SystemApi 1830 @NonNull 1831 @RequiresPermission(anyOf = { 1832 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 1833 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 1834 android.Manifest.permission.GET_RUNTIME_PERMISSIONS 1835 }) 1836 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) getAllPermissionStates(@onNull String packageName, @NonNull String persistentDeviceId)1837 public Map<String, PermissionState> getAllPermissionStates(@NonNull String packageName, 1838 @NonNull String persistentDeviceId) { 1839 try { 1840 return mPermissionManager.getAllPermissionStates(packageName, persistentDeviceId, 1841 mContext.getUserId()); 1842 } catch (RemoteException e) { 1843 throw e.rethrowFromSystemServer(); 1844 } 1845 } 1846 1847 /** 1848 * Make checkPermission() above bypass the permission cache in this process. 1849 * 1850 * @hide 1851 */ disablePermissionCache()1852 public static void disablePermissionCache() { 1853 sPermissionCache.disableLocal(); 1854 } 1855 1856 /** 1857 * Like PermissionQuery, but for permission checks based on a package name instead of 1858 * a UID. 1859 */ 1860 @Immutable 1861 private static final class PackageNamePermissionQuery { 1862 final String permName; 1863 final String pkgName; 1864 final String persistentDeviceId; 1865 @UserIdInt 1866 final int userId; 1867 PackageNamePermissionQuery(@ullable String permName, @Nullable String pkgName, @Nullable String persistentDeviceId, @UserIdInt int userId)1868 PackageNamePermissionQuery(@Nullable String permName, @Nullable String pkgName, 1869 @Nullable String persistentDeviceId, @UserIdInt int userId) { 1870 this.permName = permName; 1871 this.pkgName = pkgName; 1872 this.persistentDeviceId = persistentDeviceId; 1873 this.userId = userId; 1874 } 1875 1876 @Override toString()1877 public String toString() { 1878 return TextUtils.formatSimple( 1879 "PackageNamePermissionQuery(pkgName=\"%s\", permName=\"%s\", " 1880 + "persistentDeviceId=%s, userId=%s\")", 1881 pkgName, permName, persistentDeviceId, userId); 1882 } 1883 1884 @Override hashCode()1885 public int hashCode() { 1886 return Objects.hash(permName, pkgName, persistentDeviceId, userId); 1887 } 1888 1889 @Override equals(@ullable Object rval)1890 public boolean equals(@Nullable Object rval) { 1891 if (rval == null) { 1892 return false; 1893 } 1894 PackageNamePermissionQuery other; 1895 try { 1896 other = (PackageNamePermissionQuery) rval; 1897 } catch (ClassCastException ex) { 1898 return false; 1899 } 1900 return Objects.equals(permName, other.permName) 1901 && Objects.equals(pkgName, other.pkgName) 1902 && Objects.equals(persistentDeviceId, other.persistentDeviceId) 1903 && userId == other.userId; 1904 } 1905 } 1906 1907 /* @hide */ checkPackageNamePermissionUncached( String permName, String pkgName, String persistentDeviceId, @UserIdInt int userId)1908 private static int checkPackageNamePermissionUncached( 1909 String permName, String pkgName, String persistentDeviceId, @UserIdInt int userId) { 1910 try { 1911 return ActivityThread.getPermissionManager().checkPermission( 1912 pkgName, permName, persistentDeviceId, userId); 1913 } catch (RemoteException e) { 1914 throw e.rethrowFromSystemServer(); 1915 } 1916 } 1917 1918 /* @hide */ 1919 private static PropertyInvalidatedCache<PackageNamePermissionQuery, Integer> 1920 sPackageNamePermissionCache = 1921 new PropertyInvalidatedCache<PackageNamePermissionQuery, Integer>( 1922 16, CACHE_KEY_PACKAGE_INFO, "checkPackageNamePermission") { 1923 @Override 1924 public Integer recompute(PackageNamePermissionQuery query) { 1925 return checkPackageNamePermissionUncached( 1926 query.permName, query.pkgName, query.persistentDeviceId, query.userId); 1927 } 1928 @Override 1929 public boolean bypass(PackageNamePermissionQuery query) { 1930 return query.userId < 0; 1931 } 1932 }; 1933 1934 /** 1935 * Check whether a package has a permission for given device. 1936 * 1937 * @hide 1938 */ checkPackageNamePermission(String permName, String pkgName, int deviceId, @UserIdInt int userId)1939 public int checkPackageNamePermission(String permName, String pkgName, 1940 int deviceId, @UserIdInt int userId) { 1941 String persistentDeviceId = getPersistentDeviceId(deviceId); 1942 return sPackageNamePermissionCache.query( 1943 new PackageNamePermissionQuery(permName, pkgName, persistentDeviceId, userId)); 1944 } 1945 1946 @Nullable getPersistentDeviceId(int deviceId)1947 private String getPersistentDeviceId(int deviceId) { 1948 String persistentDeviceId = null; 1949 1950 if (deviceId == Context.DEVICE_ID_DEFAULT) { 1951 persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT; 1952 } else if (android.companion.virtual.flags.Flags.vdmPublicApis()) { 1953 VirtualDeviceManager virtualDeviceManager = mContext.getSystemService( 1954 VirtualDeviceManager.class); 1955 if (virtualDeviceManager != null) { 1956 VirtualDevice virtualDevice = virtualDeviceManager.getVirtualDevice(deviceId); 1957 if (virtualDevice == null) { 1958 Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId); 1959 return null; 1960 } 1961 persistentDeviceId = virtualDevice.getPersistentDeviceId(); 1962 if (persistentDeviceId == null) { 1963 Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId); 1964 } 1965 } 1966 } else { 1967 Slog.e(LOG_TAG, "vdmPublicApis flag is not enabled when device Id " + deviceId 1968 + "is not default."); 1969 } 1970 return persistentDeviceId; 1971 } 1972 1973 /** 1974 * Check whether a package has been granted a permission on a given device. 1975 * <p> 1976 * <strong>Note: </strong>This API returns the underlying permission state 1977 * as-is and is mostly intended for permission managing system apps. To 1978 * perform an access check for a certain app, please use the 1979 * {@link Context#checkPermission} APIs instead. 1980 * 1981 * @param permissionName The name of the permission you are checking for. 1982 * @param packageName The name of the package you are checking against. 1983 * @param persistentDeviceId The id of the physical device that you are checking permission 1984 * against. 1985 * 1986 * @return If the package has the permission on the device, PERMISSION_GRANTED is 1987 * returned. If it does not have the permission on the device, PERMISSION_DENIED 1988 * is returned. 1989 * 1990 * @see VirtualDevice#getPersistentDeviceId() 1991 * @see PackageManager#PERMISSION_GRANTED 1992 * @see PackageManager#PERMISSION_DENIED 1993 * 1994 * @hide 1995 */ 1996 @SystemApi 1997 @PermissionResult 1998 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) checkPermission(@onNull String permissionName, @NonNull String packageName, @NonNull String persistentDeviceId)1999 public int checkPermission(@NonNull String permissionName, @NonNull String packageName, 2000 @NonNull String persistentDeviceId) { 2001 return sPackageNamePermissionCache.query( 2002 new PackageNamePermissionQuery(permissionName, packageName, persistentDeviceId, 2003 mContext.getUserId())); 2004 } 2005 2006 /** 2007 * Make checkPackageNamePermission() bypass the cache in this process. 2008 * 2009 * @hide 2010 */ disablePackageNamePermissionCache()2011 public static void disablePackageNamePermissionCache() { 2012 sPackageNamePermissionCache.disableLocal(); 2013 } 2014 2015 private final class OnPermissionsChangeListenerDelegate 2016 extends IOnPermissionsChangeListener.Stub implements Handler.Callback { 2017 private static final int MSG_PERMISSIONS_CHANGED = 1; 2018 2019 private final PackageManager.OnPermissionsChangedListener mListener; 2020 private final Handler mHandler; 2021 OnPermissionsChangeListenerDelegate( PackageManager.OnPermissionsChangedListener listener, Looper looper)2022 public OnPermissionsChangeListenerDelegate( 2023 PackageManager.OnPermissionsChangedListener listener, Looper looper) { 2024 mListener = listener; 2025 mHandler = new Handler(looper, this); 2026 } 2027 2028 @Override onPermissionsChanged(int uid, String persistentDeviceId)2029 public void onPermissionsChanged(int uid, String persistentDeviceId) { 2030 mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0, persistentDeviceId) 2031 .sendToTarget(); 2032 } 2033 2034 @Override handleMessage(Message msg)2035 public boolean handleMessage(Message msg) { 2036 switch (msg.what) { 2037 case MSG_PERMISSIONS_CHANGED: { 2038 final int uid = msg.arg1; 2039 final String persistentDeviceId = msg.obj.toString(); 2040 mListener.onPermissionsChanged(uid, persistentDeviceId); 2041 return true; 2042 } 2043 default: 2044 return false; 2045 } 2046 } 2047 } 2048 2049 /** 2050 * Data class for the state of a permission requested by a package 2051 * 2052 * @hide 2053 */ 2054 @SystemApi 2055 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) 2056 public static final class PermissionState implements Parcelable { 2057 private final boolean mGranted; 2058 private final int mFlags; 2059 2060 /** @hide */ 2061 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) PermissionState(boolean granted, int flags)2062 public PermissionState(boolean granted, int flags) { 2063 mGranted = granted; 2064 mFlags = flags; 2065 } 2066 2067 /** 2068 * Returns whether this permission is granted 2069 */ 2070 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) isGranted()2071 public boolean isGranted() { 2072 return mGranted; 2073 } 2074 2075 /** 2076 * Returns the flags associated with this permission state 2077 * @see PackageManager#getPermissionFlags 2078 */ 2079 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) getFlags()2080 public int getFlags() { 2081 return mFlags; 2082 } 2083 2084 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) 2085 @Override describeContents()2086 public int describeContents() { 2087 return 0; 2088 } 2089 2090 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) 2091 @Override writeToParcel(@onNull Parcel parcel, int flags)2092 public void writeToParcel(@NonNull Parcel parcel, int flags) { 2093 parcel.writeBoolean(mGranted); 2094 parcel.writeInt(mFlags); 2095 } 2096 PermissionState(Parcel parcel)2097 private PermissionState(Parcel parcel) { 2098 this(parcel.readBoolean(), parcel.readInt()); 2099 } 2100 2101 @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) 2102 public static final @NonNull Creator<PermissionState> CREATOR = new Creator<>() { 2103 public PermissionState createFromParcel(Parcel source) { 2104 return new PermissionState(source); 2105 } 2106 2107 public PermissionState[] newArray(int size) { 2108 return new PermissionState[size]; 2109 } 2110 }; 2111 2112 /** @hide */ 2113 @Override equals(Object o)2114 public boolean equals(Object o) { 2115 if (this == o) return true; 2116 if (o == null || getClass() != o.getClass()) return false; 2117 PermissionState that = (PermissionState) o; 2118 return mGranted == that.mGranted && mFlags == that.mFlags; 2119 } 2120 2121 /** @hide */ 2122 @Override hashCode()2123 public int hashCode() { 2124 return Objects.hash(mGranted, mFlags); 2125 } 2126 2127 /** @hide */ 2128 @Override toString()2129 public String toString() { 2130 return "PermissionState{" 2131 + "mGranted=" + mGranted 2132 + ", mFlags=" + mFlags 2133 + '}'; 2134 } 2135 } 2136 } 2137