1 /*
2  * Copyright (C) 2017 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.NonNull;
20 import android.annotation.Nullable;
21 import android.util.ArrayMap;
22 import android.util.ArraySet;
23 import android.util.Log;
24 
25 import com.android.internal.annotations.GuardedBy;
26 import com.android.internal.util.XmlUtils;
27 import com.android.modules.utils.TypedXmlPullParser;
28 import com.android.modules.utils.TypedXmlSerializer;
29 import com.android.server.pm.DumpState;
30 import com.android.server.pm.PackageManagerService;
31 
32 import org.xmlpull.v1.XmlPullParser;
33 import org.xmlpull.v1.XmlPullParserException;
34 import org.xmlpull.v1.XmlSerializer;
35 
36 import java.io.IOException;
37 import java.io.PrintWriter;
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Set;
42 
43 /**
44  * Legacy permission settings for migration.
45  */
46 public class LegacyPermissionSettings {
47     /**
48      * All of the permissions known to the system. The mapping is from permission
49      * name to permission object.
50      */
51     @GuardedBy("mLock")
52     private final ArrayMap<String, LegacyPermission> mPermissions = new ArrayMap<>();
53 
54     /**
55      * All permission trees known to the system. The mapping is from permission tree
56      * name to permission object.
57      */
58     @GuardedBy("mLock")
59     private final ArrayMap<String, LegacyPermission> mPermissionTrees = new ArrayMap<>();
60 
61     @NonNull
62     private final Object mLock;
63 
LegacyPermissionSettings(@onNull Object lock)64     public LegacyPermissionSettings(@NonNull Object lock) {
65         mLock = lock;
66     }
67 
68     @NonNull
getPermissions()69     public List<LegacyPermission> getPermissions() {
70         synchronized (mLock) {
71             return new ArrayList<>(mPermissions.values());
72         }
73     }
74 
75     @NonNull
getPermissionTrees()76     public List<LegacyPermission> getPermissionTrees() {
77         synchronized (mLock) {
78             return new ArrayList<>(mPermissionTrees.values());
79         }
80     }
81 
replacePermissions(@onNull List<LegacyPermission> permissions)82     public void replacePermissions(@NonNull List<LegacyPermission> permissions) {
83         synchronized (mLock) {
84             mPermissions.clear();
85             final int permissionsSize = permissions.size();
86             for (int i = 0; i < permissionsSize; i++) {
87                 final LegacyPermission permission = permissions.get(i);
88                 mPermissions.put(permission.getPermissionInfo().name, permission);
89             }
90         }
91     }
92 
replacePermissionTrees(@onNull List<LegacyPermission> permissionTrees)93     public void replacePermissionTrees(@NonNull List<LegacyPermission> permissionTrees) {
94         synchronized (mLock) {
95             mPermissionTrees.clear();
96             final int permissionsSize = permissionTrees.size();
97             for (int i = 0; i < permissionsSize; i++) {
98                 final LegacyPermission permissionTree = permissionTrees.get(i);
99                 mPermissionTrees.put(permissionTree.getPermissionInfo().name, permissionTree);
100             }
101         }
102     }
103 
readPermissions(@onNull TypedXmlPullParser parser)104     public void readPermissions(@NonNull TypedXmlPullParser parser) throws IOException,
105             XmlPullParserException {
106         synchronized (mLock) {
107             readPermissions(mPermissions, parser);
108         }
109     }
110 
readPermissionTrees(@onNull TypedXmlPullParser parser)111     public void readPermissionTrees(@NonNull TypedXmlPullParser parser) throws IOException,
112             XmlPullParserException {
113         synchronized (mLock) {
114             readPermissions(mPermissionTrees, parser);
115         }
116     }
117 
readPermissions(@onNull ArrayMap<String, LegacyPermission> out, @NonNull TypedXmlPullParser parser)118     public static void readPermissions(@NonNull ArrayMap<String, LegacyPermission> out,
119             @NonNull TypedXmlPullParser parser) throws IOException, XmlPullParserException {
120         int outerDepth = parser.getDepth();
121         int type;
122         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
123                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
124             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
125                 continue;
126             }
127 
128             if (!LegacyPermission.read(out, parser)) {
129                 PackageManagerService.reportSettingsProblem(Log.WARN,
130                         "Unknown element reading permissions: " + parser.getName() + " at "
131                                 + parser.getPositionDescription());
132             }
133             XmlUtils.skipCurrentTag(parser);
134         }
135     }
136 
writePermissions(@onNull TypedXmlSerializer serializer)137     public void writePermissions(@NonNull TypedXmlSerializer serializer) throws IOException {
138         synchronized (mLock) {
139             for (LegacyPermission bp : mPermissions.values()) {
140                 bp.write(serializer);
141             }
142         }
143     }
144 
writePermissionTrees(@onNull TypedXmlSerializer serializer)145     public void writePermissionTrees(@NonNull TypedXmlSerializer serializer) throws IOException {
146         synchronized (mLock) {
147             for (LegacyPermission bp : mPermissionTrees.values()) {
148                 bp.write(serializer);
149             }
150         }
151     }
152 
dumpPermissions(@onNull PrintWriter pw, @Nullable String packageName, @Nullable ArraySet<String> permissionNames, @NonNull List<LegacyPermission> permissions, @NonNull Map<String, Set<String>> appOpPermissionPackages, boolean externalStorageEnforced, @NonNull DumpState dumpState)153     public static void dumpPermissions(@NonNull PrintWriter pw, @Nullable String packageName,
154             @Nullable ArraySet<String> permissionNames, @NonNull List<LegacyPermission> permissions,
155             @NonNull Map<String, Set<String>> appOpPermissionPackages,
156             boolean externalStorageEnforced, @NonNull DumpState dumpState) {
157         boolean printedSomething = false;
158         final int permissionsSize = permissions.size();
159         for (int i = 0; i < permissionsSize; i++) {
160             final LegacyPermission permission = permissions.get(i);
161             printedSomething = permission.dump(pw, packageName, permissionNames,
162                     externalStorageEnforced, printedSomething, dumpState);
163         }
164         if (packageName == null && permissionNames == null) {
165             boolean firstEntry = true;
166             for (final Map.Entry<String, Set<String>> entry : appOpPermissionPackages.entrySet()) {
167                 if (firstEntry) {
168                     firstEntry = false;
169                     if (dumpState.onTitlePrinted()) {
170                         pw.println();
171                     }
172                     pw.println("AppOp Permissions:");
173                 }
174                 pw.print("  AppOp Permission ");
175                 pw.print(entry.getKey());
176                 pw.println(":");
177                 for (final String appOpPackageName : entry.getValue()) {
178                     pw.print("    ");
179                     pw.println(appOpPackageName);
180                 }
181             }
182         }
183     }
184 }
185