blob: 26d2f19b13b6e0f2426a6978db6b410d8cf22f1e [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
Winsond9d17362019-10-02 12:41:29 -070021import android.annotation.NonNull;
Dianne Hackbornc0e4aaa2014-11-14 10:55:50 -080022import android.app.ActivityManager;
Ruben Brunk98576cf2016-03-07 18:54:28 -080023import android.content.ComponentName;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070024import android.content.pm.FeatureInfo;
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070025import android.content.pm.PackageManager;
Jiyong Parkfad99442018-03-12 10:39:07 +090026import android.os.Build;
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070027import android.os.Environment;
Luke Huang1414c612019-12-16 20:22:12 +080028import android.os.FileUtils;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070029import android.os.Process;
Steven Morelandd7827fd2018-12-03 10:27:01 -080030import android.os.SystemProperties;
Felipe Leme3eb78092019-10-22 09:22:20 -070031import android.os.Trace;
Alex Buynytskyyd8b25b82020-02-04 11:44:20 -080032import android.os.incremental.IncrementalManager;
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070033import android.os.storage.StorageManager;
Zimuzocc2932f2018-10-29 16:04:41 +000034import android.permission.PermissionManager.SplitPermissionInfo;
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -080035import android.text.TextUtils;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070036import android.util.ArrayMap;
37import android.util.ArraySet;
38import android.util.Slog;
39import android.util.SparseArray;
Felipe Leme3eb78092019-10-22 09:22:20 -070040import android.util.TimingsTraceLog;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070041import android.util.Xml;
Jeff Sharkey1c4ae802014-12-19 11:08:55 -080042
Bookatz04d7ae52019-08-05 14:07:12 -070043import com.android.internal.annotations.VisibleForTesting;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070044import com.android.internal.util.XmlUtils;
Jeff Sharkey1c4ae802014-12-19 11:08:55 -080045
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -070046import libcore.io.IoUtils;
47
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070048import org.xmlpull.v1.XmlPullParser;
49import org.xmlpull.v1.XmlPullParserException;
50
51import java.io.File;
52import java.io.FileNotFoundException;
53import java.io.FileReader;
54import java.io.IOException;
Jeff Davidson24b9d962016-07-21 12:35:10 -070055import java.util.ArrayList;
Svet Ganov087dce22017-09-07 15:42:16 -070056import java.util.Collections;
Jeff Davidson24b9d962016-07-21 12:35:10 -070057import java.util.List;
Svet Ganov087dce22017-09-07 15:42:16 -070058import java.util.Map;
Bookatz04d7ae52019-08-05 14:07:12 -070059import java.util.Set;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070060
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070061/**
62 * Loads global system configuration info.
Anthony Hughde787d42019-08-22 15:35:48 -070063 * Note: Initializing this class hits the disk and is slow. This class should generally only be
64 * accessed by the system_server process.
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070065 */
66public class SystemConfig {
67 static final String TAG = "SystemConfig";
68
69 static SystemConfig sInstance;
70
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +080071 // permission flag, determines which types of configuration are allowed to be read
72 private static final int ALLOW_FEATURES = 0x01;
73 private static final int ALLOW_LIBS = 0x02;
74 private static final int ALLOW_PERMISSIONS = 0x04;
75 private static final int ALLOW_APP_CONFIGS = 0x08;
Jaekyun Seoke3b6bf12017-02-16 13:48:30 +090076 private static final int ALLOW_PRIVAPP_PERMISSIONS = 0x10;
Svet Ganov087dce22017-09-07 15:42:16 -070077 private static final int ALLOW_OEM_PERMISSIONS = 0x20;
Mathew Inwood4693a752018-02-20 16:04:25 +000078 private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x40;
Dianne Hackborn769b2e72018-12-05 08:51:20 -080079 private static final int ALLOW_ASSOCIATIONS = 0x80;
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +080080 private static final int ALLOW_ALL = ~0;
81
Steven Morelandd7827fd2018-12-03 10:27:01 -080082 // property for runtime configuration differentiation
83 private static final String SKU_PROPERTY = "ro.boot.product.hardware.sku";
84
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070085 // Group-ids that are given to all packages as read from etc/permissions/*.xml.
86 int[] mGlobalGids;
87
88 // These are the built-in uid -> permission mappings that were read from the
89 // system configuration files.
Jeff Sharkey9f837a92014-10-24 12:07:24 -070090 final SparseArray<ArraySet<String>> mSystemPermissions = new SparseArray<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -070091
Zimuzocc2932f2018-10-29 16:04:41 +000092 final ArrayList<SplitPermissionInfo> mSplitPermissions = new ArrayList<>();
93
Ben Lin71c16d72018-12-06 18:34:51 -080094 public static final class SharedLibraryEntry {
95 public final String name;
96 public final String filename;
97 public final String[] dependencies;
98
99 SharedLibraryEntry(String name, String filename, String[] dependencies) {
100 this.name = name;
101 this.filename = filename;
102 this.dependencies = dependencies;
103 }
104 }
105
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700106 // These are the built-in shared libraries that were read from the
Ben Lin71c16d72018-12-06 18:34:51 -0800107 // system configuration files. Keys are the library names; values are
108 // the individual entries that contain information such as filename
109 // and dependencies.
110 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = new ArrayMap<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700111
112 // These are the features this devices supports that were read from the
113 // system configuration files.
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700114 final ArrayMap<String, FeatureInfo> mAvailableFeatures = new ArrayMap<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700115
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800116 // These are the features which this device doesn't support; the OEM
117 // partition uses these to opt-out of features from the system image.
118 final ArraySet<String> mUnavailableFeatures = new ArraySet<>();
119
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700120 public static final class PermissionEntry {
121 public final String name;
122 public int[] gids;
Jeff Sharkey00f39042015-03-23 16:51:22 -0700123 public boolean perUser;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700124
Jeff Sharkey00f39042015-03-23 16:51:22 -0700125 PermissionEntry(String name, boolean perUser) {
126 this.name = name;
127 this.perUser = perUser;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700128 }
129 }
130
131 // These are the permission -> gid mappings that were read from the
132 // system configuration files.
Dianne Hackbornbb8aa5a2014-09-17 13:20:38 -0700133 final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700134
135 // These are the packages that are white-listed to be able to run in the
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700136 // background while in power save mode (but not whitelisted from device idle modes),
137 // as read from the configuration files.
138 final ArraySet<String> mAllowInPowerSaveExceptIdle = new ArraySet<>();
139
140 // These are the packages that are white-listed to be able to run in the
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700141 // background while in power save mode, as read from the configuration files.
Dianne Hackbornbb8aa5a2014-09-17 13:20:38 -0700142 final ArraySet<String> mAllowInPowerSave = new ArraySet<>();
143
Felipe Lemea9505cc2016-02-26 10:28:41 -0800144 // These are the packages that are white-listed to be able to run in the
145 // background while in data-usage save mode, as read from the configuration files.
146 final ArraySet<String> mAllowInDataUsageSave = new ArraySet<>();
147
Soonil Nagarkar2b565df2017-02-14 13:33:23 -0800148 // These are the packages that are white-listed to be able to run background location
149 // without throttling, as read from the configuration files.
150 final ArraySet<String> mAllowUnthrottledLocation = new ArraySet<>();
151
Soonil Nagarkar397ad582019-01-23 22:47:57 -0800152 // These are the packages that are white-listed to be able to retrieve location even when user
153 // location settings are off, for emergency purposes, as read from the configuration files.
154 final ArraySet<String> mAllowIgnoreLocationSettings = new ArraySet<>();
155
Christopher Tate42a386b2016-11-07 12:21:21 -0800156 // These are the action strings of broadcasts which are whitelisted to
157 // be delivered anonymously even to apps which target O+.
158 final ArraySet<String> mAllowImplicitBroadcasts = new ArraySet<>();
159
Christopher Tate01e18642015-07-07 18:10:38 -0700160 // These are the package names of apps which should be in the 'always'
161 // URL-handling state upon factory reset.
162 final ArraySet<String> mLinkedApps = new ArraySet<>();
163
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700164 // These are the packages that are whitelisted to be able to run as system user
165 final ArraySet<String> mSystemUserWhitelistedApps = new ArraySet<>();
166
167 // These are the packages that should not run under system user
168 final ArraySet<String> mSystemUserBlacklistedApps = new ArraySet<>();
169
Ruben Brunk98576cf2016-03-07 18:54:28 -0800170 // These are the components that are enabled by default as VR mode listener services.
171 final ArraySet<ComponentName> mDefaultVrComponents = new ArraySet<>();
172
Christopher Tate494df792016-05-10 17:05:38 -0700173 // These are the permitted backup transport service components
174 final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();
175
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -0700176 // These are packages mapped to maps of component class name to default enabled state.
177 final ArrayMap<String, ArrayMap<String, Boolean>> mPackageComponentEnabledState =
178 new ArrayMap<>();
179
Mathew Inwood4693a752018-02-20 16:04:25 +0000180 // Package names that are exempted from private API blacklisting
181 final ArraySet<String> mHiddenApiPackageWhitelist = new ArraySet<>();
182
goneileb31cd42018-02-28 15:22:08 -0800183 // The list of carrier applications which should be disabled until used.
184 // This function suppresses update notifications for these pre-installed apps.
185 // In SubscriptionInfoUpdater, the listed applications are disabled until used when all of the
186 // following conditions are met.
187 // 1. Not currently carrier-privileged according to the inserted SIM
188 // 2. Pre-installed
189 // 3. In the default state (enabled but not explicitly)
190 // And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted
191 // that marks the app as carrier privileged. It also grants the app default permissions
192 // for Phone and Location. As such, apps MUST only ever be added to this list if they
193 // obtain user consent to access their location through other means.
194 final ArraySet<String> mDisabledUntilUsedPreinstalledCarrierApps = new ArraySet<>();
195
Jeff Davidson24b9d962016-07-21 12:35:10 -0700196 // These are the packages of carrier-associated apps which should be disabled until used until
197 // a SIM is inserted which grants carrier privileges to that carrier app.
198 final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
199 new ArrayMap<>();
200
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800201 final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
Todd Kennedy74629e32017-08-15 14:48:07 -0700202 final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>();
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800203
Jiyong Park002fdbd2017-02-13 20:50:31 +0900204 final ArrayMap<String, ArraySet<String>> mVendorPrivAppPermissions = new ArrayMap<>();
205 final ArrayMap<String, ArraySet<String>> mVendorPrivAppDenyPermissions = new ArrayMap<>();
206
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900207 final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
208 final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
209
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900210 final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>();
211 final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>();
Dario Freni2bef1762018-06-01 14:02:08 +0100212
Svet Ganov087dce22017-09-07 15:42:16 -0700213 final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
214
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800215 // Allowed associations between applications. If there are any entries
216 // for an app, those are the only associations allowed; otherwise, all associations
217 // are allowed. Allowing an association from app A to app B means app A can not
218 // associate with any other apps, but does not limit what apps B can associate with.
219 final ArrayMap<String, ArraySet<String>> mAllowedAssociations = new ArrayMap<>();
220
Nikita Ioffe07964b42019-02-28 21:35:02 +0000221 private final ArraySet<String> mBugreportWhitelistedPackages = new ArraySet<>();
Ricky Wai825d3e92019-12-18 15:16:17 +0000222 private final ArraySet<String> mAppDataIsolationWhitelistedApps = new ArraySet<>();
Nikita Ioffe07964b42019-02-28 21:35:02 +0000223
Bookatz04d7ae52019-08-05 14:07:12 -0700224 // Map of packagesNames to userTypes. Stored temporarily until cleared by UserManagerService().
225 private ArrayMap<String, Set<String>> mPackageToUserTypeWhitelist = new ArrayMap<>();
226 private ArrayMap<String, Set<String>> mPackageToUserTypeBlacklist = new ArrayMap<>();
227
JW Wangf0a70b12019-12-11 17:12:02 +0800228 private final ArraySet<String> mRollbackWhitelistedPackages = new ArraySet<>();
229
Winsond9d17362019-10-02 12:41:29 -0700230 /**
231 * Map of system pre-defined, uniquely named actors; keys are namespace,
232 * value maps actor name to package name.
233 */
Winson Chiu2fdaf812019-12-13 20:01:15 +0000234 private Map<String, Map<String, String>> mNamedActors = null;
Winsond9d17362019-10-02 12:41:29 -0700235
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700236 public static SystemConfig getInstance() {
Anthony Hughde787d42019-08-22 15:35:48 -0700237 if (!isSystemProcess()) {
238 Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
239 + "system_server.");
240 }
241
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700242 synchronized (SystemConfig.class) {
243 if (sInstance == null) {
244 sInstance = new SystemConfig();
245 }
246 return sInstance;
247 }
248 }
249
250 public int[] getGlobalGids() {
251 return mGlobalGids;
252 }
253
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700254 public SparseArray<ArraySet<String>> getSystemPermissions() {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700255 return mSystemPermissions;
256 }
257
Zimuzocc2932f2018-10-29 16:04:41 +0000258 public ArrayList<SplitPermissionInfo> getSplitPermissions() {
259 return mSplitPermissions;
260 }
261
Ben Lin71c16d72018-12-06 18:34:51 -0800262 public ArrayMap<String, SharedLibraryEntry> getSharedLibraries() {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700263 return mSharedLibraries;
264 }
265
Jeff Sharkey9f837a92014-10-24 12:07:24 -0700266 public ArrayMap<String, FeatureInfo> getAvailableFeatures() {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700267 return mAvailableFeatures;
268 }
269
270 public ArrayMap<String, PermissionEntry> getPermissions() {
271 return mPermissions;
272 }
273
Christopher Tate42a386b2016-11-07 12:21:21 -0800274 public ArraySet<String> getAllowImplicitBroadcasts() {
275 return mAllowImplicitBroadcasts;
276 }
277
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700278 public ArraySet<String> getAllowInPowerSaveExceptIdle() {
279 return mAllowInPowerSaveExceptIdle;
280 }
281
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700282 public ArraySet<String> getAllowInPowerSave() {
283 return mAllowInPowerSave;
284 }
285
Felipe Lemea9505cc2016-02-26 10:28:41 -0800286 public ArraySet<String> getAllowInDataUsageSave() {
287 return mAllowInDataUsageSave;
288 }
289
Soonil Nagarkar2b565df2017-02-14 13:33:23 -0800290 public ArraySet<String> getAllowUnthrottledLocation() {
291 return mAllowUnthrottledLocation;
292 }
293
Soonil Nagarkar397ad582019-01-23 22:47:57 -0800294 public ArraySet<String> getAllowIgnoreLocationSettings() {
295 return mAllowIgnoreLocationSettings;
296 }
297
Christopher Tate01e18642015-07-07 18:10:38 -0700298 public ArraySet<String> getLinkedApps() {
299 return mLinkedApps;
300 }
301
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700302 public ArraySet<String> getSystemUserWhitelistedApps() {
303 return mSystemUserWhitelistedApps;
304 }
305
306 public ArraySet<String> getSystemUserBlacklistedApps() {
307 return mSystemUserBlacklistedApps;
308 }
309
Mathew Inwood4693a752018-02-20 16:04:25 +0000310 public ArraySet<String> getHiddenApiWhitelistedApps() {
311 return mHiddenApiPackageWhitelist;
312 }
313
Ruben Brunk98576cf2016-03-07 18:54:28 -0800314 public ArraySet<ComponentName> getDefaultVrComponents() {
315 return mDefaultVrComponents;
316 }
317
Christopher Tate494df792016-05-10 17:05:38 -0700318 public ArraySet<ComponentName> getBackupTransportWhitelist() {
319 return mBackupTransportWhitelist;
320 }
321
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -0700322 public ArrayMap<String, Boolean> getComponentsEnabledStates(String packageName) {
323 return mPackageComponentEnabledState.get(packageName);
324 }
325
goneileb31cd42018-02-28 15:22:08 -0800326 public ArraySet<String> getDisabledUntilUsedPreinstalledCarrierApps() {
327 return mDisabledUntilUsedPreinstalledCarrierApps;
328 }
329
Jeff Davidson24b9d962016-07-21 12:35:10 -0700330 public ArrayMap<String, List<String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
331 return mDisabledUntilUsedPreinstalledCarrierAssociatedApps;
332 }
333
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -0800334 public ArraySet<String> getPrivAppPermissions(String packageName) {
335 return mPrivAppPermissions.get(packageName);
336 }
337
Todd Kennedy74629e32017-08-15 14:48:07 -0700338 public ArraySet<String> getPrivAppDenyPermissions(String packageName) {
339 return mPrivAppDenyPermissions.get(packageName);
340 }
341
Jiyong Park002fdbd2017-02-13 20:50:31 +0900342 public ArraySet<String> getVendorPrivAppPermissions(String packageName) {
343 return mVendorPrivAppPermissions.get(packageName);
344 }
345
346 public ArraySet<String> getVendorPrivAppDenyPermissions(String packageName) {
347 return mVendorPrivAppDenyPermissions.get(packageName);
348 }
349
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900350 public ArraySet<String> getProductPrivAppPermissions(String packageName) {
351 return mProductPrivAppPermissions.get(packageName);
352 }
353
354 public ArraySet<String> getProductPrivAppDenyPermissions(String packageName) {
355 return mProductPrivAppDenyPermissions.get(packageName);
356 }
357
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900358 /**
359 * Read from "permission" tags in /system_ext/etc/permissions/*.xml
360 * @return Set of privileged permissions that are explicitly granted.
361 */
362 public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) {
363 return mSystemExtPrivAppPermissions.get(packageName);
Dario Freni2bef1762018-06-01 14:02:08 +0100364 }
365
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900366 /**
367 * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml
368 * @return Set of privileged permissions that are explicitly denied.
369 */
370 public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) {
371 return mSystemExtPrivAppDenyPermissions.get(packageName);
Dario Freni2bef1762018-06-01 14:02:08 +0100372 }
373
Svet Ganov087dce22017-09-07 15:42:16 -0700374 public Map<String, Boolean> getOemPermissions(String packageName) {
375 final Map<String, Boolean> oemPermissions = mOemPermissions.get(packageName);
376 if (oemPermissions != null) {
377 return oemPermissions;
378 }
379 return Collections.emptyMap();
380 }
381
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800382 public ArrayMap<String, ArraySet<String>> getAllowedAssociations() {
383 return mAllowedAssociations;
384 }
385
Nikita Ioffe07964b42019-02-28 21:35:02 +0000386 public ArraySet<String> getBugreportWhitelistedPackages() {
387 return mBugreportWhitelistedPackages;
388 }
389
JW Wangf0a70b12019-12-11 17:12:02 +0800390 public Set<String> getRollbackWhitelistedPackages() {
391 return mRollbackWhitelistedPackages;
392 }
393
Ricky Wai825d3e92019-12-18 15:16:17 +0000394 public ArraySet<String> getAppDataIsolationWhitelistedApps() {
395 return mAppDataIsolationWhitelistedApps;
396 }
397
Bookatz04d7ae52019-08-05 14:07:12 -0700398 /**
399 * Gets map of packagesNames to userTypes, dictating on which user types each package should be
400 * initially installed, and then removes this map from SystemConfig.
401 * Called by UserManagerService when it is constructed.
402 */
403 public ArrayMap<String, Set<String>> getAndClearPackageToUserTypeWhitelist() {
404 ArrayMap<String, Set<String>> r = mPackageToUserTypeWhitelist;
405 mPackageToUserTypeWhitelist = new ArrayMap<>(0);
406 return r;
407 }
408
409 /**
410 * Gets map of packagesNames to userTypes, dictating on which user types each package should NOT
411 * be initially installed, even if they are whitelisted, and then removes this map from
412 * SystemConfig.
413 * Called by UserManagerService when it is constructed.
414 */
415 public ArrayMap<String, Set<String>> getAndClearPackageToUserTypeBlacklist() {
416 ArrayMap<String, Set<String>> r = mPackageToUserTypeBlacklist;
417 mPackageToUserTypeBlacklist = new ArrayMap<>(0);
418 return r;
419 }
420
Winsond9d17362019-10-02 12:41:29 -0700421 @NonNull
Winson Chiu2fdaf812019-12-13 20:01:15 +0000422 public Map<String, Map<String, String>> getNamedActors() {
Winsond9d17362019-10-02 12:41:29 -0700423 return mNamedActors != null ? mNamedActors : Collections.emptyMap();
424 }
425
Bookatz04d7ae52019-08-05 14:07:12 -0700426 /**
427 * Only use for testing. Do NOT use in production code.
428 * @param readPermissions false to create an empty SystemConfig; true to read the permissions.
429 */
430 @VisibleForTesting
Winsond9d17362019-10-02 12:41:29 -0700431 public SystemConfig(boolean readPermissions) {
Bookatz04d7ae52019-08-05 14:07:12 -0700432 if (readPermissions) {
433 Slog.w(TAG, "Constructing a test SystemConfig");
434 readAllPermissions();
435 } else {
436 Slog.w(TAG, "Constructing an empty test SystemConfig");
437 }
438 }
439
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700440 SystemConfig() {
Felipe Leme3eb78092019-10-22 09:22:20 -0700441 TimingsTraceLog log = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
442 log.traceBegin("readAllPermissions");
443 try {
444 readAllPermissions();
445 } finally {
446 log.traceEnd();
447 }
Bookatz04d7ae52019-08-05 14:07:12 -0700448 }
449
450 private void readAllPermissions() {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700451 // Read configuration from system
452 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800453 Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
Svet Ganov087dce22017-09-07 15:42:16 -0700454
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700455 // Read configuration from the old permissions dir
456 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800457 Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
Svet Ganov087dce22017-09-07 15:42:16 -0700458
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800459 // Vendors are only allowed to customize these
460 int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS
461 | ALLOW_ASSOCIATIONS;
Jiyong Parkfad99442018-03-12 10:39:07 +0900462 if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
463 // For backward compatibility
464 vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
465 }
Jaekyun Seoke3b6bf12017-02-16 13:48:30 +0900466 readPermissions(Environment.buildPath(
467 Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
468 readPermissions(Environment.buildPath(
469 Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);
Svet Ganov087dce22017-09-07 15:42:16 -0700470
Jiyong Park090c6b12017-12-28 12:03:28 +0900471 // Allow ODM to customize system configs as much as Vendor, because /odm is another
472 // vendor partition other than /vendor.
473 int odmPermissionFlag = vendorPermissionFlag;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700474 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800475 Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700476 readPermissions(Environment.buildPath(
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800477 Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
Svet Ganov087dce22017-09-07 15:42:16 -0700478
Steven Morelandd7827fd2018-12-03 10:27:01 -0800479 String skuProperty = SystemProperties.get(SKU_PROPERTY, "");
480 if (!skuProperty.isEmpty()) {
481 String skuDir = "sku_" + skuProperty;
482
483 readPermissions(Environment.buildPath(
484 Environment.getOdmDirectory(), "etc", "sysconfig", skuDir), odmPermissionFlag);
485 readPermissions(Environment.buildPath(
486 Environment.getOdmDirectory(), "etc", "permissions", skuDir),
487 odmPermissionFlag);
488 }
489
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800490 // Allow OEM to customize these
491 int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS;
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800492 readPermissions(Environment.buildPath(
Svet Ganov087dce22017-09-07 15:42:16 -0700493 Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800494 readPermissions(Environment.buildPath(
Svet Ganov087dce22017-09-07 15:42:16 -0700495 Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900496
Hung-ying Tyan38cd31c2018-09-26 15:05:07 +0800497 // Allow Product to customize all system configs
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900498 readPermissions(Environment.buildPath(
Hung-ying Tyan38cd31c2018-09-26 15:05:07 +0800499 Environment.getProductDirectory(), "etc", "sysconfig"), ALLOW_ALL);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +0900500 readPermissions(Environment.buildPath(
Hung-ying Tyan38cd31c2018-09-26 15:05:07 +0800501 Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
Dario Freni2bef1762018-06-01 14:02:08 +0100502
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900503 // Allow /system_ext to customize all system configs
Dario Freni2bef1762018-06-01 14:02:08 +0100504 readPermissions(Environment.buildPath(
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900505 Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
Dario Freni2bef1762018-06-01 14:02:08 +0100506 readPermissions(Environment.buildPath(
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900507 Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
Luke Huang1414c612019-12-16 20:22:12 +0800508
509 // Skip loading configuration from apex if it is not a system process.
510 if (!isSystemProcess()) {
511 return;
512 }
513 // Read configuration of libs from apex module.
514 // TODO: Use a solid way to filter apex module folders?
515 for (File f: FileUtils.listFilesOrEmpty(Environment.getApexDirectory())) {
516 if (f.isFile() || f.getPath().contains("@")) {
517 continue;
518 }
519 readPermissions(Environment.buildPath(f, "etc", "permissions"), ALLOW_LIBS);
520 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700521 }
522
Bookatz04d7ae52019-08-05 14:07:12 -0700523 @VisibleForTesting
524 public void readPermissions(File libraryDir, int permissionFlag) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700525 // Read permissions from given directory.
526 if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800527 if (permissionFlag == ALLOW_ALL) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700528 Slog.w(TAG, "No directory " + libraryDir + ", skipping");
529 }
530 return;
531 }
532 if (!libraryDir.canRead()) {
533 Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
534 return;
535 }
536
537 // Iterate over the files in the directory and scan .xml files
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800538 File platformFile = null;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700539 for (File f : libraryDir.listFiles()) {
Steven Morelandd7827fd2018-12-03 10:27:01 -0800540 if (!f.isFile()) {
541 continue;
542 }
543
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700544 // We'll read platform.xml last
545 if (f.getPath().endsWith("etc/permissions/platform.xml")) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800546 platformFile = f;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700547 continue;
548 }
549
550 if (!f.getPath().endsWith(".xml")) {
551 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
552 continue;
553 }
554 if (!f.canRead()) {
555 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
556 continue;
557 }
558
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800559 readPermissionsFromXml(f, permissionFlag);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700560 }
561
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800562 // Read platform permissions last so it will take precedence
563 if (platformFile != null) {
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800564 readPermissionsFromXml(platformFile, permissionFlag);
Jeff Sharkey1c4ae802014-12-19 11:08:55 -0800565 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700566 }
567
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800568 private void logNotAllowedInPartition(String name, File permFile, XmlPullParser parser) {
569 Slog.w(TAG, "<" + name + "> not allowed in partition of "
570 + permFile + " at " + parser.getPositionDescription());
571 }
572
Hung-ying Tyanbdc9d582015-11-20 11:53:39 +0800573 private void readPermissionsFromXml(File permFile, int permissionFlag) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700574 FileReader permReader = null;
575 try {
576 permReader = new FileReader(permFile);
577 } catch (FileNotFoundException e) {
578 Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
579 return;
580 }
Felipe Leme1fbe9b52019-10-21 14:20:08 -0700581 Slog.i(TAG, "Reading permissions from " + permFile);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700582
Dianne Hackbornc0e4aaa2014-11-14 10:55:50 -0800583 final boolean lowRam = ActivityManager.isLowRamDeviceStatic();
584
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700585 try {
586 XmlPullParser parser = Xml.newPullParser();
587 parser.setInput(permReader);
588
589 int type;
590 while ((type=parser.next()) != parser.START_TAG
591 && type != parser.END_DOCUMENT) {
592 ;
593 }
594
595 if (type != parser.START_TAG) {
596 throw new XmlPullParserException("No start tag found");
597 }
598
599 if (!parser.getName().equals("permissions") && !parser.getName().equals("config")) {
Dianne Hackbornb3d4cb32015-01-09 09:54:06 -0800600 throw new XmlPullParserException("Unexpected start tag in " + permFile
601 + ": found " + parser.getName() + ", expected 'permissions' or 'config'");
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700602 }
603
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800604 final boolean allowAll = permissionFlag == ALLOW_ALL;
605 final boolean allowLibs = (permissionFlag & ALLOW_LIBS) != 0;
606 final boolean allowFeatures = (permissionFlag & ALLOW_FEATURES) != 0;
607 final boolean allowPermissions = (permissionFlag & ALLOW_PERMISSIONS) != 0;
608 final boolean allowAppConfigs = (permissionFlag & ALLOW_APP_CONFIGS) != 0;
609 final boolean allowPrivappPermissions = (permissionFlag & ALLOW_PRIVAPP_PERMISSIONS)
610 != 0;
611 final boolean allowOemPermissions = (permissionFlag & ALLOW_OEM_PERMISSIONS) != 0;
612 final boolean allowApiWhitelisting = (permissionFlag & ALLOW_HIDDENAPI_WHITELISTING)
613 != 0;
614 final boolean allowAssociations = (permissionFlag & ALLOW_ASSOCIATIONS) != 0;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700615 while (true) {
616 XmlUtils.nextElement(parser);
617 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
618 break;
619 }
620
621 String name = parser.getName();
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800622 if (name == null) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700623 XmlUtils.skipCurrentTag(parser);
624 continue;
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800625 }
626 switch (name) {
627 case "group": {
628 if (allowAll) {
629 String gidStr = parser.getAttributeValue(null, "gid");
630 if (gidStr != null) {
631 int gid = android.os.Process.getGidForName(gidStr);
632 mGlobalGids = appendInt(mGlobalGids, gid);
633 } else {
634 Slog.w(TAG, "<" + name + "> without gid in " + permFile + " at "
goneileb31cd42018-02-28 15:22:08 -0800635 + parser.getPositionDescription());
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800636 }
637 } else {
638 logNotAllowedInPartition(name, permFile, parser);
639 }
640 XmlUtils.skipCurrentTag(parser);
641 } break;
642 case "permission": {
643 if (allowPermissions) {
644 String perm = parser.getAttributeValue(null, "name");
645 if (perm == null) {
646 Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
647 + parser.getPositionDescription());
648 XmlUtils.skipCurrentTag(parser);
649 break;
650 }
651 perm = perm.intern();
652 readPermission(parser, perm);
653 } else {
654 logNotAllowedInPartition(name, permFile, parser);
655 XmlUtils.skipCurrentTag(parser);
656 }
657 } break;
658 case "assign-permission": {
659 if (allowPermissions) {
660 String perm = parser.getAttributeValue(null, "name");
661 if (perm == null) {
662 Slog.w(TAG, "<" + name + "> without name in " + permFile
663 + " at " + parser.getPositionDescription());
664 XmlUtils.skipCurrentTag(parser);
665 break;
666 }
667 String uidStr = parser.getAttributeValue(null, "uid");
668 if (uidStr == null) {
669 Slog.w(TAG, "<" + name + "> without uid in " + permFile
670 + " at " + parser.getPositionDescription());
671 XmlUtils.skipCurrentTag(parser);
672 break;
673 }
674 int uid = Process.getUidForName(uidStr);
675 if (uid < 0) {
676 Slog.w(TAG, "<" + name + "> with unknown uid \""
677 + uidStr + " in " + permFile + " at "
678 + parser.getPositionDescription());
679 XmlUtils.skipCurrentTag(parser);
680 break;
681 }
682 perm = perm.intern();
683 ArraySet<String> perms = mSystemPermissions.get(uid);
684 if (perms == null) {
685 perms = new ArraySet<String>();
686 mSystemPermissions.put(uid, perms);
687 }
688 perms.add(perm);
689 } else {
690 logNotAllowedInPartition(name, permFile, parser);
691 }
692 XmlUtils.skipCurrentTag(parser);
693 } break;
694 case "split-permission": {
695 if (allowPermissions) {
696 readSplitPermission(parser, permFile);
697 } else {
698 logNotAllowedInPartition(name, permFile, parser);
699 XmlUtils.skipCurrentTag(parser);
700 }
701 } break;
702 case "library": {
703 if (allowLibs) {
704 String lname = parser.getAttributeValue(null, "name");
705 String lfile = parser.getAttributeValue(null, "file");
706 String ldependency = parser.getAttributeValue(null, "dependency");
707 if (lname == null) {
708 Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
709 + parser.getPositionDescription());
710 } else if (lfile == null) {
711 Slog.w(TAG, "<" + name + "> without file in " + permFile + " at "
712 + parser.getPositionDescription());
713 } else {
714 //Log.i(TAG, "Got library " + lname + " in " + lfile);
715 SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile,
716 ldependency == null ? new String[0] : ldependency.split(":"));
717 mSharedLibraries.put(lname, entry);
718 }
719 } else {
720 logNotAllowedInPartition(name, permFile, parser);
721 }
722 XmlUtils.skipCurrentTag(parser);
723 } break;
724 case "feature": {
725 if (allowFeatures) {
726 String fname = parser.getAttributeValue(null, "name");
727 int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
728 boolean allowed;
729 if (!lowRam) {
730 allowed = true;
731 } else {
732 String notLowRam = parser.getAttributeValue(null, "notLowRam");
733 allowed = !"true".equals(notLowRam);
734 }
735 if (fname == null) {
736 Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
737 + parser.getPositionDescription());
738 } else if (allowed) {
739 addFeature(fname, fversion);
740 }
741 } else {
742 logNotAllowedInPartition(name, permFile, parser);
743 }
744 XmlUtils.skipCurrentTag(parser);
745 } break;
746 case "unavailable-feature": {
747 if (allowFeatures) {
748 String fname = parser.getAttributeValue(null, "name");
749 if (fname == null) {
750 Slog.w(TAG, "<" + name + "> without name in " + permFile
751 + " at " + parser.getPositionDescription());
752 } else {
753 mUnavailableFeatures.add(fname);
754 }
755 } else {
756 logNotAllowedInPartition(name, permFile, parser);
757 }
758 XmlUtils.skipCurrentTag(parser);
759 } break;
760 case "allow-in-power-save-except-idle": {
761 if (allowAll) {
762 String pkgname = parser.getAttributeValue(null, "package");
763 if (pkgname == null) {
764 Slog.w(TAG, "<" + name + "> without package in "
765 + permFile + " at " + parser.getPositionDescription());
766 } else {
767 mAllowInPowerSaveExceptIdle.add(pkgname);
768 }
769 } else {
770 logNotAllowedInPartition(name, permFile, parser);
771 }
772 XmlUtils.skipCurrentTag(parser);
773 } break;
774 case "allow-in-power-save": {
775 if (allowAll) {
776 String pkgname = parser.getAttributeValue(null, "package");
777 if (pkgname == null) {
778 Slog.w(TAG, "<" + name + "> without package in "
779 + permFile + " at " + parser.getPositionDescription());
780 } else {
781 mAllowInPowerSave.add(pkgname);
782 }
783 } else {
784 logNotAllowedInPartition(name, permFile, parser);
785 }
786 XmlUtils.skipCurrentTag(parser);
787 } break;
788 case "allow-in-data-usage-save": {
789 if (allowAll) {
790 String pkgname = parser.getAttributeValue(null, "package");
791 if (pkgname == null) {
792 Slog.w(TAG, "<" + name + "> without package in "
793 + permFile + " at " + parser.getPositionDescription());
794 } else {
795 mAllowInDataUsageSave.add(pkgname);
796 }
797 } else {
798 logNotAllowedInPartition(name, permFile, parser);
799 }
800 XmlUtils.skipCurrentTag(parser);
801 } break;
802 case "allow-unthrottled-location": {
803 if (allowAll) {
804 String pkgname = parser.getAttributeValue(null, "package");
805 if (pkgname == null) {
806 Slog.w(TAG, "<" + name + "> without package in "
807 + permFile + " at " + parser.getPositionDescription());
808 } else {
809 mAllowUnthrottledLocation.add(pkgname);
810 }
811 } else {
812 logNotAllowedInPartition(name, permFile, parser);
813 }
814 XmlUtils.skipCurrentTag(parser);
815 } break;
Soonil Nagarkar397ad582019-01-23 22:47:57 -0800816 case "allow-ignore-location-settings": {
817 if (allowAll) {
818 String pkgname = parser.getAttributeValue(null, "package");
819 if (pkgname == null) {
820 Slog.w(TAG, "<" + name + "> without package in "
821 + permFile + " at " + parser.getPositionDescription());
822 } else {
823 mAllowIgnoreLocationSettings.add(pkgname);
824 }
825 } else {
826 logNotAllowedInPartition(name, permFile, parser);
827 }
828 XmlUtils.skipCurrentTag(parser);
829 } break;
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800830 case "allow-implicit-broadcast": {
831 if (allowAll) {
832 String action = parser.getAttributeValue(null, "action");
833 if (action == null) {
834 Slog.w(TAG, "<" + name + "> without action in "
835 + permFile + " at " + parser.getPositionDescription());
836 } else {
837 mAllowImplicitBroadcasts.add(action);
838 }
839 } else {
840 logNotAllowedInPartition(name, permFile, parser);
841 }
842 XmlUtils.skipCurrentTag(parser);
843 } break;
844 case "app-link": {
845 if (allowAppConfigs) {
846 String pkgname = parser.getAttributeValue(null, "package");
847 if (pkgname == null) {
848 Slog.w(TAG, "<" + name + "> without package in " + permFile
849 + " at " + parser.getPositionDescription());
850 } else {
851 mLinkedApps.add(pkgname);
852 }
853 } else {
854 logNotAllowedInPartition(name, permFile, parser);
855 }
856 XmlUtils.skipCurrentTag(parser);
857 } break;
858 case "system-user-whitelisted-app": {
859 if (allowAppConfigs) {
860 String pkgname = parser.getAttributeValue(null, "package");
861 if (pkgname == null) {
862 Slog.w(TAG, "<" + name + "> without package in "
863 + permFile + " at " + parser.getPositionDescription());
864 } else {
865 mSystemUserWhitelistedApps.add(pkgname);
866 }
867 } else {
868 logNotAllowedInPartition(name, permFile, parser);
869 }
870 XmlUtils.skipCurrentTag(parser);
871 } break;
872 case "system-user-blacklisted-app": {
873 if (allowAppConfigs) {
874 String pkgname = parser.getAttributeValue(null, "package");
875 if (pkgname == null) {
876 Slog.w(TAG, "<" + name + "> without package in "
877 + permFile + " at " + parser.getPositionDescription());
878 } else {
879 mSystemUserBlacklistedApps.add(pkgname);
880 }
881 } else {
882 logNotAllowedInPartition(name, permFile, parser);
883 }
884 XmlUtils.skipCurrentTag(parser);
885 } break;
886 case "default-enabled-vr-app": {
887 if (allowAppConfigs) {
888 String pkgname = parser.getAttributeValue(null, "package");
889 String clsname = parser.getAttributeValue(null, "class");
890 if (pkgname == null) {
891 Slog.w(TAG, "<" + name + "> without package in "
892 + permFile + " at " + parser.getPositionDescription());
893 } else if (clsname == null) {
894 Slog.w(TAG, "<" + name + "> without class in "
895 + permFile + " at " + parser.getPositionDescription());
896 } else {
897 mDefaultVrComponents.add(new ComponentName(pkgname, clsname));
898 }
899 } else {
900 logNotAllowedInPartition(name, permFile, parser);
901 }
902 XmlUtils.skipCurrentTag(parser);
903 } break;
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -0700904 case "component-override": {
Ryan Mitchell61a30322019-10-30 08:52:43 -0700905 readComponentOverrides(parser, permFile);
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -0700906 XmlUtils.skipCurrentTag(parser);
907 } break;
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800908 case "backup-transport-whitelisted-service": {
909 if (allowFeatures) {
910 String serviceName = parser.getAttributeValue(null, "service");
911 if (serviceName == null) {
912 Slog.w(TAG, "<" + name + "> without service in "
913 + permFile + " at " + parser.getPositionDescription());
914 } else {
915 ComponentName cn = ComponentName.unflattenFromString(serviceName);
916 if (cn == null) {
917 Slog.w(TAG, "<" + name + "> with invalid service name "
918 + serviceName + " in " + permFile
919 + " at " + parser.getPositionDescription());
920 } else {
921 mBackupTransportWhitelist.add(cn);
922 }
923 }
924 } else {
925 logNotAllowedInPartition(name, permFile, parser);
926 }
927 XmlUtils.skipCurrentTag(parser);
928 } break;
929 case "disabled-until-used-preinstalled-carrier-associated-app": {
930 if (allowAppConfigs) {
931 String pkgname = parser.getAttributeValue(null, "package");
932 String carrierPkgname = parser.getAttributeValue(null,
933 "carrierAppPackage");
934 if (pkgname == null || carrierPkgname == null) {
935 Slog.w(TAG, "<" + name
936 + "> without package or carrierAppPackage in " + permFile
937 + " at " + parser.getPositionDescription());
938 } else {
939 List<String> associatedPkgs =
940 mDisabledUntilUsedPreinstalledCarrierAssociatedApps.get(
941 carrierPkgname);
942 if (associatedPkgs == null) {
943 associatedPkgs = new ArrayList<>();
944 mDisabledUntilUsedPreinstalledCarrierAssociatedApps.put(
945 carrierPkgname, associatedPkgs);
946 }
947 associatedPkgs.add(pkgname);
948 }
949 } else {
950 logNotAllowedInPartition(name, permFile, parser);
951 }
952 XmlUtils.skipCurrentTag(parser);
953 } break;
954 case "disabled-until-used-preinstalled-carrier-app": {
955 if (allowAppConfigs) {
956 String pkgname = parser.getAttributeValue(null, "package");
957 if (pkgname == null) {
958 Slog.w(TAG,
959 "<" + name + "> without "
960 + "package in " + permFile + " at "
961 + parser.getPositionDescription());
962 } else {
963 mDisabledUntilUsedPreinstalledCarrierApps.add(pkgname);
964 }
965 } else {
966 logNotAllowedInPartition(name, permFile, parser);
967 }
968 XmlUtils.skipCurrentTag(parser);
969 } break;
970 case "privapp-permissions": {
971 if (allowPrivappPermissions) {
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900972 // privapp permissions from system, vendor, product and system_ext
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800973 // partitions are stored separately. This is to prevent xml files in
974 // the vendor partition from granting permissions to priv apps in the
975 // system partition and vice versa.
976 boolean vendor = permFile.toPath().startsWith(
977 Environment.getVendorDirectory().toPath() + "/")
978 || permFile.toPath().startsWith(
979 Environment.getOdmDirectory().toPath() + "/");
980 boolean product = permFile.toPath().startsWith(
981 Environment.getProductDirectory().toPath() + "/");
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900982 boolean systemExt = permFile.toPath().startsWith(
983 Environment.getSystemExtDirectory().toPath() + "/");
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800984 if (vendor) {
985 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
986 mVendorPrivAppDenyPermissions);
987 } else if (product) {
988 readPrivAppPermissions(parser, mProductPrivAppPermissions,
989 mProductPrivAppDenyPermissions);
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900990 } else if (systemExt) {
991 readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
992 mSystemExtPrivAppDenyPermissions);
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800993 } else {
994 readPrivAppPermissions(parser, mPrivAppPermissions,
995 mPrivAppDenyPermissions);
996 }
997 } else {
998 logNotAllowedInPartition(name, permFile, parser);
999 XmlUtils.skipCurrentTag(parser);
1000 }
1001 } break;
1002 case "oem-permissions": {
1003 if (allowOemPermissions) {
1004 readOemPermissions(parser);
1005 } else {
1006 logNotAllowedInPartition(name, permFile, parser);
1007 XmlUtils.skipCurrentTag(parser);
1008 }
1009 } break;
1010 case "hidden-api-whitelisted-app": {
1011 if (allowApiWhitelisting) {
1012 String pkgname = parser.getAttributeValue(null, "package");
1013 if (pkgname == null) {
1014 Slog.w(TAG, "<" + name + "> without package in "
1015 + permFile + " at " + parser.getPositionDescription());
1016 } else {
1017 mHiddenApiPackageWhitelist.add(pkgname);
1018 }
1019 } else {
1020 logNotAllowedInPartition(name, permFile, parser);
1021 }
1022 XmlUtils.skipCurrentTag(parser);
1023 } break;
1024 case "allow-association": {
1025 if (allowAssociations) {
1026 String target = parser.getAttributeValue(null, "target");
1027 if (target == null) {
1028 Slog.w(TAG, "<" + name + "> without target in " + permFile
1029 + " at " + parser.getPositionDescription());
1030 XmlUtils.skipCurrentTag(parser);
1031 break;
1032 }
1033 String allowed = parser.getAttributeValue(null, "allowed");
1034 if (allowed == null) {
1035 Slog.w(TAG, "<" + name + "> without allowed in " + permFile
1036 + " at " + parser.getPositionDescription());
1037 XmlUtils.skipCurrentTag(parser);
1038 break;
1039 }
1040 target = target.intern();
1041 allowed = allowed.intern();
1042 ArraySet<String> associations = mAllowedAssociations.get(target);
1043 if (associations == null) {
1044 associations = new ArraySet<>();
1045 mAllowedAssociations.put(target, associations);
1046 }
1047 Slog.i(TAG, "Adding association: " + target + " <- " + allowed);
1048 associations.add(allowed);
1049 } else {
1050 logNotAllowedInPartition(name, permFile, parser);
1051 }
1052 XmlUtils.skipCurrentTag(parser);
1053 } break;
Ricky Wai825d3e92019-12-18 15:16:17 +00001054 case "app-data-isolation-whitelisted-app": {
1055 String pkgname = parser.getAttributeValue(null, "package");
1056 if (pkgname == null) {
1057 Slog.w(TAG, "<" + name + "> without package in " + permFile
1058 + " at " + parser.getPositionDescription());
1059 } else {
1060 mAppDataIsolationWhitelistedApps.add(pkgname);
1061 }
1062 XmlUtils.skipCurrentTag(parser);
1063 } break;
Nikita Ioffe07964b42019-02-28 21:35:02 +00001064 case "bugreport-whitelisted": {
1065 String pkgname = parser.getAttributeValue(null, "package");
1066 if (pkgname == null) {
1067 Slog.w(TAG, "<" + name + "> without package in " + permFile
1068 + " at " + parser.getPositionDescription());
1069 } else {
1070 mBugreportWhitelistedPackages.add(pkgname);
1071 }
Nikita Ioffe08146ef2019-03-13 17:04:21 +00001072 XmlUtils.skipCurrentTag(parser);
Nikita Ioffe07964b42019-02-28 21:35:02 +00001073 } break;
Bookatz04d7ae52019-08-05 14:07:12 -07001074 case "install-in-user-type": {
1075 // NB: We allow any directory permission to declare install-in-user-type.
1076 readInstallInUserType(parser,
1077 mPackageToUserTypeWhitelist, mPackageToUserTypeBlacklist);
1078 } break;
Winsond9d17362019-10-02 12:41:29 -07001079 case "named-actor": {
1080 String namespace = TextUtils.safeIntern(
1081 parser.getAttributeValue(null, "namespace"));
1082 String actorName = parser.getAttributeValue(null, "name");
1083 String pkgName = TextUtils.safeIntern(
1084 parser.getAttributeValue(null, "package"));
1085 if (TextUtils.isEmpty(namespace)) {
1086 Slog.wtf(TAG, "<" + name + "> without namespace in " + permFile
1087 + " at " + parser.getPositionDescription());
1088 } else if (TextUtils.isEmpty(actorName)) {
1089 Slog.wtf(TAG, "<" + name + "> without actor name in " + permFile
1090 + " at " + parser.getPositionDescription());
1091 } else if (TextUtils.isEmpty(pkgName)) {
1092 Slog.wtf(TAG, "<" + name + "> without package name in " + permFile
1093 + " at " + parser.getPositionDescription());
1094 } else if ("android".equalsIgnoreCase(namespace)) {
1095 throw new IllegalStateException("Defining " + actorName + " as "
1096 + pkgName + " for the android namespace is not allowed");
1097 } else {
1098 if (mNamedActors == null) {
1099 mNamedActors = new ArrayMap<>();
1100 }
1101
Winson Chiu2fdaf812019-12-13 20:01:15 +00001102 Map<String, String> nameToPkgMap = mNamedActors.get(namespace);
Winsond9d17362019-10-02 12:41:29 -07001103 if (nameToPkgMap == null) {
1104 nameToPkgMap = new ArrayMap<>();
1105 mNamedActors.put(namespace, nameToPkgMap);
1106 } else if (nameToPkgMap.containsKey(actorName)) {
1107 String existing = nameToPkgMap.get(actorName);
1108 throw new IllegalStateException("Duplicate actor definition for "
1109 + namespace + "/" + actorName
1110 + "; defined as both " + existing + " and " + pkgName);
1111 }
1112
1113 nameToPkgMap.put(actorName, pkgName);
1114 }
1115 XmlUtils.skipCurrentTag(parser);
1116 } break;
JW Wangf0a70b12019-12-11 17:12:02 +08001117 case "rollback-whitelisted-app": {
1118 String pkgname = parser.getAttributeValue(null, "package");
1119 if (pkgname == null) {
1120 Slog.w(TAG, "<" + name + "> without package in " + permFile
1121 + " at " + parser.getPositionDescription());
1122 } else {
1123 mRollbackWhitelistedPackages.add(pkgname);
1124 }
1125 XmlUtils.skipCurrentTag(parser);
1126 } break;
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001127 default: {
1128 Slog.w(TAG, "Tag " + name + " is unknown in "
1129 + permFile + " at " + parser.getPositionDescription());
1130 XmlUtils.skipCurrentTag(parser);
1131 } break;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001132 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001133 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001134 } catch (XmlPullParserException e) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -08001135 Slog.w(TAG, "Got exception parsing permissions.", e);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001136 } catch (IOException e) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -08001137 Slog.w(TAG, "Got exception parsing permissions.", e);
1138 } finally {
1139 IoUtils.closeQuietly(permReader);
1140 }
1141
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001142 // Some devices can be field-converted to FBE, so offer to splice in
1143 // those features if not already defined by the static config
Paul Lawrence20be5d62016-02-26 13:51:17 -08001144 if (StorageManager.isFileEncryptedNativeOnly()) {
Jeff Sharkey115d2c12016-02-15 17:25:57 -07001145 addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
1146 addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001147 }
1148
Jeff Sharkey8eb783b2018-01-04 16:46:48 -07001149 // Help legacy devices that may not have updated their static config
1150 if (StorageManager.hasAdoptable()) {
1151 addFeature(PackageManager.FEATURE_ADOPTABLE_STORAGE, 0);
1152 }
1153
Dianne Hackborn2a103f12017-08-08 15:50:31 -07001154 if (ActivityManager.isLowRamDeviceStatic()) {
1155 addFeature(PackageManager.FEATURE_RAM_LOW, 0);
1156 } else {
1157 addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
1158 }
1159
Alex Buynytskyyd8b25b82020-02-04 11:44:20 -08001160 if (IncrementalManager.isEnabled()) {
1161 addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY, 0);
1162 }
1163
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001164 for (String featureName : mUnavailableFeatures) {
1165 removeFeature(featureName);
1166 }
1167 }
1168
Jeff Sharkey115d2c12016-02-15 17:25:57 -07001169 private void addFeature(String name, int version) {
1170 FeatureInfo fi = mAvailableFeatures.get(name);
1171 if (fi == null) {
1172 fi = new FeatureInfo();
1173 fi.name = name;
1174 fi.version = version;
1175 mAvailableFeatures.put(name, fi);
1176 } else {
1177 fi.version = Math.max(fi.version, version);
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001178 }
1179 }
1180
Jeff Sharkey115d2c12016-02-15 17:25:57 -07001181 private void removeFeature(String name) {
1182 if (mAvailableFeatures.remove(name) != null) {
1183 Slog.d(TAG, "Removed unavailable feature " + name);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001184 }
1185 }
1186
1187 void readPermission(XmlPullParser parser, String name)
1188 throws IOException, XmlPullParserException {
Jeff Sharkey00f39042015-03-23 16:51:22 -07001189 if (mPermissions.containsKey(name)) {
1190 throw new IllegalStateException("Duplicate permission definition for " + name);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001191 }
Jeff Sharkey00f39042015-03-23 16:51:22 -07001192
1193 final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
1194 final PermissionEntry perm = new PermissionEntry(name, perUser);
1195 mPermissions.put(name, perm);
1196
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001197 int outerDepth = parser.getDepth();
1198 int type;
1199 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1200 && (type != XmlPullParser.END_TAG
1201 || parser.getDepth() > outerDepth)) {
1202 if (type == XmlPullParser.END_TAG
1203 || type == XmlPullParser.TEXT) {
1204 continue;
1205 }
1206
1207 String tagName = parser.getName();
1208 if ("group".equals(tagName)) {
1209 String gidStr = parser.getAttributeValue(null, "gid");
1210 if (gidStr != null) {
1211 int gid = Process.getGidForName(gidStr);
1212 perm.gids = appendInt(perm.gids, gid);
1213 } else {
1214 Slog.w(TAG, "<group> without gid at "
1215 + parser.getPositionDescription());
1216 }
1217 }
1218 XmlUtils.skipCurrentTag(parser);
1219 }
1220 }
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001221
Jiyong Park002fdbd2017-02-13 20:50:31 +09001222 private void readPrivAppPermissions(XmlPullParser parser,
1223 ArrayMap<String, ArraySet<String>> grantMap,
1224 ArrayMap<String, ArraySet<String>> denyMap)
1225 throws IOException, XmlPullParserException {
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001226 String packageName = parser.getAttributeValue(null, "package");
1227 if (TextUtils.isEmpty(packageName)) {
1228 Slog.w(TAG, "package is required for <privapp-permissions> in "
1229 + parser.getPositionDescription());
1230 return;
1231 }
1232
Jiyong Park002fdbd2017-02-13 20:50:31 +09001233 ArraySet<String> permissions = grantMap.get(packageName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001234 if (permissions == null) {
1235 permissions = new ArraySet<>();
1236 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001237 ArraySet<String> denyPermissions = denyMap.get(packageName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001238 int depth = parser.getDepth();
1239 while (XmlUtils.nextElementWithin(parser, depth)) {
1240 String name = parser.getName();
1241 if ("permission".equals(name)) {
1242 String permName = parser.getAttributeValue(null, "name");
1243 if (TextUtils.isEmpty(permName)) {
1244 Slog.w(TAG, "name is required for <permission> in "
1245 + parser.getPositionDescription());
1246 continue;
1247 }
1248 permissions.add(permName);
Todd Kennedy74629e32017-08-15 14:48:07 -07001249 } else if ("deny-permission".equals(name)) {
1250 String permName = parser.getAttributeValue(null, "name");
1251 if (TextUtils.isEmpty(permName)) {
1252 Slog.w(TAG, "name is required for <deny-permission> in "
1253 + parser.getPositionDescription());
1254 continue;
1255 }
1256 if (denyPermissions == null) {
1257 denyPermissions = new ArraySet<>();
1258 }
1259 denyPermissions.add(permName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001260 }
1261 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001262 grantMap.put(packageName, permissions);
Todd Kennedy74629e32017-08-15 14:48:07 -07001263 if (denyPermissions != null) {
Jiyong Park002fdbd2017-02-13 20:50:31 +09001264 denyMap.put(packageName, denyPermissions);
Todd Kennedy74629e32017-08-15 14:48:07 -07001265 }
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001266 }
Svet Ganov087dce22017-09-07 15:42:16 -07001267
Bookatz04d7ae52019-08-05 14:07:12 -07001268 private void readInstallInUserType(XmlPullParser parser,
1269 Map<String, Set<String>> doInstallMap,
1270 Map<String, Set<String>> nonInstallMap)
1271 throws IOException, XmlPullParserException {
1272 final String packageName = parser.getAttributeValue(null, "package");
1273 if (TextUtils.isEmpty(packageName)) {
1274 Slog.w(TAG, "package is required for <install-in-user-type> in "
1275 + parser.getPositionDescription());
1276 return;
1277 }
1278
1279 Set<String> userTypesYes = doInstallMap.get(packageName);
1280 Set<String> userTypesNo = nonInstallMap.get(packageName);
1281 final int depth = parser.getDepth();
1282 while (XmlUtils.nextElementWithin(parser, depth)) {
1283 final String name = parser.getName();
1284 if ("install-in".equals(name)) {
1285 final String userType = parser.getAttributeValue(null, "user-type");
1286 if (TextUtils.isEmpty(userType)) {
1287 Slog.w(TAG, "user-type is required for <install-in-user-type> in "
1288 + parser.getPositionDescription());
1289 continue;
1290 }
1291 if (userTypesYes == null) {
1292 userTypesYes = new ArraySet<>();
1293 doInstallMap.put(packageName, userTypesYes);
1294 }
1295 userTypesYes.add(userType);
1296 } else if ("do-not-install-in".equals(name)) {
1297 final String userType = parser.getAttributeValue(null, "user-type");
1298 if (TextUtils.isEmpty(userType)) {
1299 Slog.w(TAG, "user-type is required for <install-in-user-type> in "
1300 + parser.getPositionDescription());
1301 continue;
1302 }
1303 if (userTypesNo == null) {
1304 userTypesNo = new ArraySet<>();
1305 nonInstallMap.put(packageName, userTypesNo);
1306 }
1307 userTypesNo.add(userType);
1308 } else {
1309 Slog.w(TAG, "unrecognized tag in <install-in-user-type> in "
1310 + parser.getPositionDescription());
1311 }
1312 }
1313 }
1314
Svet Ganov087dce22017-09-07 15:42:16 -07001315 void readOemPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
1316 final String packageName = parser.getAttributeValue(null, "package");
1317 if (TextUtils.isEmpty(packageName)) {
1318 Slog.w(TAG, "package is required for <oem-permissions> in "
1319 + parser.getPositionDescription());
1320 return;
1321 }
1322
1323 ArrayMap<String, Boolean> permissions = mOemPermissions.get(packageName);
1324 if (permissions == null) {
1325 permissions = new ArrayMap<>();
1326 }
1327 final int depth = parser.getDepth();
1328 while (XmlUtils.nextElementWithin(parser, depth)) {
1329 final String name = parser.getName();
1330 if ("permission".equals(name)) {
1331 final String permName = parser.getAttributeValue(null, "name");
1332 if (TextUtils.isEmpty(permName)) {
1333 Slog.w(TAG, "name is required for <permission> in "
1334 + parser.getPositionDescription());
1335 continue;
1336 }
1337 permissions.put(permName, Boolean.TRUE);
1338 } else if ("deny-permission".equals(name)) {
1339 String permName = parser.getAttributeValue(null, "name");
1340 if (TextUtils.isEmpty(permName)) {
1341 Slog.w(TAG, "name is required for <deny-permission> in "
1342 + parser.getPositionDescription());
1343 continue;
1344 }
1345 permissions.put(permName, Boolean.FALSE);
1346 }
1347 }
1348 mOemPermissions.put(packageName, permissions);
1349 }
Zimuzocc2932f2018-10-29 16:04:41 +00001350
1351 private void readSplitPermission(XmlPullParser parser, File permFile)
1352 throws IOException, XmlPullParserException {
1353 String splitPerm = parser.getAttributeValue(null, "name");
1354 if (splitPerm == null) {
1355 Slog.w(TAG, "<split-permission> without name in " + permFile + " at "
1356 + parser.getPositionDescription());
1357 XmlUtils.skipCurrentTag(parser);
1358 return;
1359 }
1360 String targetSdkStr = parser.getAttributeValue(null, "targetSdk");
1361 int targetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT + 1;
1362 if (!TextUtils.isEmpty(targetSdkStr)) {
1363 try {
1364 targetSdk = Integer.parseInt(targetSdkStr);
1365 } catch (NumberFormatException e) {
1366 Slog.w(TAG, "<split-permission> targetSdk not an integer in " + permFile + " at "
1367 + parser.getPositionDescription());
1368 XmlUtils.skipCurrentTag(parser);
1369 return;
1370 }
1371 }
1372 final int depth = parser.getDepth();
1373 List<String> newPermissions = new ArrayList<>();
1374 while (XmlUtils.nextElementWithin(parser, depth)) {
1375 String name = parser.getName();
1376 if ("new-permission".equals(name)) {
1377 final String newName = parser.getAttributeValue(null, "name");
1378 if (TextUtils.isEmpty(newName)) {
1379 Slog.w(TAG, "name is required for <new-permission> in "
1380 + parser.getPositionDescription());
1381 continue;
1382 }
1383 newPermissions.add(newName);
1384 } else {
1385 XmlUtils.skipCurrentTag(parser);
1386 }
1387 }
1388 if (!newPermissions.isEmpty()) {
1389 mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
1390 }
1391 }
Anthony Hughde787d42019-08-22 15:35:48 -07001392
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -07001393 private void readComponentOverrides(XmlPullParser parser, File permFile)
1394 throws IOException, XmlPullParserException {
1395 String pkgname = parser.getAttributeValue(null, "package");
1396 if (pkgname == null) {
1397 Slog.w(TAG, "<component-override> without package in "
1398 + permFile + " at " + parser.getPositionDescription());
1399 return;
1400 }
1401
1402 pkgname = pkgname.intern();
1403
1404 final int depth = parser.getDepth();
1405 while (XmlUtils.nextElementWithin(parser, depth)) {
1406 String name = parser.getName();
1407 if ("component".equals(name)) {
1408 String clsname = parser.getAttributeValue(null, "class");
1409 String enabled = parser.getAttributeValue(null, "enabled");
1410 if (clsname == null) {
1411 Slog.w(TAG, "<component> without class in "
1412 + permFile + " at " + parser.getPositionDescription());
1413 return;
1414 } else if (enabled == null) {
1415 Slog.w(TAG, "<component> without enabled in "
1416 + permFile + " at " + parser.getPositionDescription());
1417 return;
1418 }
1419
1420 if (clsname.startsWith(".")) {
1421 clsname = pkgname + clsname;
1422 }
1423
1424 clsname = clsname.intern();
1425
1426 ArrayMap<String, Boolean> componentEnabledStates =
1427 mPackageComponentEnabledState.get(pkgname);
1428 if (componentEnabledStates == null) {
1429 componentEnabledStates = new ArrayMap<>();
1430 mPackageComponentEnabledState.put(pkgname,
1431 componentEnabledStates);
1432 }
1433
1434 componentEnabledStates.put(clsname, !"false".equals(enabled));
1435 } else {
1436 XmlUtils.skipCurrentTag(parser);
1437 }
1438 }
1439 }
1440
Anthony Hughde787d42019-08-22 15:35:48 -07001441 private static boolean isSystemProcess() {
1442 return Process.myUid() == Process.SYSTEM_UID;
1443 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001444}