• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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 com.android.server.pm.permission;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.content.pm.PermissionInfo;
23 import android.util.Log;
24 
25 import com.android.modules.utils.TypedXmlPullParser;
26 import com.android.modules.utils.TypedXmlSerializer;
27 import com.android.server.pm.DumpState;
28 import com.android.server.pm.PackageManagerService;
29 
30 import libcore.util.EmptyArray;
31 
32 import java.io.IOException;
33 import java.io.PrintWriter;
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.util.Arrays;
37 import java.util.Map;
38 import java.util.Objects;
39 import java.util.Set;
40 
41 /**
42  * Legacy permission definition.
43  */
44 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
45 public final class LegacyPermission {
46     /**
47      * The permission is defined in a manifest.
48      */
49     public static final int TYPE_MANIFEST = 0;
50 
51     /**
52      * The permission is defined in a system config.
53      */
54     public static final int TYPE_CONFIG = 1;
55 
56     /**
57      * The permission is defined dynamically.
58      */
59     public static final int TYPE_DYNAMIC = 2;
60 
61     /**
62      * @hide
63      */
64     @IntDef({
65             TYPE_MANIFEST,
66             TYPE_CONFIG,
67             TYPE_DYNAMIC,
68     })
69     @Retention(RetentionPolicy.SOURCE)
70     public @interface PermissionType {}
71 
72     private static final String ATTR_NAME = "name";
73     private static final String ATTR_PACKAGE = "package";
74     private static final String TAG_ITEM = "item";
75 
76     @NonNull
77     private final PermissionInfo mPermissionInfo;
78     @PermissionType
79     private final int mType;
80     private final int mUid;
81     @NonNull
82     private final int[] mGids;
83 
84     /**
85      * Create a new instance of this class.
86      *
87      * @param permissionInfo the {@link PermissionInfo} for the permission
88      * @param type the type of the permission
89      * @param uid the UID defining the permission
90      * @param gids the GIDs associated with the permission
91      */
LegacyPermission(@onNull PermissionInfo permissionInfo, @PermissionType int type, int uid, @NonNull int[] gids)92     public LegacyPermission(@NonNull PermissionInfo permissionInfo, @PermissionType int type,
93             int uid, @NonNull int[] gids) {
94         mPermissionInfo = permissionInfo;
95         mType = type;
96         mUid = uid;
97         mGids = gids;
98     }
99 
LegacyPermission(@onNull String name, @NonNull String packageName, @PermissionType int type)100     private LegacyPermission(@NonNull String name, @NonNull String packageName,
101             @PermissionType int type) {
102         mPermissionInfo = new PermissionInfo();
103         mPermissionInfo.name = name;
104         mPermissionInfo.packageName = packageName;
105         // Default to most conservative protection level.
106         mPermissionInfo.protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
107         mType = type;
108         mUid = 0;
109         mGids = EmptyArray.INT;
110     }
111 
112     /**
113      * Get the {@link PermissionInfo} for this mission.
114      *
115      * @return the {@link PermissionInfo}
116      */
117     @NonNull
getPermissionInfo()118     public PermissionInfo getPermissionInfo() {
119         return mPermissionInfo;
120     }
121 
122     /**
123      * Get the type of this mission.
124      *
125      * @return the type
126      */
getType()127     public int getType() {
128         return mType;
129     }
130 
131     /**
132      * @hide
133      */
read(@onNull Map<String, LegacyPermission> out, @NonNull TypedXmlPullParser parser)134     public static boolean read(@NonNull Map<String, LegacyPermission> out,
135             @NonNull TypedXmlPullParser parser) {
136         final String tagName = parser.getName();
137         if (!tagName.equals(TAG_ITEM)) {
138             return false;
139         }
140         final String name = parser.getAttributeValue(null, ATTR_NAME);
141         final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
142         final String ptype = parser.getAttributeValue(null, "type");
143         if (name == null || packageName == null) {
144             PackageManagerService.reportSettingsProblem(Log.WARN,
145                     "Error in package manager settings: permissions has" + " no name at "
146                             + parser.getPositionDescription());
147             return false;
148         }
149         final boolean dynamic = "dynamic".equals(ptype);
150         LegacyPermission bp = out.get(name);
151         // If the permission is builtin, do not clobber it.
152         if (bp == null || bp.mType != TYPE_CONFIG) {
153             bp = new LegacyPermission(name.intern(), packageName,
154                     dynamic ? TYPE_DYNAMIC : TYPE_MANIFEST);
155         }
156         bp.mPermissionInfo.protectionLevel = readInt(parser, null, "protection",
157                 PermissionInfo.PROTECTION_NORMAL);
158         bp.mPermissionInfo.protectionLevel = PermissionInfo.fixProtectionLevel(
159                 bp.mPermissionInfo.protectionLevel);
160         if (dynamic) {
161             bp.mPermissionInfo.icon = readInt(parser, null, "icon", 0);
162             bp.mPermissionInfo.nonLocalizedLabel = parser.getAttributeValue(null, "label");
163         }
164         out.put(bp.mPermissionInfo.name, bp);
165         return true;
166     }
167 
readInt(@onNull TypedXmlPullParser parser, @Nullable String namespace, @NonNull String name, int defaultValue)168     private static int readInt(@NonNull TypedXmlPullParser parser, @Nullable String namespace,
169             @NonNull String name, int defaultValue) {
170         return parser.getAttributeInt(namespace, name, defaultValue);
171     }
172 
173     /**
174      * @hide
175      */
write(@onNull TypedXmlSerializer serializer)176     public void write(@NonNull TypedXmlSerializer serializer) throws IOException {
177         if (mPermissionInfo.packageName == null) {
178             return;
179         }
180         serializer.startTag(null, TAG_ITEM);
181         serializer.attribute(null, ATTR_NAME, mPermissionInfo.name);
182         serializer.attribute(null, ATTR_PACKAGE, mPermissionInfo.packageName);
183         if (mPermissionInfo.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
184             serializer.attributeInt(null, "protection", mPermissionInfo.protectionLevel);
185         }
186         if (mType == TYPE_DYNAMIC) {
187             serializer.attribute(null, "type", "dynamic");
188             if (mPermissionInfo.icon != 0) {
189                 serializer.attributeInt(null, "icon", mPermissionInfo.icon);
190             }
191             if (mPermissionInfo.nonLocalizedLabel != null) {
192                 serializer.attribute(null, "label", mPermissionInfo.nonLocalizedLabel.toString());
193             }
194         }
195         serializer.endTag(null, TAG_ITEM);
196     }
197 
198     /**
199      * @hide
200      */
dump(@onNull PrintWriter pw, @NonNull String packageName, @NonNull Set<String> permissionNames, boolean readEnforced, boolean printedSomething, @NonNull DumpState dumpState)201     public boolean dump(@NonNull PrintWriter pw, @NonNull String packageName,
202             @NonNull Set<String> permissionNames, boolean readEnforced, boolean printedSomething,
203             @NonNull DumpState dumpState) {
204         if (packageName != null && !packageName.equals(mPermissionInfo.packageName)) {
205             return false;
206         }
207         if (permissionNames != null && !permissionNames.contains(mPermissionInfo.name)) {
208             return false;
209         }
210         if (!printedSomething) {
211             if (dumpState.onTitlePrinted()) {
212                 pw.println();
213             }
214             pw.println("Permissions:");
215         }
216         pw.print("  Permission ["); pw.print(mPermissionInfo.name); pw.print("] (");
217         pw.print(Integer.toHexString(System.identityHashCode(this)));
218         pw.println("):");
219         pw.print("    sourcePackage="); pw.println(mPermissionInfo.packageName);
220         pw.print("    uid="); pw.print(mUid);
221         pw.print(" gids="); pw.print(Arrays.toString(mGids));
222         pw.print(" type="); pw.print(mType);
223         pw.print(" prot=");
224         pw.println(PermissionInfo.protectionToString(mPermissionInfo.protectionLevel));
225         if (mPermissionInfo != null) {
226             pw.print("    perm="); pw.println(mPermissionInfo);
227             if ((mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0
228                     || (mPermissionInfo.flags & PermissionInfo.FLAG_REMOVED) != 0) {
229                 pw.print("    flags=0x"); pw.println(Integer.toHexString(mPermissionInfo.flags));
230             }
231         }
232         if (Objects.equals(mPermissionInfo.name,
233                 android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
234             pw.print("    enforced=");
235             pw.println(readEnforced);
236         }
237         return true;
238     }
239 }
240