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 * @deprecated This flag has been replaced by the 277 * {@link android.R.string#config_defaultRetailDemo retail demo role} and is a 278 * no-op since {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. 279 * 280 * @hide 281 */ 282 @SystemApi 283 public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000; 284 285 /** 286 * Additional flag for {@link #protectionLevel}, corresponding 287 * to the <code>recents</code> value of 288 * {@link android.R.attr#protectionLevel}. 289 * 290 * @hide 291 */ 292 @SystemApi 293 public static final int PROTECTION_FLAG_RECENTS = 0x2000000; 294 295 /** 296 * Additional flag for {@link #protectionLevel}, corresponding to the <code>role</code> value of 297 * {@link android.R.attr#protectionLevel}. 298 * 299 * @hide 300 */ 301 @SystemApi 302 public static final int PROTECTION_FLAG_ROLE = 0x4000000; 303 304 /** 305 * Additional flag for {@link #protectionLevel}, correspoinding to the {@code knownSigner} value 306 * of {@link android.R.attr#protectionLevel}. 307 * 308 * @hide 309 */ 310 @SystemApi 311 public static final int PROTECTION_FLAG_KNOWN_SIGNER = 0x8000000; 312 313 /** @hide */ 314 @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { 315 PROTECTION_FLAG_PRIVILEGED, 316 PROTECTION_FLAG_SYSTEM, 317 PROTECTION_FLAG_DEVELOPMENT, 318 PROTECTION_FLAG_APPOP, 319 PROTECTION_FLAG_PRE23, 320 PROTECTION_FLAG_INSTALLER, 321 PROTECTION_FLAG_VERIFIER, 322 PROTECTION_FLAG_PREINSTALLED, 323 PROTECTION_FLAG_SETUP, 324 PROTECTION_FLAG_INSTANT, 325 PROTECTION_FLAG_RUNTIME_ONLY, 326 PROTECTION_FLAG_OEM, 327 PROTECTION_FLAG_VENDOR_PRIVILEGED, 328 PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER, 329 PROTECTION_FLAG_CONFIGURATOR, 330 PROTECTION_FLAG_INCIDENT_REPORT_APPROVER, 331 PROTECTION_FLAG_APP_PREDICTOR, 332 PROTECTION_FLAG_COMPANION, 333 PROTECTION_FLAG_RETAIL_DEMO, 334 PROTECTION_FLAG_RECENTS, 335 PROTECTION_FLAG_ROLE, 336 PROTECTION_FLAG_KNOWN_SIGNER, 337 PROTECTION_FLAG_MODULE, 338 }) 339 @Retention(RetentionPolicy.SOURCE) 340 public @interface ProtectionFlags {} 341 342 /** 343 * Mask for {@link #protectionLevel}: the basic protection type. 344 * 345 * @deprecated Use #getProtection() instead. 346 */ 347 @Deprecated 348 public static final int PROTECTION_MASK_BASE = 0xf; 349 350 /** 351 * Mask for {@link #protectionLevel}: additional flag bits. 352 * 353 * @deprecated Use #getProtectionFlags() instead. 354 */ 355 @Deprecated 356 public static final int PROTECTION_MASK_FLAGS = 0xfff0; 357 358 /** 359 * The level of access this permission is protecting, as per 360 * {@link android.R.attr#protectionLevel}. Consists of 361 * a base permission type and zero or more flags. Use the following functions 362 * to extract them. 363 * 364 * <pre> 365 * int basePermissionType = permissionInfo.getProtection(); 366 * int permissionFlags = permissionInfo.getProtectionFlags(); 367 * </pre> 368 * 369 * <p></p>Base permission types are {@link #PROTECTION_NORMAL}, 370 * {@link #PROTECTION_DANGEROUS}, {@link #PROTECTION_SIGNATURE}, {@link #PROTECTION_INTERNAL} 371 * and the deprecated {@link #PROTECTION_SIGNATURE_OR_SYSTEM}. 372 * Flags are listed under {@link android.R.attr#protectionLevel}. 373 * 374 * @deprecated Use #getProtection() and #getProtectionFlags() instead. 375 */ 376 @Deprecated 377 public int protectionLevel; 378 379 /** 380 * The group this permission is a part of, as per 381 * {@link android.R.attr#permissionGroup}. 382 * <p> 383 * The actual grouping of platform-defined runtime permissions is subject to change and can be 384 * queried with {@link PackageManager#getGroupOfPlatformPermission}. 385 */ 386 public @Nullable String group; 387 388 /** 389 * Flag for {@link #flags}, corresponding to <code>costsMoney</code> 390 * value of {@link android.R.attr#permissionFlags}. 391 */ 392 public static final int FLAG_COSTS_MONEY = 1<<0; 393 394 /** 395 * Flag for {@link #flags}, corresponding to <code>removed</code> 396 * value of {@link android.R.attr#permissionFlags}. 397 * @hide 398 */ 399 @SystemApi 400 public static final int FLAG_REMOVED = 1<<1; 401 402 /** 403 * Flag for {@link #flags}, corresponding to <code>hardRestricted</code> 404 * value of {@link android.R.attr#permissionFlags}. 405 * 406 * <p> This permission is restricted by the platform and it would be 407 * grantable only to apps that meet special criteria per platform 408 * policy. 409 */ 410 public static final int FLAG_HARD_RESTRICTED = 1<<2; 411 412 /** 413 * Flag for {@link #flags}, corresponding to <code>softRestricted</code> 414 * value of {@link android.R.attr#permissionFlags}. 415 * 416 * <p>This permission is restricted by the platform and it would be 417 * grantable in its full form to apps that meet special criteria 418 * per platform policy. Otherwise, a weaker form of the permission 419 * would be granted. The weak grant depends on the permission. 420 */ 421 public static final int FLAG_SOFT_RESTRICTED = 1<<3; 422 423 /** 424 * Flag for {@link #flags}, corresponding to <code>immutablyRestricted</code> 425 * value of {@link android.R.attr#permissionFlags}. 426 * 427 * <p>This permission is restricted immutably which means that its 428 * restriction state may be specified only on the first install of 429 * the app and will stay in this initial allowlist state until 430 * the app is uninstalled. 431 */ 432 public static final int FLAG_IMMUTABLY_RESTRICTED = 1<<4; 433 434 /** 435 * Flag for {@link #flags}, indicating that this permission has been 436 * installed into the system's globally defined permissions. 437 */ 438 public static final int FLAG_INSTALLED = 1<<30; 439 440 /** @hide */ 441 @IntDef(flag = true, prefix = { "FLAG_" }, value = { 442 FLAG_COSTS_MONEY, 443 FLAG_REMOVED, 444 FLAG_HARD_RESTRICTED, 445 FLAG_SOFT_RESTRICTED, 446 FLAG_IMMUTABLY_RESTRICTED, 447 FLAG_INSTALLED 448 }) 449 @Retention(RetentionPolicy.SOURCE) 450 public @interface Flags {} 451 452 /** 453 * Additional flags about this permission as given by 454 * {@link android.R.attr#permissionFlags}. 455 */ 456 public @Flags int flags; 457 458 /** 459 * A string resource identifier (in the package's resources) of this 460 * permission's description. From the "description" attribute or, 461 * if not set, 0. 462 */ 463 public @StringRes int descriptionRes; 464 465 /** 466 * A string resource identifier (in the package's resources) used to request the permissions. 467 * From the "request" attribute or, if not set, 0. 468 * 469 * @hide 470 */ 471 @SystemApi 472 public @StringRes int requestRes; 473 474 /** 475 * Some permissions only grant access while the app is in foreground. Some of these permissions 476 * allow to add background capabilities by adding another permission. 477 * 478 * If this is such a permission, this is the name of the permission adding the background 479 * access. 480 * 481 * From the "backgroundPermission" attribute or, if not set null 482 * 483 * @hide 484 */ 485 @SystemApi 486 public final @Nullable String backgroundPermission; 487 488 /** 489 * The description string provided in the AndroidManifest file, if any. You 490 * probably don't want to use this, since it will be null if the description 491 * is in a resource. You probably want 492 * {@link PermissionInfo#loadDescription} instead. 493 */ 494 public @Nullable CharSequence nonLocalizedDescription; 495 496 private static final ForStringSet sForStringSet = 497 Parcelling.Cache.getOrCreate(ForStringSet.class); 498 499 /** 500 * A {@link Set} of trusted signing certificate digests. If this permission has the {@link 501 * #PROTECTION_FLAG_KNOWN_SIGNER} flag set the permission will be granted to a requesting app 502 * if the app is signed by any of these certificates. 503 * 504 * @hide 505 */ 506 // Already being used as mutable and most other fields in this class are also mutable. 507 @SuppressLint("MutableBareField") 508 @SystemApi 509 public @NonNull Set<String> knownCerts = Collections.emptySet(); 510 511 /** @hide */ fixProtectionLevel(int level)512 public static int fixProtectionLevel(int level) { 513 if (level == PROTECTION_SIGNATURE_OR_SYSTEM) { 514 level = PROTECTION_SIGNATURE | PROTECTION_FLAG_PRIVILEGED; 515 } 516 if ((level & PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0 517 && (level & PROTECTION_FLAG_PRIVILEGED) == 0) { 518 // 'vendorPrivileged' must be 'privileged'. If not, 519 // drop the vendorPrivileged. 520 level = level & ~PROTECTION_FLAG_VENDOR_PRIVILEGED; 521 } 522 return level; 523 } 524 525 /** @hide */ 526 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protectionToString(int level)527 public static @NonNull String protectionToString(int level) { 528 final StringBuilder protLevel = new StringBuilder(); 529 switch (level & PROTECTION_MASK_BASE) { 530 case PermissionInfo.PROTECTION_DANGEROUS: 531 protLevel.append("dangerous"); 532 break; 533 case PermissionInfo.PROTECTION_NORMAL: 534 protLevel.append("normal"); 535 break; 536 case PermissionInfo.PROTECTION_SIGNATURE: 537 protLevel.append("signature"); 538 break; 539 case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: 540 protLevel.append("signatureOrSystem"); 541 break; 542 case PermissionInfo.PROTECTION_INTERNAL: 543 protLevel.append("internal"); 544 break; 545 default: 546 protLevel.append("????"); 547 break; 548 } 549 if ((level & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 550 protLevel.append("|privileged"); 551 } 552 if ((level & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 553 protLevel.append("|development"); 554 } 555 if ((level & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 556 protLevel.append("|appop"); 557 } 558 if ((level & PermissionInfo.PROTECTION_FLAG_PRE23) != 0) { 559 protLevel.append("|pre23"); 560 } 561 if ((level & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) { 562 protLevel.append("|installer"); 563 } 564 if ((level & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) { 565 protLevel.append("|verifier"); 566 } 567 if ((level & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) { 568 protLevel.append("|preinstalled"); 569 } 570 if ((level & PermissionInfo.PROTECTION_FLAG_SETUP) != 0) { 571 protLevel.append("|setup"); 572 } 573 if ((level & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0) { 574 protLevel.append("|instant"); 575 } 576 if ((level & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0) { 577 protLevel.append("|runtime"); 578 } 579 if ((level & PermissionInfo.PROTECTION_FLAG_OEM) != 0) { 580 protLevel.append("|oem"); 581 } 582 if ((level & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0) { 583 protLevel.append("|vendorPrivileged"); 584 } 585 if ((level & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) != 0) { 586 protLevel.append("|textClassifier"); 587 } 588 if ((level & PROTECTION_FLAG_CONFIGURATOR) != 0) { 589 protLevel.append("|configurator"); 590 } 591 if ((level & PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER) != 0) { 592 protLevel.append("|incidentReportApprover"); 593 } 594 if ((level & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0) { 595 protLevel.append("|appPredictor"); 596 } 597 if ((level & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0) { 598 protLevel.append("|companion"); 599 } 600 if ((level & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0) { 601 protLevel.append("|retailDemo"); 602 } 603 if ((level & PermissionInfo.PROTECTION_FLAG_RECENTS) != 0) { 604 protLevel.append("|recents"); 605 } 606 if ((level & PermissionInfo.PROTECTION_FLAG_ROLE) != 0) { 607 protLevel.append("|role"); 608 } 609 if ((level & PermissionInfo.PROTECTION_FLAG_KNOWN_SIGNER) != 0) { 610 protLevel.append("|knownSigner"); 611 } 612 if ((level & PermissionInfo.PROTECTION_FLAG_MODULE) != 0) { 613 protLevel.append(("|module")); 614 } 615 return protLevel.toString(); 616 } 617 618 /** @hide */ flagsToString(@lags int flags)619 public static @NonNull String flagsToString(@Flags int flags) { 620 StringBuilder sb = new StringBuilder("["); 621 while (flags != 0) { 622 final int flag = 1 << Integer.numberOfTrailingZeros(flags); 623 flags &= ~flag; 624 switch (flag) { 625 case PermissionInfo.FLAG_COSTS_MONEY: 626 sb.append("costsMoney"); 627 break; 628 case PermissionInfo.FLAG_REMOVED: 629 sb.append("removed"); 630 break; 631 case PermissionInfo.FLAG_HARD_RESTRICTED: 632 sb.append("hardRestricted"); 633 break; 634 case PermissionInfo.FLAG_SOFT_RESTRICTED: 635 sb.append("softRestricted"); 636 break; 637 case PermissionInfo.FLAG_IMMUTABLY_RESTRICTED: 638 sb.append("immutablyRestricted"); 639 break; 640 case PermissionInfo.FLAG_INSTALLED: 641 sb.append("installed"); 642 break; 643 default: sb.append(flag); 644 } 645 if (flags != 0) { 646 sb.append("|"); 647 } 648 } 649 return sb.append("]").toString(); 650 } 651 652 /** 653 * @hide 654 */ PermissionInfo(@ullable String backgroundPermission)655 public PermissionInfo(@Nullable String backgroundPermission) { 656 this.backgroundPermission = backgroundPermission; 657 } 658 659 /** 660 * @deprecated Should only be created by the system. 661 */ 662 @Deprecated PermissionInfo()663 public PermissionInfo() { 664 this((String) null); 665 } 666 667 /** 668 * @deprecated Should only be created by the system. 669 */ 670 @Deprecated PermissionInfo(@onNull PermissionInfo orig)671 public PermissionInfo(@NonNull PermissionInfo orig) { 672 super(orig); 673 protectionLevel = orig.protectionLevel; 674 flags = orig.flags; 675 group = orig.group; 676 backgroundPermission = orig.backgroundPermission; 677 descriptionRes = orig.descriptionRes; 678 requestRes = orig.requestRes; 679 nonLocalizedDescription = orig.nonLocalizedDescription; 680 // Note that knownCerts wasn't properly copied before Android U. 681 knownCerts = orig.knownCerts; 682 } 683 684 /** 685 * Retrieve the textual description of this permission. This 686 * will call back on the given PackageManager to load the description from 687 * the application. 688 * 689 * @param pm A PackageManager from which the label can be loaded; usually 690 * the PackageManager from which you originally retrieved this item. 691 * 692 * @return Returns a CharSequence containing the permission's description. 693 * If there is no description, null is returned. 694 */ loadDescription(@onNull PackageManager pm)695 public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) { 696 if (nonLocalizedDescription != null) { 697 return nonLocalizedDescription; 698 } 699 if (descriptionRes != 0) { 700 CharSequence label = pm.getText(packageName, descriptionRes, null); 701 if (label != null) { 702 return label; 703 } 704 } 705 return null; 706 } 707 708 /** 709 * Return the base permission type. 710 */ 711 @Protection getProtection()712 public int getProtection() { 713 return protectionLevel & PROTECTION_MASK_BASE; 714 } 715 716 /** 717 * Return the additional flags in {@link #protectionLevel}. 718 */ 719 @ProtectionFlags getProtectionFlags()720 public int getProtectionFlags() { 721 return protectionLevel & ~PROTECTION_MASK_BASE; 722 } 723 724 @Override toString()725 public String toString() { 726 return "PermissionInfo{" 727 + Integer.toHexString(System.identityHashCode(this)) 728 + " " + name + "}"; 729 } 730 731 @Override describeContents()732 public int describeContents() { 733 return 0; 734 } 735 736 @Override writeToParcel(Parcel dest, int parcelableFlags)737 public void writeToParcel(Parcel dest, int parcelableFlags) { 738 super.writeToParcel(dest, parcelableFlags); 739 dest.writeInt(protectionLevel); 740 dest.writeInt(flags); 741 dest.writeString8(group); 742 dest.writeString8(backgroundPermission); 743 dest.writeInt(descriptionRes); 744 dest.writeInt(requestRes); 745 TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags); 746 sForStringSet.parcel(knownCerts, dest, parcelableFlags); 747 } 748 749 /** @hide */ calculateFootprint()750 public int calculateFootprint() { 751 int size = name.length(); 752 if (nonLocalizedLabel != null) { 753 size += nonLocalizedLabel.length(); 754 } 755 if (nonLocalizedDescription != null) { 756 size += nonLocalizedDescription.length(); 757 } 758 return size; 759 } 760 761 /** @hide */ isHardRestricted()762 public boolean isHardRestricted() { 763 return (flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0; 764 } 765 766 /** @hide */ isSoftRestricted()767 public boolean isSoftRestricted() { 768 return (flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0; 769 } 770 771 /** @hide */ isRestricted()772 public boolean isRestricted() { 773 return isHardRestricted() || isSoftRestricted(); 774 } 775 776 /** @hide */ isAppOp()777 public boolean isAppOp() { 778 return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; 779 } 780 781 /** @hide */ isRuntime()782 public boolean isRuntime() { 783 return getProtection() == PROTECTION_DANGEROUS; 784 } 785 786 public static final @NonNull Creator<PermissionInfo> CREATOR = 787 new Creator<PermissionInfo>() { 788 @Override 789 public PermissionInfo createFromParcel(Parcel source) { 790 return new PermissionInfo(source); 791 } 792 @Override 793 public PermissionInfo[] newArray(int size) { 794 return new PermissionInfo[size]; 795 } 796 }; 797 PermissionInfo(Parcel source)798 private PermissionInfo(Parcel source) { 799 super(source); 800 protectionLevel = source.readInt(); 801 flags = source.readInt(); 802 group = source.readString8(); 803 backgroundPermission = source.readString8(); 804 descriptionRes = source.readInt(); 805 requestRes = source.readInt(); 806 nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 807 knownCerts = sForStringSet.unparcel(source); 808 } 809 } 810