1 /* 2 * Copyright (C) 2008 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.content.pm; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.StringRes; 23 import android.annotation.SuppressLint; 24 import android.annotation.SystemApi; 25 import android.compat.annotation.UnsupportedAppUsage; 26 import android.os.Build; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 import android.text.TextUtils; 30 31 import com.android.internal.util.Parcelling; 32 import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; 33 34 import java.lang.annotation.Retention; 35 import java.lang.annotation.RetentionPolicy; 36 import java.util.Collections; 37 import java.util.Set; 38 39 /** 40 * Information you can retrieve about a particular security permission 41 * known to the system. This corresponds to information collected from the 42 * AndroidManifest.xml's <permission> tags. 43 */ 44 public class PermissionInfo extends PackageItemInfo implements Parcelable { 45 /** 46 * A normal application value for {@link #protectionLevel}, corresponding 47 * to the <code>normal</code> value of 48 * {@link android.R.attr#protectionLevel}. 49 */ 50 public static final int PROTECTION_NORMAL = 0; 51 52 /** 53 * Dangerous value for {@link #protectionLevel}, corresponding 54 * to the <code>dangerous</code> value of 55 * {@link android.R.attr#protectionLevel}. 56 */ 57 public static final int PROTECTION_DANGEROUS = 1; 58 59 /** 60 * System-level value for {@link #protectionLevel}, corresponding 61 * to the <code>signature</code> value of 62 * {@link android.R.attr#protectionLevel}. 63 */ 64 public static final int PROTECTION_SIGNATURE = 2; 65 66 /** 67 * @deprecated Use {@link #PROTECTION_SIGNATURE}|{@link #PROTECTION_FLAG_PRIVILEGED} 68 * instead. 69 */ 70 @Deprecated 71 public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; 72 73 /** 74 * System-level value for {@link #protectionLevel}, corresponding 75 * to the <code>internal</code> value of 76 * {@link android.R.attr#protectionLevel}. 77 */ 78 public static final int PROTECTION_INTERNAL = 4; 79 80 /** @hide */ 81 @IntDef(flag = false, prefix = { "PROTECTION_" }, value = { 82 PROTECTION_NORMAL, 83 PROTECTION_DANGEROUS, 84 PROTECTION_SIGNATURE, 85 PROTECTION_SIGNATURE_OR_SYSTEM, 86 PROTECTION_INTERNAL, 87 }) 88 @Retention(RetentionPolicy.SOURCE) 89 public @interface Protection {} 90 91 /** 92 * Additional flag for {@link #protectionLevel}, corresponding 93 * to the <code>privileged</code> value of 94 * {@link android.R.attr#protectionLevel}. 95 */ 96 public static final int PROTECTION_FLAG_PRIVILEGED = 0x10; 97 98 /** 99 * @deprecated Old name for {@link #PROTECTION_FLAG_PRIVILEGED}, which 100 * is now very confusing because it only applies to privileged apps, not all 101 * apps on the system image. 102 */ 103 @Deprecated 104 public static final int PROTECTION_FLAG_SYSTEM = 0x10; 105 106 /** 107 * Additional flag for {@link #protectionLevel}, corresponding 108 * to the <code>development</code> value of 109 * {@link android.R.attr#protectionLevel}. 110 */ 111 public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20; 112 113 /** 114 * Additional flag for {@link #protectionLevel}, corresponding 115 * to the <code>appop</code> value of 116 * {@link android.R.attr#protectionLevel}. 117 */ 118 public static final int PROTECTION_FLAG_APPOP = 0x40; 119 120 /** 121 * Additional flag for {@link #protectionLevel}, corresponding 122 * to the <code>pre23</code> value of 123 * {@link android.R.attr#protectionLevel}. 124 */ 125 public static final int PROTECTION_FLAG_PRE23 = 0x80; 126 127 /** 128 * Additional flag for {@link #protectionLevel}, corresponding 129 * to the <code>installer</code> value of 130 * {@link android.R.attr#protectionLevel}. 131 */ 132 public static final int PROTECTION_FLAG_INSTALLER = 0x100; 133 134 /** 135 * Additional flag for {@link #protectionLevel}, corresponding 136 * to the <code>verifier</code> value of 137 * {@link android.R.attr#protectionLevel}. 138 */ 139 public static final int PROTECTION_FLAG_VERIFIER = 0x200; 140 141 /** 142 * Additional flag for {@link #protectionLevel}, corresponding 143 * to the <code>preinstalled</code> value of 144 * {@link android.R.attr#protectionLevel}. 145 */ 146 public static final int PROTECTION_FLAG_PREINSTALLED = 0x400; 147 148 /** 149 * Additional flag for {@link #protectionLevel}, corresponding 150 * to the <code>setup</code> value of 151 * {@link android.R.attr#protectionLevel}. 152 */ 153 public static final int PROTECTION_FLAG_SETUP = 0x800; 154 155 /** 156 * Additional flag for {@link #protectionLevel}, corresponding 157 * to the <code>instant</code> value of 158 * {@link android.R.attr#protectionLevel}. 159 */ 160 public static final int PROTECTION_FLAG_INSTANT = 0x1000; 161 162 /** 163 * Additional flag for {@link #protectionLevel}, corresponding 164 * to the <code>runtime</code> value of 165 * {@link android.R.attr#protectionLevel}. 166 */ 167 public static final int PROTECTION_FLAG_RUNTIME_ONLY = 0x2000; 168 169 /** 170 * Additional flag for {@link #protectionLevel}, corresponding 171 * to the <code>oem</code> value of 172 * {@link android.R.attr#protectionLevel}. 173 * 174 * @hide 175 */ 176 @SystemApi 177 public static final int PROTECTION_FLAG_OEM = 0x4000; 178 179 /** 180 * Additional flag for {${link #protectionLevel}, corresponding 181 * to the <code>vendorPrivileged</code> value of 182 * {@link android.R.attr#protectionLevel}. 183 * 184 * @hide 185 */ 186 @SystemApi 187 public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000; 188 189 /** 190 * Additional flag for {@link #protectionLevel}, corresponding 191 * to the <code>text_classifier</code> value of 192 * {@link android.R.attr#protectionLevel}. 193 * 194 * @hide 195 */ 196 @SystemApi 197 public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 0x10000; 198 199 /** 200 * Additional flag for {${link #protectionLevel}, corresponding 201 * to the <code>wellbeing</code> value of 202 * {@link android.R.attr#protectionLevel}. 203 * 204 * @deprecated this protectionLevel is obsolete. Permissions previously granted through this 205 * protectionLevel have been migrated to use <code>role</code> instead 206 * @hide 207 */ 208 @SystemApi 209 public static final int PROTECTION_FLAG_WELLBEING = 0x20000; 210 211 /** 212 * Additional flag for {@link #protectionLevel}, corresponding to the 213 * {@code documenter} value of {@link android.R.attr#protectionLevel}. 214 * 215 * @deprecated this protectionLevel is obsolete. Permissions previously granted 216 * through this protectionLevel have been migrated to use <code>role</code> instead 217 * @hide 218 */ 219 @SystemApi 220 public static final int PROTECTION_FLAG_DOCUMENTER = 0x40000; 221 222 /** 223 * Additional flag for {@link #protectionLevel}, corresponding to the 224 * {@code configurator} value of {@link android.R.attr#protectionLevel}. 225 * 226 * @hide 227 */ 228 @SystemApi 229 public static final int PROTECTION_FLAG_CONFIGURATOR = 0x80000; 230 231 /** 232 * Additional flag for {${link #protectionLevel}, corresponding 233 * to the <code>incident_report_approver</code> value of 234 * {@link android.R.attr#protectionLevel}. 235 * 236 * @hide 237 */ 238 @SystemApi 239 public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 0x100000; 240 241 /** 242 * Additional flag for {@link #protectionLevel}, corresponding 243 * to the <code>app_predictor</code> value of 244 * {@link android.R.attr#protectionLevel}. 245 * 246 * @hide 247 */ 248 @SystemApi 249 public static final int PROTECTION_FLAG_APP_PREDICTOR = 0x200000; 250 251 /** 252 * Additional flag for {@link #protectionLevel}, corresponding 253 * to the <code>module</code> value of 254 * {@link android.R.attr#protectionLevel}. 255 * 256 * @hide 257 */ 258 @SystemApi 259 public static final int PROTECTION_FLAG_MODULE = 0x400000; 260 261 /** 262 * Additional flag for {@link #protectionLevel}, corresponding 263 * to the <code>companion</code> value of 264 * {@link android.R.attr#protectionLevel}. 265 * 266 * @hide 267 */ 268 @SystemApi 269 public static final int PROTECTION_FLAG_COMPANION = 0x800000; 270 271 /** 272 * Additional flag for {@link #protectionLevel}, corresponding 273 * to the <code>retailDemo</code> value of 274 * {@link android.R.attr#protectionLevel}. 275 * 276 * @hide 277 */ 278 @SystemApi 279 public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000; 280 281 /** 282 * Additional flag for {@link #protectionLevel}, corresponding 283 * to the <code>recents</code> value of 284 * {@link android.R.attr#protectionLevel}. 285 * 286 * @hide 287 */ 288 @SystemApi 289 public static final int PROTECTION_FLAG_RECENTS = 0x2000000; 290 291 /** 292 * Additional flag for {@link #protectionLevel}, corresponding to the <code>role</code> value of 293 * {@link android.R.attr#protectionLevel}. 294 * 295 * @hide 296 */ 297 @SystemApi 298 public static final int PROTECTION_FLAG_ROLE = 0x4000000; 299 300 /** 301 * Additional flag for {@link #protectionLevel}, correspoinding to the {@code knownSigner} value 302 * of {@link android.R.attr#protectionLevel}. 303 * 304 * @hide 305 */ 306 @SystemApi 307 public static final int PROTECTION_FLAG_KNOWN_SIGNER = 0x8000000; 308 309 /** @hide */ 310 @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { 311 PROTECTION_FLAG_PRIVILEGED, 312 PROTECTION_FLAG_SYSTEM, 313 PROTECTION_FLAG_DEVELOPMENT, 314 PROTECTION_FLAG_APPOP, 315 PROTECTION_FLAG_PRE23, 316 PROTECTION_FLAG_INSTALLER, 317 PROTECTION_FLAG_VERIFIER, 318 PROTECTION_FLAG_PREINSTALLED, 319 PROTECTION_FLAG_SETUP, 320 PROTECTION_FLAG_INSTANT, 321 PROTECTION_FLAG_RUNTIME_ONLY, 322 PROTECTION_FLAG_OEM, 323 PROTECTION_FLAG_VENDOR_PRIVILEGED, 324 PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER, 325 PROTECTION_FLAG_CONFIGURATOR, 326 PROTECTION_FLAG_INCIDENT_REPORT_APPROVER, 327 PROTECTION_FLAG_APP_PREDICTOR, 328 PROTECTION_FLAG_COMPANION, 329 PROTECTION_FLAG_RETAIL_DEMO, 330 PROTECTION_FLAG_RECENTS, 331 PROTECTION_FLAG_ROLE, 332 PROTECTION_FLAG_KNOWN_SIGNER, 333 PROTECTION_FLAG_MODULE, 334 }) 335 @Retention(RetentionPolicy.SOURCE) 336 public @interface ProtectionFlags {} 337 338 /** 339 * Mask for {@link #protectionLevel}: the basic protection type. 340 * 341 * @deprecated Use #getProtection() instead. 342 */ 343 @Deprecated 344 public static final int PROTECTION_MASK_BASE = 0xf; 345 346 /** 347 * Mask for {@link #protectionLevel}: additional flag bits. 348 * 349 * @deprecated Use #getProtectionFlags() instead. 350 */ 351 @Deprecated 352 public static final int PROTECTION_MASK_FLAGS = 0xfff0; 353 354 /** 355 * The level of access this permission is protecting, as per 356 * {@link android.R.attr#protectionLevel}. Consists of 357 * a base permission type and zero or more flags. Use the following functions 358 * to extract them. 359 * 360 * <pre> 361 * int basePermissionType = permissionInfo.getProtection(); 362 * int permissionFlags = permissionInfo.getProtectionFlags(); 363 * </pre> 364 * 365 * <p></p>Base permission types are {@link #PROTECTION_NORMAL}, 366 * {@link #PROTECTION_DANGEROUS}, {@link #PROTECTION_SIGNATURE}, {@link #PROTECTION_INTERNAL} 367 * and the deprecated {@link #PROTECTION_SIGNATURE_OR_SYSTEM}. 368 * Flags are listed under {@link android.R.attr#protectionLevel}. 369 * 370 * @deprecated Use #getProtection() and #getProtectionFlags() instead. 371 */ 372 @Deprecated 373 public int protectionLevel; 374 375 /** 376 * The group this permission is a part of, as per 377 * {@link android.R.attr#permissionGroup}. 378 * <p> 379 * The actual grouping of platform-defined runtime permissions is subject to change and can be 380 * queried with {@link PackageManager#getGroupOfPlatformPermission}. 381 */ 382 public @Nullable String group; 383 384 /** 385 * Flag for {@link #flags}, corresponding to <code>costsMoney</code> 386 * value of {@link android.R.attr#permissionFlags}. 387 */ 388 public static final int FLAG_COSTS_MONEY = 1<<0; 389 390 /** 391 * Flag for {@link #flags}, corresponding to <code>removed</code> 392 * value of {@link android.R.attr#permissionFlags}. 393 * @hide 394 */ 395 @SystemApi 396 public static final int FLAG_REMOVED = 1<<1; 397 398 /** 399 * Flag for {@link #flags}, corresponding to <code>hardRestricted</code> 400 * value of {@link android.R.attr#permissionFlags}. 401 * 402 * <p> This permission is restricted by the platform and it would be 403 * grantable only to apps that meet special criteria per platform 404 * policy. 405 */ 406 public static final int FLAG_HARD_RESTRICTED = 1<<2; 407 408 /** 409 * Flag for {@link #flags}, corresponding to <code>softRestricted</code> 410 * value of {@link android.R.attr#permissionFlags}. 411 * 412 * <p>This permission is restricted by the platform and it would be 413 * grantable in its full form to apps that meet special criteria 414 * per platform policy. Otherwise, a weaker form of the permission 415 * would be granted. The weak grant depends on the permission. 416 */ 417 public static final int FLAG_SOFT_RESTRICTED = 1<<3; 418 419 /** 420 * Flag for {@link #flags}, corresponding to <code>immutablyRestricted</code> 421 * value of {@link android.R.attr#permissionFlags}. 422 * 423 * <p>This permission is restricted immutably which means that its 424 * restriction state may be specified only on the first install of 425 * the app and will stay in this initial allowlist state until 426 * the app is uninstalled. 427 */ 428 public static final int FLAG_IMMUTABLY_RESTRICTED = 1<<4; 429 430 /** 431 * Flag for {@link #flags}, indicating that this permission has been 432 * installed into the system's globally defined permissions. 433 */ 434 public static final int FLAG_INSTALLED = 1<<30; 435 436 /** @hide */ 437 @IntDef(flag = true, prefix = { "FLAG_" }, value = { 438 FLAG_COSTS_MONEY, 439 FLAG_REMOVED, 440 FLAG_HARD_RESTRICTED, 441 FLAG_SOFT_RESTRICTED, 442 FLAG_IMMUTABLY_RESTRICTED, 443 FLAG_INSTALLED 444 }) 445 @Retention(RetentionPolicy.SOURCE) 446 public @interface Flags {} 447 448 /** 449 * Additional flags about this permission as given by 450 * {@link android.R.attr#permissionFlags}. 451 */ 452 public @Flags int flags; 453 454 /** 455 * A string resource identifier (in the package's resources) of this 456 * permission's description. From the "description" attribute or, 457 * if not set, 0. 458 */ 459 public @StringRes int descriptionRes; 460 461 /** 462 * A string resource identifier (in the package's resources) used to request the permissions. 463 * From the "request" attribute or, if not set, 0. 464 * 465 * @hide 466 */ 467 @SystemApi 468 public @StringRes int requestRes; 469 470 /** 471 * Some permissions only grant access while the app is in foreground. Some of these permissions 472 * allow to add background capabilities by adding another permission. 473 * 474 * If this is such a permission, this is the name of the permission adding the background 475 * access. 476 * 477 * From the "backgroundPermission" attribute or, if not set null 478 * 479 * @hide 480 */ 481 @SystemApi 482 public final @Nullable String backgroundPermission; 483 484 /** 485 * The description string provided in the AndroidManifest file, if any. You 486 * probably don't want to use this, since it will be null if the description 487 * is in a resource. You probably want 488 * {@link PermissionInfo#loadDescription} instead. 489 */ 490 public @Nullable CharSequence nonLocalizedDescription; 491 492 private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class); 493 494 /** 495 * A {@link Set} of trusted signing certificate digests. If this permission has the {@link 496 * #PROTECTION_FLAG_KNOWN_SIGNER} flag set the permission will be granted to a requesting app 497 * if the app is signed by any of these certificates. 498 * 499 * @hide 500 */ 501 // Already being used as mutable and most other fields in this class are also mutable. 502 @SuppressLint("MutableBareField") 503 @SystemApi 504 public @NonNull Set<String> knownCerts = Collections.emptySet(); 505 506 /** @hide */ fixProtectionLevel(int level)507 public static int fixProtectionLevel(int level) { 508 if (level == PROTECTION_SIGNATURE_OR_SYSTEM) { 509 level = PROTECTION_SIGNATURE | PROTECTION_FLAG_PRIVILEGED; 510 } 511 if ((level & PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0 512 && (level & PROTECTION_FLAG_PRIVILEGED) == 0) { 513 // 'vendorPrivileged' must be 'privileged'. If not, 514 // drop the vendorPrivileged. 515 level = level & ~PROTECTION_FLAG_VENDOR_PRIVILEGED; 516 } 517 return level; 518 } 519 520 /** @hide */ 521 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protectionToString(int level)522 public static @NonNull String protectionToString(int level) { 523 final StringBuilder protLevel = new StringBuilder(); 524 switch (level & PROTECTION_MASK_BASE) { 525 case PermissionInfo.PROTECTION_DANGEROUS: 526 protLevel.append("dangerous"); 527 break; 528 case PermissionInfo.PROTECTION_NORMAL: 529 protLevel.append("normal"); 530 break; 531 case PermissionInfo.PROTECTION_SIGNATURE: 532 protLevel.append("signature"); 533 break; 534 case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: 535 protLevel.append("signatureOrSystem"); 536 break; 537 case PermissionInfo.PROTECTION_INTERNAL: 538 protLevel.append("internal"); 539 break; 540 default: 541 protLevel.append("????"); 542 break; 543 } 544 if ((level & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 545 protLevel.append("|privileged"); 546 } 547 if ((level & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 548 protLevel.append("|development"); 549 } 550 if ((level & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 551 protLevel.append("|appop"); 552 } 553 if ((level & PermissionInfo.PROTECTION_FLAG_PRE23) != 0) { 554 protLevel.append("|pre23"); 555 } 556 if ((level & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) { 557 protLevel.append("|installer"); 558 } 559 if ((level & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) { 560 protLevel.append("|verifier"); 561 } 562 if ((level & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) { 563 protLevel.append("|preinstalled"); 564 } 565 if ((level & PermissionInfo.PROTECTION_FLAG_SETUP) != 0) { 566 protLevel.append("|setup"); 567 } 568 if ((level & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0) { 569 protLevel.append("|instant"); 570 } 571 if ((level & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0) { 572 protLevel.append("|runtime"); 573 } 574 if ((level & PermissionInfo.PROTECTION_FLAG_OEM) != 0) { 575 protLevel.append("|oem"); 576 } 577 if ((level & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0) { 578 protLevel.append("|vendorPrivileged"); 579 } 580 if ((level & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) != 0) { 581 protLevel.append("|textClassifier"); 582 } 583 if ((level & PROTECTION_FLAG_CONFIGURATOR) != 0) { 584 protLevel.append("|configurator"); 585 } 586 if ((level & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0) { 587 protLevel.append("|incidentReportApprover"); 588 } 589 if ((level & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0) { 590 protLevel.append("|appPredictor"); 591 } 592 if ((level & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0) { 593 protLevel.append("|companion"); 594 } 595 if ((level & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0) { 596 protLevel.append("|retailDemo"); 597 } 598 if ((level & PermissionInfo.PROTECTION_FLAG_RECENTS) != 0) { 599 protLevel.append("|recents"); 600 } 601 if ((level & PermissionInfo.PROTECTION_FLAG_ROLE) != 0) { 602 protLevel.append("|role"); 603 } 604 if ((level & PermissionInfo.PROTECTION_FLAG_KNOWN_SIGNER) != 0) { 605 protLevel.append("|knownSigner"); 606 } 607 if ((level & PermissionInfo.PROTECTION_FLAG_MODULE) != 0) { 608 protLevel.append(("|module")); 609 } 610 return protLevel.toString(); 611 } 612 613 /** 614 * @hide 615 */ PermissionInfo(@ullable String backgroundPermission)616 public PermissionInfo(@Nullable String backgroundPermission) { 617 this.backgroundPermission = backgroundPermission; 618 } 619 620 /** 621 * @deprecated Should only be created by the system. 622 */ 623 @Deprecated PermissionInfo()624 public PermissionInfo() { 625 this((String) null); 626 } 627 628 /** 629 * @deprecated Should only be created by the system. 630 */ 631 @Deprecated PermissionInfo(@onNull PermissionInfo orig)632 public PermissionInfo(@NonNull PermissionInfo orig) { 633 super(orig); 634 protectionLevel = orig.protectionLevel; 635 flags = orig.flags; 636 group = orig.group; 637 backgroundPermission = orig.backgroundPermission; 638 descriptionRes = orig.descriptionRes; 639 requestRes = orig.requestRes; 640 nonLocalizedDescription = orig.nonLocalizedDescription; 641 // Note that knownCerts wasn't properly copied before Android U. 642 knownCerts = orig.knownCerts; 643 } 644 645 /** 646 * Retrieve the textual description of this permission. This 647 * will call back on the given PackageManager to load the description from 648 * the application. 649 * 650 * @param pm A PackageManager from which the label can be loaded; usually 651 * the PackageManager from which you originally retrieved this item. 652 * 653 * @return Returns a CharSequence containing the permission's description. 654 * If there is no description, null is returned. 655 */ loadDescription(@onNull PackageManager pm)656 public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) { 657 if (nonLocalizedDescription != null) { 658 return nonLocalizedDescription; 659 } 660 if (descriptionRes != 0) { 661 CharSequence label = pm.getText(packageName, descriptionRes, null); 662 if (label != null) { 663 return label; 664 } 665 } 666 return null; 667 } 668 669 /** 670 * Return the base permission type. 671 */ 672 @Protection getProtection()673 public int getProtection() { 674 return protectionLevel & PROTECTION_MASK_BASE; 675 } 676 677 /** 678 * Return the additional flags in {@link #protectionLevel}. 679 */ 680 @ProtectionFlags getProtectionFlags()681 public int getProtectionFlags() { 682 return protectionLevel & ~PROTECTION_MASK_BASE; 683 } 684 685 @Override toString()686 public String toString() { 687 return "PermissionInfo{" 688 + Integer.toHexString(System.identityHashCode(this)) 689 + " " + name + "}"; 690 } 691 692 @Override describeContents()693 public int describeContents() { 694 return 0; 695 } 696 697 @Override writeToParcel(Parcel dest, int parcelableFlags)698 public void writeToParcel(Parcel dest, int parcelableFlags) { 699 super.writeToParcel(dest, parcelableFlags); 700 dest.writeInt(protectionLevel); 701 dest.writeInt(flags); 702 dest.writeString8(group); 703 dest.writeString8(backgroundPermission); 704 dest.writeInt(descriptionRes); 705 dest.writeInt(requestRes); 706 TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags); 707 sForStringSet.parcel(knownCerts, dest, parcelableFlags); 708 } 709 710 /** @hide */ calculateFootprint()711 public int calculateFootprint() { 712 int size = name.length(); 713 if (nonLocalizedLabel != null) { 714 size += nonLocalizedLabel.length(); 715 } 716 if (nonLocalizedDescription != null) { 717 size += nonLocalizedDescription.length(); 718 } 719 return size; 720 } 721 722 /** @hide */ isHardRestricted()723 public boolean isHardRestricted() { 724 return (flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0; 725 } 726 727 /** @hide */ isSoftRestricted()728 public boolean isSoftRestricted() { 729 return (flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0; 730 } 731 732 /** @hide */ isRestricted()733 public boolean isRestricted() { 734 return isHardRestricted() || isSoftRestricted(); 735 } 736 737 /** @hide */ isAppOp()738 public boolean isAppOp() { 739 return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; 740 } 741 742 /** @hide */ isRuntime()743 public boolean isRuntime() { 744 return getProtection() == PROTECTION_DANGEROUS; 745 } 746 747 public static final @NonNull Creator<PermissionInfo> CREATOR = 748 new Creator<PermissionInfo>() { 749 @Override 750 public PermissionInfo createFromParcel(Parcel source) { 751 return new PermissionInfo(source); 752 } 753 @Override 754 public PermissionInfo[] newArray(int size) { 755 return new PermissionInfo[size]; 756 } 757 }; 758 PermissionInfo(Parcel source)759 private PermissionInfo(Parcel source) { 760 super(source); 761 protectionLevel = source.readInt(); 762 flags = source.readInt(); 763 group = source.readString8(); 764 backgroundPermission = source.readString8(); 765 descriptionRes = source.readInt(); 766 requestRes = source.readInt(); 767 nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 768 knownCerts = sForStringSet.unparcel(source); 769 } 770 } 771