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