blob: c5be8e4a3aba6aa157a8b45df6d5a38c2a2cfa47 [file] [log] [blame]
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001/*
2 * Copyright (C) 2014 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 com.android.server;
18
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070019import static com.android.internal.util.ArrayUtils.appendInt;
20
Dianne Hackbornc0e4aaa2014-11-14 10:55:50 -080021import android.app.ActivityManager;
Ruben Brunk98576cf2016-03-07 18:54:28 -080022import android.content.ComponentName;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070023import android.content.pm.FeatureInfo;
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070024import android.content.pm.PackageManager;
Jiyong Parkfad99442018-03-12 10:39:07 +090025import android.os.Build;
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070026import android.os.Environment;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070027import android.os.Process;
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070028import android.os.storage.StorageManager;
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -080029import android.text.TextUtils;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070030import android.util.ArrayMap;
31import android.util.ArraySet;
32import android.util.Slog;
33import android.util.SparseArray;
34import android.util.Xml;
Jeff Sharkey1c4ae802014-12-19 11:08:55 -080035
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070036import com.android.internal.util.XmlUtils;
Jeff Sharkey1c4ae802014-12-19 11:08:55 -080037
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070038import libcore.io.IoUtils;
39
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070040import org.xmlpull.v1.XmlPullParser;
41import org.xmlpull.v1.XmlPullParserException;
42
43import java.io.File;
44import java.io.FileNotFoundException;
45import java.io.FileReader;
46import java.io.IOException;
Jeff Davidson24b9d962016-07-21 12:35:10 -070047import java.util.ArrayList;
Svet Ganov087dce22017-09-07 15:42:16 -070048import java.util.Collections;
Jeff Davidson24b9d962016-07-21 12:35:10 -070049import java.util.List;
Svet Ganov087dce22017-09-07 15:42:16 -070050import java.util.Map;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070051
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070052/**
53 * Loads global system configuration info.
54 */
55public class SystemConfig {
56 static final String TAG = "SystemConfig";
57
58 static SystemConfig sInstance;
59
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +080060 // permission flag, determines which types of configuration are allowed to be read
61 private static final int ALLOW_FEATURES = 0x01;
62 private static final int ALLOW_LIBS = 0x02;
63 private static final int ALLOW_PERMISSIONS = 0x04;
64 private static final int ALLOW_APP_CONFIGS = 0x08;
Jaekyun Seoke3b6bf12017-02-16 13:48:30 +090065 private static final int ALLOW_PRIVAPP_PERMISSIONS = 0x10;
Svet Ganov087dce22017-09-07 15:42:16 -070066 private static final int ALLOW_OEM_PERMISSIONS = 0x20;
Mathew Inwood4693a752018-02-20 16:04:25 +000067 private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x40;
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +080068 private static final int ALLOW_ALL = ~0;
69
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070070 // Group-ids that are given to all packages as read from etc/permissions/*.xml.
71 int[] mGlobalGids;
72
73 // These are the built-in uid -> permission mappings that were read from the
74 // system configuration files.
Jeff Sharkey9f837a92014-10-24 12:07:24 -070075 final SparseArray<ArraySet<String>> mSystemPermissions = new SparseArray<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070076
77 // These are the built-in shared libraries that were read from the
78 // system configuration files. Keys are the library names; strings are the
79 // paths to the libraries.
Dianne Hackbornbb8aa5a2014-09-17 13:20:38 -070080 final ArrayMap<String, String> mSharedLibraries = new ArrayMap<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070081
82 // These are the features this devices supports that were read from the
83 // system configuration files.
Jeff Sharkey9f837a92014-10-24 12:07:24 -070084 final ArrayMap<String, FeatureInfo> mAvailableFeatures = new ArrayMap<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070085
Jeff Sharkey1c4ae802014-12-19 11:08:55 -080086 // These are the features which this device doesn't support; the OEM
87 // partition uses these to opt-out of features from the system image.
88 final ArraySet<String> mUnavailableFeatures = new ArraySet<>();
89
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070090 public static final class PermissionEntry {
91 public final String name;
92 public int[] gids;
Jeff Sharkey00f39042015-03-23 16:51:22 -070093 public boolean perUser;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070094
Jeff Sharkey00f39042015-03-23 16:51:22 -070095 PermissionEntry(String name, boolean perUser) {
96 this.name = name;
97 this.perUser = perUser;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070098 }
99 }
100
101 // These are the permission -> gid mappings that were read from the
102 // system configuration files.
Dianne Hackbornbb8aa5a2014-09-17 13:20:38 -0700103 final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700104
105 // These are the packages that are white-listed to be able to run in the
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700106 // background while in power save mode (but not whitelisted from device idle modes),
107 // as read from the configuration files.
108 final ArraySet<String> mAllowInPowerSaveExceptIdle = new ArraySet<>();
109
110 // These are the packages that are white-listed to be able to run in the
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700111 // background while in power save mode, as read from the configuration files.
Dianne Hackbornbb8aa5a2014-09-17 13:20:38 -0700112 final ArraySet<String> mAllowInPowerSave = new ArraySet<>();
113
Felipe Lemea9505cc2016-02-26 10:28:41 -0800114 // These are the packages that are white-listed to be able to run in the
115 // background while in data-usage save mode, as read from the configuration files.
116 final ArraySet<String> mAllowInDataUsageSave = new ArraySet<>();
117
Soonil Nagarkar2b565df2017-02-14 13:33:23 -0800118 // These are the packages that are white-listed to be able to run background location
119 // without throttling, as read from the configuration files.
120 final ArraySet<String> mAllowUnthrottledLocation = new ArraySet<>();
121
Christopher Tate42a386b2016-11-07 12:21:21 -0800122 // These are the action strings of broadcasts which are whitelisted to
123 // be delivered anonymously even to apps which target O+.
124 final ArraySet<String> mAllowImplicitBroadcasts = new ArraySet<>();
125
Christopher Tate01e18642015-07-07 18:10:38 -0700126 // These are the package names of apps which should be in the 'always'
127 // URL-handling state upon factory reset.
128 final ArraySet<String> mLinkedApps = new ArraySet<>();
129
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700130 // These are the packages that are whitelisted to be able to run as system user
131 final ArraySet<String> mSystemUserWhitelistedApps = new ArraySet<>();
132
133 // These are the packages that should not run under system user
134 final ArraySet<String> mSystemUserBlacklistedApps = new ArraySet<>();
135
Ruben Brunk98576cf2016-03-07 18:54:28 -0800136 // These are the components that are enabled by default as VR mode listener services.
137 final ArraySet<ComponentName> mDefaultVrComponents = new ArraySet<>();
138
Christopher Tate494df792016-05-10 17:05:38 -0700139 // These are the permitted backup transport service components
140 final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();
141
Mathew Inwood4693a752018-02-20 16:04:25 +0000142 // Package names that are exempted from private API blacklisting
143 final ArraySet<String> mHiddenApiPackageWhitelist = new ArraySet<>();
144
goneil18928e92018-02-28 15:22:08 -0800145 // The list of carrier applications which should be disabled until used.
146 // This function suppresses update notifications for these pre-installed apps.
147 // In SubscriptionInfoUpdater, the listed applications are disabled until used when all of the
148 // following conditions are met.
149 // 1. Not currently carrier-privileged according to the inserted SIM
150 // 2. Pre-installed
151 // 3. In the default state (enabled but not explicitly)
152 // And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted
153 // that marks the app as carrier privileged. It also grants the app default permissions
154 // for Phone and Location. As such, apps MUST only ever be added to this list if they
155 // obtain user consent to access their location through other means.
156 final ArraySet<String> mDisabledUntilUsedPreinstalledCarrierApps = new ArraySet<>();
157
Jeff Davidson24b9d962016-07-21 12:35:10 -0700158 // These are the packages of carrier-associated apps which should be disabled until used until
159 // a SIM is inserted which grants carrier privileges to that carrier app.
160 final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
161 new ArrayMap<>();
162
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800163 final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
Todd Kennedy74629e32017-08-15 14:48:07 -0700164 final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>();
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800165
Jiyong Park002fdbd2017-02-13 20:50:31 +0900166 final ArrayMap<String, ArraySet<String>> mVendorPrivAppPermissions = new ArrayMap<>();
167 final ArrayMap<String, ArraySet<String>> mVendorPrivAppDenyPermissions = new ArrayMap<>();
168
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900169 final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
170 final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
171
Svet Ganov087dce22017-09-07 15:42:16 -0700172 final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
173
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700174 public static SystemConfig getInstance() {
175 synchronized (SystemConfig.class) {
176 if (sInstance == null) {
177 sInstance = new SystemConfig();
178 }
179 return sInstance;
180 }
181 }
182
183 public int[] getGlobalGids() {
184 return mGlobalGids;
185 }
186
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700187 public SparseArray<ArraySet<String>> getSystemPermissions() {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700188 return mSystemPermissions;
189 }
190
191 public ArrayMap<String, String> getSharedLibraries() {
192 return mSharedLibraries;
193 }
194
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700195 public ArrayMap<String, FeatureInfo> getAvailableFeatures() {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700196 return mAvailableFeatures;
197 }
198
199 public ArrayMap<String, PermissionEntry> getPermissions() {
200 return mPermissions;
201 }
202
Christopher Tate42a386b2016-11-07 12:21:21 -0800203 public ArraySet<String> getAllowImplicitBroadcasts() {
204 return mAllowImplicitBroadcasts;
205 }
206
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700207 public ArraySet<String> getAllowInPowerSaveExceptIdle() {
208 return mAllowInPowerSaveExceptIdle;
209 }
210
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700211 public ArraySet<String> getAllowInPowerSave() {
212 return mAllowInPowerSave;
213 }
214
Felipe Lemea9505cc2016-02-26 10:28:41 -0800215 public ArraySet<String> getAllowInDataUsageSave() {
216 return mAllowInDataUsageSave;
217 }
218
Soonil Nagarkar2b565df2017-02-14 13:33:23 -0800219 public ArraySet<String> getAllowUnthrottledLocation() {
220 return mAllowUnthrottledLocation;
221 }
222
Christopher Tate01e18642015-07-07 18:10:38 -0700223 public ArraySet<String> getLinkedApps() {
224 return mLinkedApps;
225 }
226
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700227 public ArraySet<String> getSystemUserWhitelistedApps() {
228 return mSystemUserWhitelistedApps;
229 }
230
231 public ArraySet<String> getSystemUserBlacklistedApps() {
232 return mSystemUserBlacklistedApps;
233 }
234
Mathew Inwood4693a752018-02-20 16:04:25 +0000235 public ArraySet<String> getHiddenApiWhitelistedApps() {
236 return mHiddenApiPackageWhitelist;
237 }
238
Ruben Brunk98576cf2016-03-07 18:54:28 -0800239 public ArraySet<ComponentName> getDefaultVrComponents() {
240 return mDefaultVrComponents;
241 }
242
Christopher Tate494df792016-05-10 17:05:38 -0700243 public ArraySet<ComponentName> getBackupTransportWhitelist() {
244 return mBackupTransportWhitelist;
245 }
246
goneil18928e92018-02-28 15:22:08 -0800247 public ArraySet<String> getDisabledUntilUsedPreinstalledCarrierApps() {
248 return mDisabledUntilUsedPreinstalledCarrierApps;
249 }
250
Jeff Davidson24b9d962016-07-21 12:35:10 -0700251 public ArrayMap<String, List<String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
252 return mDisabledUntilUsedPreinstalledCarrierAssociatedApps;
253 }
254
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800255 public ArraySet<String> getPrivAppPermissions(String packageName) {
256 return mPrivAppPermissions.get(packageName);
257 }
258
Todd Kennedy74629e32017-08-15 14:48:07 -0700259 public ArraySet<String> getPrivAppDenyPermissions(String packageName) {
260 return mPrivAppDenyPermissions.get(packageName);
261 }
262
Jiyong Park002fdbd2017-02-13 20:50:31 +0900263 public ArraySet<String> getVendorPrivAppPermissions(String packageName) {
264 return mVendorPrivAppPermissions.get(packageName);
265 }
266
267 public ArraySet<String> getVendorPrivAppDenyPermissions(String packageName) {
268 return mVendorPrivAppDenyPermissions.get(packageName);
269 }
270
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900271 public ArraySet<String> getProductPrivAppPermissions(String packageName) {
272 return mProductPrivAppPermissions.get(packageName);
273 }
274
275 public ArraySet<String> getProductPrivAppDenyPermissions(String packageName) {
276 return mProductPrivAppDenyPermissions.get(packageName);
277 }
278
Svet Ganov087dce22017-09-07 15:42:16 -0700279 public Map<String, Boolean> getOemPermissions(String packageName) {
280 final Map<String, Boolean> oemPermissions = mOemPermissions.get(packageName);
281 if (oemPermissions != null) {
282 return oemPermissions;
283 }
284 return Collections.emptyMap();
285 }
286
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700287 SystemConfig() {
288 // Read configuration from system
289 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800290 Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
Svet Ganov087dce22017-09-07 15:42:16 -0700291
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700292 // Read configuration from the old permissions dir
293 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800294 Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
Svet Ganov087dce22017-09-07 15:42:16 -0700295
Jiyong Parkfad99442018-03-12 10:39:07 +0900296 // Vendors are only allowed to customze libs, features and privapp permissions
297 int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS;
298 if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
299 // For backward compatibility
300 vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
301 }
Jaekyun Seoke3b6bf12017-02-16 13:48:30 +0900302 readPermissions(Environment.buildPath(
303 Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
304 readPermissions(Environment.buildPath(
305 Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);
Svet Ganov087dce22017-09-07 15:42:16 -0700306
Jiyong Park090c6b12017-12-28 12:03:28 +0900307 // Allow ODM to customize system configs as much as Vendor, because /odm is another
308 // vendor partition other than /vendor.
309 int odmPermissionFlag = vendorPermissionFlag;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700310 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800311 Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700312 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800313 Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
Svet Ganov087dce22017-09-07 15:42:16 -0700314
315 // Allow OEM to customize features and OEM permissions
316 int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS;
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800317 readPermissions(Environment.buildPath(
Svet Ganov087dce22017-09-07 15:42:16 -0700318 Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800319 readPermissions(Environment.buildPath(
Svet Ganov087dce22017-09-07 15:42:16 -0700320 Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900321
322 // Allow Product to customize system configs around libs, features, permissions and apps
323 int productPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
324 ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
325 readPermissions(Environment.buildPath(
326 Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
327 readPermissions(Environment.buildPath(
328 Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700329 }
330
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800331 void readPermissions(File libraryDir, int permissionFlag) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700332 // Read permissions from given directory.
333 if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800334 if (permissionFlag == ALLOW_ALL) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700335 Slog.w(TAG, "No directory " + libraryDir + ", skipping");
336 }
337 return;
338 }
339 if (!libraryDir.canRead()) {
340 Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
341 return;
342 }
343
344 // Iterate over the files in the directory and scan .xml files
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800345 File platformFile = null;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700346 for (File f : libraryDir.listFiles()) {
347 // We'll read platform.xml last
348 if (f.getPath().endsWith("etc/permissions/platform.xml")) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800349 platformFile = f;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700350 continue;
351 }
352
353 if (!f.getPath().endsWith(".xml")) {
354 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
355 continue;
356 }
357 if (!f.canRead()) {
358 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
359 continue;
360 }
361
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800362 readPermissionsFromXml(f, permissionFlag);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700363 }
364
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800365 // Read platform permissions last so it will take precedence
366 if (platformFile != null) {
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800367 readPermissionsFromXml(platformFile, permissionFlag);
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800368 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700369 }
370
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800371 private void readPermissionsFromXml(File permFile, int permissionFlag) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700372 FileReader permReader = null;
373 try {
374 permReader = new FileReader(permFile);
375 } catch (FileNotFoundException e) {
376 Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
377 return;
378 }
379
Dianne Hackbornc0e4aaa2014-11-14 10:55:50 -0800380 final boolean lowRam = ActivityManager.isLowRamDeviceStatic();
381
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700382 try {
383 XmlPullParser parser = Xml.newPullParser();
384 parser.setInput(permReader);
385
386 int type;
387 while ((type=parser.next()) != parser.START_TAG
388 && type != parser.END_DOCUMENT) {
389 ;
390 }
391
392 if (type != parser.START_TAG) {
393 throw new XmlPullParserException("No start tag found");
394 }
395
396 if (!parser.getName().equals("permissions") && !parser.getName().equals("config")) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800397 throw new XmlPullParserException("Unexpected start tag in " + permFile
398 + ": found " + parser.getName() + ", expected 'permissions' or 'config'");
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700399 }
400
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800401 boolean allowAll = permissionFlag == ALLOW_ALL;
402 boolean allowLibs = (permissionFlag & ALLOW_LIBS) != 0;
403 boolean allowFeatures = (permissionFlag & ALLOW_FEATURES) != 0;
404 boolean allowPermissions = (permissionFlag & ALLOW_PERMISSIONS) != 0;
405 boolean allowAppConfigs = (permissionFlag & ALLOW_APP_CONFIGS) != 0;
Jaekyun Seoke3b6bf12017-02-16 13:48:30 +0900406 boolean allowPrivappPermissions = (permissionFlag & ALLOW_PRIVAPP_PERMISSIONS) != 0;
Svet Ganov087dce22017-09-07 15:42:16 -0700407 boolean allowOemPermissions = (permissionFlag & ALLOW_OEM_PERMISSIONS) != 0;
Mathew Inwood4693a752018-02-20 16:04:25 +0000408 boolean allowApiWhitelisting = (permissionFlag & ALLOW_HIDDENAPI_WHITELISTING) != 0;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700409 while (true) {
410 XmlUtils.nextElement(parser);
411 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
412 break;
413 }
414
415 String name = parser.getName();
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800416 if ("group".equals(name) && allowAll) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700417 String gidStr = parser.getAttributeValue(null, "gid");
418 if (gidStr != null) {
419 int gid = android.os.Process.getGidForName(gidStr);
420 mGlobalGids = appendInt(mGlobalGids, gid);
421 } else {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800422 Slog.w(TAG, "<group> without gid in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700423 + parser.getPositionDescription());
424 }
425
426 XmlUtils.skipCurrentTag(parser);
427 continue;
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800428 } else if ("permission".equals(name) && allowPermissions) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700429 String perm = parser.getAttributeValue(null, "name");
430 if (perm == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800431 Slog.w(TAG, "<permission> without name in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700432 + parser.getPositionDescription());
433 XmlUtils.skipCurrentTag(parser);
434 continue;
435 }
436 perm = perm.intern();
437 readPermission(parser, perm);
438
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800439 } else if ("assign-permission".equals(name) && allowPermissions) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700440 String perm = parser.getAttributeValue(null, "name");
441 if (perm == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800442 Slog.w(TAG, "<assign-permission> without name in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700443 + parser.getPositionDescription());
444 XmlUtils.skipCurrentTag(parser);
445 continue;
446 }
447 String uidStr = parser.getAttributeValue(null, "uid");
448 if (uidStr == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800449 Slog.w(TAG, "<assign-permission> without uid in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700450 + parser.getPositionDescription());
451 XmlUtils.skipCurrentTag(parser);
452 continue;
453 }
454 int uid = Process.getUidForName(uidStr);
455 if (uid < 0) {
456 Slog.w(TAG, "<assign-permission> with unknown uid \""
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800457 + uidStr + " in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700458 + parser.getPositionDescription());
459 XmlUtils.skipCurrentTag(parser);
460 continue;
461 }
462 perm = perm.intern();
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700463 ArraySet<String> perms = mSystemPermissions.get(uid);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700464 if (perms == null) {
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700465 perms = new ArraySet<String>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700466 mSystemPermissions.put(uid, perms);
467 }
468 perms.add(perm);
469 XmlUtils.skipCurrentTag(parser);
470
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800471 } else if ("library".equals(name) && allowLibs) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700472 String lname = parser.getAttributeValue(null, "name");
473 String lfile = parser.getAttributeValue(null, "file");
474 if (lname == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800475 Slog.w(TAG, "<library> without name in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700476 + parser.getPositionDescription());
477 } else if (lfile == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800478 Slog.w(TAG, "<library> without file in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700479 + parser.getPositionDescription());
480 } else {
481 //Log.i(TAG, "Got library " + lname + " in " + lfile);
482 mSharedLibraries.put(lname, lfile);
483 }
484 XmlUtils.skipCurrentTag(parser);
485 continue;
486
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800487 } else if ("feature".equals(name) && allowFeatures) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700488 String fname = parser.getAttributeValue(null, "name");
Arunesh Mishra4e0bdf32016-02-15 23:50:38 -0800489 int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
Dianne Hackbornc0e4aaa2014-11-14 10:55:50 -0800490 boolean allowed;
491 if (!lowRam) {
492 allowed = true;
493 } else {
494 String notLowRam = parser.getAttributeValue(null, "notLowRam");
495 allowed = !"true".equals(notLowRam);
496 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700497 if (fname == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800498 Slog.w(TAG, "<feature> without name in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700499 + parser.getPositionDescription());
Dianne Hackbornc0e4aaa2014-11-14 10:55:50 -0800500 } else if (allowed) {
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700501 addFeature(fname, fversion);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700502 }
503 XmlUtils.skipCurrentTag(parser);
504 continue;
505
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800506 } else if ("unavailable-feature".equals(name) && allowFeatures) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800507 String fname = parser.getAttributeValue(null, "name");
508 if (fname == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800509 Slog.w(TAG, "<unavailable-feature> without name in " + permFile + " at "
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800510 + parser.getPositionDescription());
511 } else {
512 mUnavailableFeatures.add(fname);
513 }
514 XmlUtils.skipCurrentTag(parser);
515 continue;
516
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800517 } else if ("allow-in-power-save-except-idle".equals(name) && allowAll) {
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700518 String pkgname = parser.getAttributeValue(null, "package");
519 if (pkgname == null) {
520 Slog.w(TAG, "<allow-in-power-save-except-idle> without package in "
521 + permFile + " at " + parser.getPositionDescription());
522 } else {
523 mAllowInPowerSaveExceptIdle.add(pkgname);
524 }
525 XmlUtils.skipCurrentTag(parser);
526 continue;
527
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800528 } else if ("allow-in-power-save".equals(name) && allowAll) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700529 String pkgname = parser.getAttributeValue(null, "package");
530 if (pkgname == null) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800531 Slog.w(TAG, "<allow-in-power-save> without package in " + permFile + " at "
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700532 + parser.getPositionDescription());
533 } else {
534 mAllowInPowerSave.add(pkgname);
535 }
536 XmlUtils.skipCurrentTag(parser);
537 continue;
538
Felipe Lemea9505cc2016-02-26 10:28:41 -0800539 } else if ("allow-in-data-usage-save".equals(name) && allowAll) {
540 String pkgname = parser.getAttributeValue(null, "package");
541 if (pkgname == null) {
542 Slog.w(TAG, "<allow-in-data-usage-save> without package in " + permFile
543 + " at " + parser.getPositionDescription());
544 } else {
545 mAllowInDataUsageSave.add(pkgname);
546 }
547 XmlUtils.skipCurrentTag(parser);
548 continue;
549
Soonil Nagarkar2b565df2017-02-14 13:33:23 -0800550 } else if ("allow-unthrottled-location".equals(name) && allowAll) {
551 String pkgname = parser.getAttributeValue(null, "package");
552 if (pkgname == null) {
553 Slog.w(TAG, "<allow-unthrottled-location> without package in "
554 + permFile + " at " + parser.getPositionDescription());
555 } else {
556 mAllowUnthrottledLocation.add(pkgname);
557 }
558 XmlUtils.skipCurrentTag(parser);
559 continue;
560
Christopher Tate42a386b2016-11-07 12:21:21 -0800561 } else if ("allow-implicit-broadcast".equals(name) && allowAll) {
562 String action = parser.getAttributeValue(null, "action");
563 if (action == null) {
564 Slog.w(TAG, "<allow-implicit-broadcast> without action in " + permFile
565 + " at " + parser.getPositionDescription());
566 } else {
567 mAllowImplicitBroadcasts.add(action);
568 }
569 XmlUtils.skipCurrentTag(parser);
570 continue;
571
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800572 } else if ("app-link".equals(name) && allowAppConfigs) {
Christopher Tate01e18642015-07-07 18:10:38 -0700573 String pkgname = parser.getAttributeValue(null, "package");
574 if (pkgname == null) {
575 Slog.w(TAG, "<app-link> without package in " + permFile + " at "
576 + parser.getPositionDescription());
577 } else {
578 mLinkedApps.add(pkgname);
579 }
580 XmlUtils.skipCurrentTag(parser);
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800581 } else if ("system-user-whitelisted-app".equals(name) && allowAppConfigs) {
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700582 String pkgname = parser.getAttributeValue(null, "package");
583 if (pkgname == null) {
584 Slog.w(TAG, "<system-user-whitelisted-app> without package in " + permFile
585 + " at " + parser.getPositionDescription());
586 } else {
587 mSystemUserWhitelistedApps.add(pkgname);
588 }
589 XmlUtils.skipCurrentTag(parser);
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800590 } else if ("system-user-blacklisted-app".equals(name) && allowAppConfigs) {
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700591 String pkgname = parser.getAttributeValue(null, "package");
592 if (pkgname == null) {
593 Slog.w(TAG, "<system-user-blacklisted-app without package in " + permFile
594 + " at " + parser.getPositionDescription());
595 } else {
596 mSystemUserBlacklistedApps.add(pkgname);
597 }
598 XmlUtils.skipCurrentTag(parser);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800599 } else if ("default-enabled-vr-app".equals(name) && allowAppConfigs) {
600 String pkgname = parser.getAttributeValue(null, "package");
601 String clsname = parser.getAttributeValue(null, "class");
602 if (pkgname == null) {
603 Slog.w(TAG, "<default-enabled-vr-app without package in " + permFile
604 + " at " + parser.getPositionDescription());
605 } else if (clsname == null) {
606 Slog.w(TAG, "<default-enabled-vr-app without class in " + permFile
607 + " at " + parser.getPositionDescription());
608 } else {
609 mDefaultVrComponents.add(new ComponentName(pkgname, clsname));
610 }
611 XmlUtils.skipCurrentTag(parser);
Christopher Tate494df792016-05-10 17:05:38 -0700612 } else if ("backup-transport-whitelisted-service".equals(name) && allowFeatures) {
613 String serviceName = parser.getAttributeValue(null, "service");
614 if (serviceName == null) {
615 Slog.w(TAG, "<backup-transport-whitelisted-service> without service in "
616 + permFile + " at " + parser.getPositionDescription());
617 } else {
618 ComponentName cn = ComponentName.unflattenFromString(serviceName);
619 if (cn == null) {
620 Slog.w(TAG,
621 "<backup-transport-whitelisted-service> with invalid service name "
622 + serviceName + " in "+ permFile
623 + " at " + parser.getPositionDescription());
624 } else {
625 mBackupTransportWhitelist.add(cn);
626 }
627 }
628 XmlUtils.skipCurrentTag(parser);
Jeff Davidson24b9d962016-07-21 12:35:10 -0700629 } else if ("disabled-until-used-preinstalled-carrier-associated-app".equals(name)
630 && allowAppConfigs) {
631 String pkgname = parser.getAttributeValue(null, "package");
632 String carrierPkgname = parser.getAttributeValue(null, "carrierAppPackage");
633 if (pkgname == null || carrierPkgname == null) {
634 Slog.w(TAG, "<disabled-until-used-preinstalled-carrier-associated-app"
635 + " without package or carrierAppPackage in " + permFile + " at "
636 + parser.getPositionDescription());
637 } else {
638 List<String> associatedPkgs =
639 mDisabledUntilUsedPreinstalledCarrierAssociatedApps.get(
640 carrierPkgname);
641 if (associatedPkgs == null) {
642 associatedPkgs = new ArrayList<>();
643 mDisabledUntilUsedPreinstalledCarrierAssociatedApps.put(
644 carrierPkgname, associatedPkgs);
645 }
646 associatedPkgs.add(pkgname);
647 }
648 XmlUtils.skipCurrentTag(parser);
goneil18928e92018-02-28 15:22:08 -0800649 } else if ("disabled-until-used-preinstalled-carrier-app".equals(name)
650 && allowAppConfigs) {
651 String pkgname = parser.getAttributeValue(null, "package");
652 if (pkgname == null) {
653 Slog.w(TAG,
654 "<disabled-until-used-preinstalled-carrier-app> without "
655 + "package in " + permFile + " at "
656 + parser.getPositionDescription());
657 } else {
658 mDisabledUntilUsedPreinstalledCarrierApps.add(pkgname);
659 }
660 XmlUtils.skipCurrentTag(parser);
Jaekyun Seoke3b6bf12017-02-16 13:48:30 +0900661 } else if ("privapp-permissions".equals(name) && allowPrivappPermissions) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900662 // privapp permissions from system, vendor and product partitions are stored
Jiyong Park002fdbd2017-02-13 20:50:31 +0900663 // separately. This is to prevent xml files in the vendor partition from
664 // granting permissions to priv apps in the system partition and vice
665 // versa.
666 boolean vendor = permFile.toPath().startsWith(
Jiyong Park090c6b12017-12-28 12:03:28 +0900667 Environment.getVendorDirectory().toPath())
668 || permFile.toPath().startsWith(
669 Environment.getOdmDirectory().toPath());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900670 boolean product = permFile.toPath().startsWith(
671 Environment.getProductDirectory().toPath());
Jiyong Park002fdbd2017-02-13 20:50:31 +0900672 if (vendor) {
673 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
674 mVendorPrivAppDenyPermissions);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900675 } else if (product) {
676 readPrivAppPermissions(parser, mProductPrivAppPermissions,
677 mProductPrivAppDenyPermissions);
Jiyong Park002fdbd2017-02-13 20:50:31 +0900678 } else {
679 readPrivAppPermissions(parser, mPrivAppPermissions,
680 mPrivAppDenyPermissions);
681 }
Svet Ganov087dce22017-09-07 15:42:16 -0700682 } else if ("oem-permissions".equals(name) && allowOemPermissions) {
683 readOemPermissions(parser);
Mathew Inwood4693a752018-02-20 16:04:25 +0000684 } else if ("hidden-api-whitelisted-app".equals(name) && allowApiWhitelisting) {
685 String pkgname = parser.getAttributeValue(null, "package");
686 if (pkgname == null) {
687 Slog.w(TAG, "<hidden-api-whitelisted-app> without package in " + permFile
688 + " at " + parser.getPositionDescription());
689 } else {
690 mHiddenApiPackageWhitelist.add(pkgname);
691 }
692 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700693 } else {
Jiyong Parkfad99442018-03-12 10:39:07 +0900694 Slog.w(TAG, "Tag " + name + " is unknown or not allowed in "
695 + permFile.getParent());
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700696 XmlUtils.skipCurrentTag(parser);
697 continue;
698 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700699 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700700 } catch (XmlPullParserException e) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800701 Slog.w(TAG, "Got exception parsing permissions.", e);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700702 } catch (IOException e) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800703 Slog.w(TAG, "Got exception parsing permissions.", e);
704 } finally {
705 IoUtils.closeQuietly(permReader);
706 }
707
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -0700708 // Some devices can be field-converted to FBE, so offer to splice in
709 // those features if not already defined by the static config
Paul Lawrence20be5d62016-02-26 13:51:17 -0800710 if (StorageManager.isFileEncryptedNativeOnly()) {
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700711 addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
712 addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -0700713 }
714
Jeff Sharkey8eb783b2018-01-04 16:46:48 -0700715 // Help legacy devices that may not have updated their static config
716 if (StorageManager.hasAdoptable()) {
717 addFeature(PackageManager.FEATURE_ADOPTABLE_STORAGE, 0);
718 }
719
Dianne Hackborn2a103f12017-08-08 15:50:31 -0700720 if (ActivityManager.isLowRamDeviceStatic()) {
721 addFeature(PackageManager.FEATURE_RAM_LOW, 0);
722 } else {
723 addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
724 }
725
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -0700726 for (String featureName : mUnavailableFeatures) {
727 removeFeature(featureName);
728 }
729 }
730
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700731 private void addFeature(String name, int version) {
732 FeatureInfo fi = mAvailableFeatures.get(name);
733 if (fi == null) {
734 fi = new FeatureInfo();
735 fi.name = name;
736 fi.version = version;
737 mAvailableFeatures.put(name, fi);
738 } else {
739 fi.version = Math.max(fi.version, version);
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -0700740 }
741 }
742
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700743 private void removeFeature(String name) {
744 if (mAvailableFeatures.remove(name) != null) {
745 Slog.d(TAG, "Removed unavailable feature " + name);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700746 }
747 }
748
749 void readPermission(XmlPullParser parser, String name)
750 throws IOException, XmlPullParserException {
Jeff Sharkey00f39042015-03-23 16:51:22 -0700751 if (mPermissions.containsKey(name)) {
752 throw new IllegalStateException("Duplicate permission definition for " + name);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700753 }
Jeff Sharkey00f39042015-03-23 16:51:22 -0700754
755 final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
756 final PermissionEntry perm = new PermissionEntry(name, perUser);
757 mPermissions.put(name, perm);
758
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700759 int outerDepth = parser.getDepth();
760 int type;
761 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
762 && (type != XmlPullParser.END_TAG
763 || parser.getDepth() > outerDepth)) {
764 if (type == XmlPullParser.END_TAG
765 || type == XmlPullParser.TEXT) {
766 continue;
767 }
768
769 String tagName = parser.getName();
770 if ("group".equals(tagName)) {
771 String gidStr = parser.getAttributeValue(null, "gid");
772 if (gidStr != null) {
773 int gid = Process.getGidForName(gidStr);
774 perm.gids = appendInt(perm.gids, gid);
775 } else {
776 Slog.w(TAG, "<group> without gid at "
777 + parser.getPositionDescription());
778 }
779 }
780 XmlUtils.skipCurrentTag(parser);
781 }
782 }
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800783
Jiyong Park002fdbd2017-02-13 20:50:31 +0900784 private void readPrivAppPermissions(XmlPullParser parser,
785 ArrayMap<String, ArraySet<String>> grantMap,
786 ArrayMap<String, ArraySet<String>> denyMap)
787 throws IOException, XmlPullParserException {
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800788 String packageName = parser.getAttributeValue(null, "package");
789 if (TextUtils.isEmpty(packageName)) {
790 Slog.w(TAG, "package is required for <privapp-permissions> in "
791 + parser.getPositionDescription());
792 return;
793 }
794
Jiyong Park002fdbd2017-02-13 20:50:31 +0900795 ArraySet<String> permissions = grantMap.get(packageName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800796 if (permissions == null) {
797 permissions = new ArraySet<>();
798 }
Jiyong Park002fdbd2017-02-13 20:50:31 +0900799 ArraySet<String> denyPermissions = denyMap.get(packageName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800800 int depth = parser.getDepth();
801 while (XmlUtils.nextElementWithin(parser, depth)) {
802 String name = parser.getName();
803 if ("permission".equals(name)) {
804 String permName = parser.getAttributeValue(null, "name");
805 if (TextUtils.isEmpty(permName)) {
806 Slog.w(TAG, "name is required for <permission> in "
807 + parser.getPositionDescription());
808 continue;
809 }
810 permissions.add(permName);
Todd Kennedy74629e32017-08-15 14:48:07 -0700811 } else if ("deny-permission".equals(name)) {
812 String permName = parser.getAttributeValue(null, "name");
813 if (TextUtils.isEmpty(permName)) {
814 Slog.w(TAG, "name is required for <deny-permission> in "
815 + parser.getPositionDescription());
816 continue;
817 }
818 if (denyPermissions == null) {
819 denyPermissions = new ArraySet<>();
820 }
821 denyPermissions.add(permName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800822 }
823 }
Jiyong Park002fdbd2017-02-13 20:50:31 +0900824 grantMap.put(packageName, permissions);
Todd Kennedy74629e32017-08-15 14:48:07 -0700825 if (denyPermissions != null) {
Jiyong Park002fdbd2017-02-13 20:50:31 +0900826 denyMap.put(packageName, denyPermissions);
Todd Kennedy74629e32017-08-15 14:48:07 -0700827 }
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800828 }
Svet Ganov087dce22017-09-07 15:42:16 -0700829
830 void readOemPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
831 final String packageName = parser.getAttributeValue(null, "package");
832 if (TextUtils.isEmpty(packageName)) {
833 Slog.w(TAG, "package is required for <oem-permissions> in "
834 + parser.getPositionDescription());
835 return;
836 }
837
838 ArrayMap<String, Boolean> permissions = mOemPermissions.get(packageName);
839 if (permissions == null) {
840 permissions = new ArrayMap<>();
841 }
842 final int depth = parser.getDepth();
843 while (XmlUtils.nextElementWithin(parser, depth)) {
844 final String name = parser.getName();
845 if ("permission".equals(name)) {
846 final String permName = parser.getAttributeValue(null, "name");
847 if (TextUtils.isEmpty(permName)) {
848 Slog.w(TAG, "name is required for <permission> in "
849 + parser.getPositionDescription());
850 continue;
851 }
852 permissions.put(permName, Boolean.TRUE);
853 } else if ("deny-permission".equals(name)) {
854 String permName = parser.getAttributeValue(null, "name");
855 if (TextUtils.isEmpty(permName)) {
856 Slog.w(TAG, "name is required for <deny-permission> in "
857 + parser.getPositionDescription());
858 continue;
859 }
860 permissions.put(permName, Boolean.FALSE);
861 }
862 }
863 mOemPermissions.put(packageName, permissions);
864 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700865}