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
17package android.content.pm;
18
19import android.annotation.SystemApi;
20import android.annotation.TestApi;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.text.TextUtils;
24
25/**
26 * Information you can retrieve about a particular security permission
27 * known to the system.  This corresponds to information collected from the
28 * AndroidManifest.xml's <permission> tags.
29 */
30public class PermissionInfo extends PackageItemInfo implements Parcelable {
31    /**
32     * A normal application value for {@link #protectionLevel}, corresponding
33     * to the <code>normal</code> value of
34     * {@link android.R.attr#protectionLevel}.
35     */
36    public static final int PROTECTION_NORMAL = 0;
37
38    /**
39     * Dangerous value for {@link #protectionLevel}, corresponding
40     * to the <code>dangerous</code> value of
41     * {@link android.R.attr#protectionLevel}.
42     */
43    public static final int PROTECTION_DANGEROUS = 1;
44
45    /**
46     * System-level value for {@link #protectionLevel}, corresponding
47     * to the <code>signature</code> value of
48     * {@link android.R.attr#protectionLevel}.
49     */
50    public static final int PROTECTION_SIGNATURE = 2;
51
52    /**
53     * @deprecated Use {@link #PROTECTION_SIGNATURE}|{@link #PROTECTION_FLAG_PRIVILEGED}
54     * instead.
55     */
56    @Deprecated
57    public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
58
59    /**
60     * Additional flag for {@link #protectionLevel}, corresponding
61     * to the <code>privileged</code> value of
62     * {@link android.R.attr#protectionLevel}.
63     */
64    public static final int PROTECTION_FLAG_PRIVILEGED = 0x10;
65
66    /**
67     * @deprecated Old name for {@link #PROTECTION_FLAG_PRIVILEGED}, which
68     * is now very confusing because it only applies to privileged apps, not all
69     * apps on the system image.
70     */
71    @Deprecated
72    public static final int PROTECTION_FLAG_SYSTEM = 0x10;
73
74    /**
75     * Additional flag for {@link #protectionLevel}, corresponding
76     * to the <code>development</code> value of
77     * {@link android.R.attr#protectionLevel}.
78     */
79    public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
80
81    /**
82     * Additional flag for {@link #protectionLevel}, corresponding
83     * to the <code>appop</code> value of
84     * {@link android.R.attr#protectionLevel}.
85     */
86    public static final int PROTECTION_FLAG_APPOP = 0x40;
87
88    /**
89     * Additional flag for {@link #protectionLevel}, corresponding
90     * to the <code>pre23</code> value of
91     * {@link android.R.attr#protectionLevel}.
92     */
93    public static final int PROTECTION_FLAG_PRE23 = 0x80;
94
95    /**
96     * Additional flag for {@link #protectionLevel}, corresponding
97     * to the <code>installer</code> value of
98     * {@link android.R.attr#protectionLevel}.
99     */
100    public static final int PROTECTION_FLAG_INSTALLER = 0x100;
101
102    /**
103     * Additional flag for {@link #protectionLevel}, corresponding
104     * to the <code>verifier</code> value of
105     * {@link android.R.attr#protectionLevel}.
106     */
107    public static final int PROTECTION_FLAG_VERIFIER = 0x200;
108
109    /**
110     * Additional flag for {@link #protectionLevel}, corresponding
111     * to the <code>preinstalled</code> value of
112     * {@link android.R.attr#protectionLevel}.
113     */
114    public static final int PROTECTION_FLAG_PREINSTALLED = 0x400;
115
116    /**
117     * Additional flag for {@link #protectionLevel}, corresponding
118     * to the <code>setup</code> value of
119     * {@link android.R.attr#protectionLevel}.
120     */
121    public static final int PROTECTION_FLAG_SETUP = 0x800;
122
123    /**
124     * Additional flag for {@link #protectionLevel}, corresponding
125     * to the <code>instant</code> value of
126     * {@link android.R.attr#protectionLevel}.
127     */
128    public static final int PROTECTION_FLAG_INSTANT = 0x1000;
129
130    /**
131     * Additional flag for {@link #protectionLevel}, corresponding
132     * to the <code>runtime</code> value of
133     * {@link android.R.attr#protectionLevel}.
134     */
135    public static final int PROTECTION_FLAG_RUNTIME_ONLY = 0x2000;
136
137    /**
138     * Mask for {@link #protectionLevel}: the basic protection type.
139     */
140    public static final int PROTECTION_MASK_BASE = 0xf;
141
142    /**
143     * Mask for {@link #protectionLevel}: additional flag bits.
144     */
145    public static final int PROTECTION_MASK_FLAGS = 0xfff0;
146
147    /**
148     * The level of access this permission is protecting, as per
149     * {@link android.R.attr#protectionLevel}.  Values may be
150     * {@link #PROTECTION_NORMAL}, {@link #PROTECTION_DANGEROUS}, or
151     * {@link #PROTECTION_SIGNATURE}.  May also include the additional
152     * flags {@link #PROTECTION_FLAG_SYSTEM} or {@link #PROTECTION_FLAG_DEVELOPMENT}
153     * (which only make sense in combination with the base
154     * {@link #PROTECTION_SIGNATURE}.
155     */
156    public int protectionLevel;
157
158    /**
159     * The group this permission is a part of, as per
160     * {@link android.R.attr#permissionGroup}.
161     */
162    public String group;
163
164    /**
165     * Flag for {@link #flags}, corresponding to <code>costsMoney</code>
166     * value of {@link android.R.attr#permissionFlags}.
167     */
168    public static final int FLAG_COSTS_MONEY = 1<<0;
169
170    /**
171     * Flag for {@link #flags}, corresponding to <code>removed</code>
172     * value of {@link android.R.attr#permissionFlags}.
173     * @hide
174     */
175    @SystemApi
176    public static final int FLAG_REMOVED = 1<<1;
177
178    /**
179     * Flag for {@link #flags}, indicating that this permission has been
180     * installed into the system's globally defined permissions.
181     */
182    public static final int FLAG_INSTALLED = 1<<30;
183
184    /**
185     * Additional flags about this permission as given by
186     * {@link android.R.attr#permissionFlags}.
187     */
188    public int flags;
189
190    /**
191     * A string resource identifier (in the package's resources) of this
192     * permission's description.  From the "description" attribute or,
193     * if not set, 0.
194     */
195    public int descriptionRes;
196
197    /**
198     * The description string provided in the AndroidManifest file, if any.  You
199     * probably don't want to use this, since it will be null if the description
200     * is in a resource.  You probably want
201     * {@link PermissionInfo#loadDescription} instead.
202     */
203    public CharSequence nonLocalizedDescription;
204
205    /** @hide */
206    public static int fixProtectionLevel(int level) {
207        if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
208            level = PROTECTION_SIGNATURE | PROTECTION_FLAG_PRIVILEGED;
209        }
210        return level;
211    }
212
213    /** @hide */
214    public static String protectionToString(int level) {
215        String protLevel = "????";
216        switch (level&PROTECTION_MASK_BASE) {
217            case PermissionInfo.PROTECTION_DANGEROUS:
218                protLevel = "dangerous";
219                break;
220            case PermissionInfo.PROTECTION_NORMAL:
221                protLevel = "normal";
222                break;
223            case PermissionInfo.PROTECTION_SIGNATURE:
224                protLevel = "signature";
225                break;
226            case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
227                protLevel = "signatureOrSystem";
228                break;
229        }
230        if ((level&PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
231            protLevel += "|privileged";
232        }
233        if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
234            protLevel += "|development";
235        }
236        if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
237            protLevel += "|appop";
238        }
239        if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) {
240            protLevel += "|pre23";
241        }
242        if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) {
243            protLevel += "|installer";
244        }
245        if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) {
246            protLevel += "|verifier";
247        }
248        if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) {
249            protLevel += "|preinstalled";
250        }
251        if ((level&PermissionInfo.PROTECTION_FLAG_SETUP) != 0) {
252            protLevel += "|setup";
253        }
254        if ((level&PermissionInfo.PROTECTION_FLAG_INSTANT) != 0) {
255            protLevel += "|instant";
256        }
257        if ((level&PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0) {
258            protLevel += "|runtime";
259        }
260        return protLevel;
261    }
262
263    public PermissionInfo() {
264    }
265
266    public PermissionInfo(PermissionInfo orig) {
267        super(orig);
268        protectionLevel = orig.protectionLevel;
269        flags = orig.flags;
270        group = orig.group;
271        descriptionRes = orig.descriptionRes;
272        nonLocalizedDescription = orig.nonLocalizedDescription;
273    }
274
275    /**
276     * Retrieve the textual description of this permission.  This
277     * will call back on the given PackageManager to load the description from
278     * the application.
279     *
280     * @param pm A PackageManager from which the label can be loaded; usually
281     * the PackageManager from which you originally retrieved this item.
282     *
283     * @return Returns a CharSequence containing the permission's description.
284     * If there is no description, null is returned.
285     */
286    public CharSequence loadDescription(PackageManager pm) {
287        if (nonLocalizedDescription != null) {
288            return nonLocalizedDescription;
289        }
290        if (descriptionRes != 0) {
291            CharSequence label = pm.getText(packageName, descriptionRes, null);
292            if (label != null) {
293                return label;
294            }
295        }
296        return null;
297    }
298
299    public String toString() {
300        return "PermissionInfo{"
301            + Integer.toHexString(System.identityHashCode(this))
302            + " " + name + "}";
303    }
304
305    public int describeContents() {
306        return 0;
307    }
308
309    public void writeToParcel(Parcel dest, int parcelableFlags) {
310        super.writeToParcel(dest, parcelableFlags);
311        dest.writeInt(protectionLevel);
312        dest.writeInt(flags);
313        dest.writeString(group);
314        dest.writeInt(descriptionRes);
315        TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
316    }
317
318    public static final Creator<PermissionInfo> CREATOR =
319        new Creator<PermissionInfo>() {
320        public PermissionInfo createFromParcel(Parcel source) {
321            return new PermissionInfo(source);
322        }
323        public PermissionInfo[] newArray(int size) {
324            return new PermissionInfo[size];
325        }
326    };
327
328    private PermissionInfo(Parcel source) {
329        super(source);
330        protectionLevel = source.readInt();
331        flags = source.readInt();
332        group = source.readString();
333        descriptionRes = source.readInt();
334        nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
335    }
336}
337