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