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