• 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      * @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