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