blob: 578c0cc23a7410e49d2b85f9514a1ebd1c42c624 [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 } break;
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800907 case "backup-transport-whitelisted-service": {
908 if (allowFeatures) {
909 String serviceName = parser.getAttributeValue(null, "service");
910 if (serviceName == null) {
911 Slog.w(TAG, "<" + name + "> without service in "
912 + permFile + " at " + parser.getPositionDescription());
913 } else {
914 ComponentName cn = ComponentName.unflattenFromString(serviceName);
915 if (cn == null) {
916 Slog.w(TAG, "<" + name + "> with invalid service name "
917 + serviceName + " in " + permFile
918 + " at " + parser.getPositionDescription());
919 } else {
920 mBackupTransportWhitelist.add(cn);
921 }
922 }
923 } else {
924 logNotAllowedInPartition(name, permFile, parser);
925 }
926 XmlUtils.skipCurrentTag(parser);
927 } break;
928 case "disabled-until-used-preinstalled-carrier-associated-app": {
929 if (allowAppConfigs) {
930 String pkgname = parser.getAttributeValue(null, "package");
931 String carrierPkgname = parser.getAttributeValue(null,
932 "carrierAppPackage");
933 if (pkgname == null || carrierPkgname == null) {
934 Slog.w(TAG, "<" + name
935 + "> without package or carrierAppPackage in " + permFile
936 + " at " + parser.getPositionDescription());
937 } else {
938 List<String> associatedPkgs =
939 mDisabledUntilUsedPreinstalledCarrierAssociatedApps.get(
940 carrierPkgname);
941 if (associatedPkgs == null) {
942 associatedPkgs = new ArrayList<>();
943 mDisabledUntilUsedPreinstalledCarrierAssociatedApps.put(
944 carrierPkgname, associatedPkgs);
945 }
946 associatedPkgs.add(pkgname);
947 }
948 } else {
949 logNotAllowedInPartition(name, permFile, parser);
950 }
951 XmlUtils.skipCurrentTag(parser);
952 } break;
953 case "disabled-until-used-preinstalled-carrier-app": {
954 if (allowAppConfigs) {
955 String pkgname = parser.getAttributeValue(null, "package");
956 if (pkgname == null) {
957 Slog.w(TAG,
958 "<" + name + "> without "
959 + "package in " + permFile + " at "
960 + parser.getPositionDescription());
961 } else {
962 mDisabledUntilUsedPreinstalledCarrierApps.add(pkgname);
963 }
964 } else {
965 logNotAllowedInPartition(name, permFile, parser);
966 }
967 XmlUtils.skipCurrentTag(parser);
968 } break;
969 case "privapp-permissions": {
970 if (allowPrivappPermissions) {
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900971 // privapp permissions from system, vendor, product and system_ext
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800972 // partitions are stored separately. This is to prevent xml files in
973 // the vendor partition from granting permissions to priv apps in the
974 // system partition and vice versa.
975 boolean vendor = permFile.toPath().startsWith(
976 Environment.getVendorDirectory().toPath() + "/")
977 || permFile.toPath().startsWith(
978 Environment.getOdmDirectory().toPath() + "/");
979 boolean product = permFile.toPath().startsWith(
980 Environment.getProductDirectory().toPath() + "/");
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900981 boolean systemExt = permFile.toPath().startsWith(
982 Environment.getSystemExtDirectory().toPath() + "/");
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800983 if (vendor) {
984 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
985 mVendorPrivAppDenyPermissions);
986 } else if (product) {
987 readPrivAppPermissions(parser, mProductPrivAppPermissions,
988 mProductPrivAppDenyPermissions);
Jeongik Cha9ec059a2019-07-04 21:12:06 +0900989 } else if (systemExt) {
990 readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
991 mSystemExtPrivAppDenyPermissions);
Dianne Hackborn769b2e72018-12-05 08:51:20 -0800992 } else {
993 readPrivAppPermissions(parser, mPrivAppPermissions,
994 mPrivAppDenyPermissions);
995 }
996 } else {
997 logNotAllowedInPartition(name, permFile, parser);
998 XmlUtils.skipCurrentTag(parser);
999 }
1000 } break;
1001 case "oem-permissions": {
1002 if (allowOemPermissions) {
1003 readOemPermissions(parser);
1004 } else {
1005 logNotAllowedInPartition(name, permFile, parser);
1006 XmlUtils.skipCurrentTag(parser);
1007 }
1008 } break;
1009 case "hidden-api-whitelisted-app": {
1010 if (allowApiWhitelisting) {
1011 String pkgname = parser.getAttributeValue(null, "package");
1012 if (pkgname == null) {
1013 Slog.w(TAG, "<" + name + "> without package in "
1014 + permFile + " at " + parser.getPositionDescription());
1015 } else {
1016 mHiddenApiPackageWhitelist.add(pkgname);
1017 }
1018 } else {
1019 logNotAllowedInPartition(name, permFile, parser);
1020 }
1021 XmlUtils.skipCurrentTag(parser);
1022 } break;
1023 case "allow-association": {
1024 if (allowAssociations) {
1025 String target = parser.getAttributeValue(null, "target");
1026 if (target == null) {
1027 Slog.w(TAG, "<" + name + "> without target in " + permFile
1028 + " at " + parser.getPositionDescription());
1029 XmlUtils.skipCurrentTag(parser);
1030 break;
1031 }
1032 String allowed = parser.getAttributeValue(null, "allowed");
1033 if (allowed == null) {
1034 Slog.w(TAG, "<" + name + "> without allowed in " + permFile
1035 + " at " + parser.getPositionDescription());
1036 XmlUtils.skipCurrentTag(parser);
1037 break;
1038 }
1039 target = target.intern();
1040 allowed = allowed.intern();
1041 ArraySet<String> associations = mAllowedAssociations.get(target);
1042 if (associations == null) {
1043 associations = new ArraySet<>();
1044 mAllowedAssociations.put(target, associations);
1045 }
1046 Slog.i(TAG, "Adding association: " + target + " <- " + allowed);
1047 associations.add(allowed);
1048 } else {
1049 logNotAllowedInPartition(name, permFile, parser);
1050 }
1051 XmlUtils.skipCurrentTag(parser);
1052 } break;
Ricky Wai825d3e92019-12-18 15:16:17 +00001053 case "app-data-isolation-whitelisted-app": {
1054 String pkgname = parser.getAttributeValue(null, "package");
1055 if (pkgname == null) {
1056 Slog.w(TAG, "<" + name + "> without package in " + permFile
1057 + " at " + parser.getPositionDescription());
1058 } else {
1059 mAppDataIsolationWhitelistedApps.add(pkgname);
1060 }
1061 XmlUtils.skipCurrentTag(parser);
1062 } break;
Nikita Ioffe07964b42019-02-28 21:35:02 +00001063 case "bugreport-whitelisted": {
1064 String pkgname = parser.getAttributeValue(null, "package");
1065 if (pkgname == null) {
1066 Slog.w(TAG, "<" + name + "> without package in " + permFile
1067 + " at " + parser.getPositionDescription());
1068 } else {
1069 mBugreportWhitelistedPackages.add(pkgname);
1070 }
Nikita Ioffe08146ef2019-03-13 17:04:21 +00001071 XmlUtils.skipCurrentTag(parser);
Nikita Ioffe07964b42019-02-28 21:35:02 +00001072 } break;
Bookatz04d7ae52019-08-05 14:07:12 -07001073 case "install-in-user-type": {
1074 // NB: We allow any directory permission to declare install-in-user-type.
1075 readInstallInUserType(parser,
1076 mPackageToUserTypeWhitelist, mPackageToUserTypeBlacklist);
1077 } break;
Winsond9d17362019-10-02 12:41:29 -07001078 case "named-actor": {
1079 String namespace = TextUtils.safeIntern(
1080 parser.getAttributeValue(null, "namespace"));
1081 String actorName = parser.getAttributeValue(null, "name");
1082 String pkgName = TextUtils.safeIntern(
1083 parser.getAttributeValue(null, "package"));
1084 if (TextUtils.isEmpty(namespace)) {
1085 Slog.wtf(TAG, "<" + name + "> without namespace in " + permFile
1086 + " at " + parser.getPositionDescription());
1087 } else if (TextUtils.isEmpty(actorName)) {
1088 Slog.wtf(TAG, "<" + name + "> without actor name in " + permFile
1089 + " at " + parser.getPositionDescription());
1090 } else if (TextUtils.isEmpty(pkgName)) {
1091 Slog.wtf(TAG, "<" + name + "> without package name in " + permFile
1092 + " at " + parser.getPositionDescription());
1093 } else if ("android".equalsIgnoreCase(namespace)) {
1094 throw new IllegalStateException("Defining " + actorName + " as "
1095 + pkgName + " for the android namespace is not allowed");
1096 } else {
1097 if (mNamedActors == null) {
1098 mNamedActors = new ArrayMap<>();
1099 }
1100
Winson Chiu2fdaf812019-12-13 20:01:15 +00001101 Map<String, String> nameToPkgMap = mNamedActors.get(namespace);
Winsond9d17362019-10-02 12:41:29 -07001102 if (nameToPkgMap == null) {
1103 nameToPkgMap = new ArrayMap<>();
1104 mNamedActors.put(namespace, nameToPkgMap);
1105 } else if (nameToPkgMap.containsKey(actorName)) {
1106 String existing = nameToPkgMap.get(actorName);
1107 throw new IllegalStateException("Duplicate actor definition for "
1108 + namespace + "/" + actorName
1109 + "; defined as both " + existing + " and " + pkgName);
1110 }
1111
1112 nameToPkgMap.put(actorName, pkgName);
1113 }
1114 XmlUtils.skipCurrentTag(parser);
1115 } break;
JW Wangf0a70b12019-12-11 17:12:02 +08001116 case "rollback-whitelisted-app": {
1117 String pkgname = parser.getAttributeValue(null, "package");
1118 if (pkgname == null) {
1119 Slog.w(TAG, "<" + name + "> without package in " + permFile
1120 + " at " + parser.getPositionDescription());
1121 } else {
1122 mRollbackWhitelistedPackages.add(pkgname);
1123 }
1124 XmlUtils.skipCurrentTag(parser);
1125 } break;
Dianne Hackborn769b2e72018-12-05 08:51:20 -08001126 default: {
1127 Slog.w(TAG, "Tag " + name + " is unknown in "
1128 + permFile + " at " + parser.getPositionDescription());
1129 XmlUtils.skipCurrentTag(parser);
1130 } break;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001131 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001132 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001133 } catch (XmlPullParserException e) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -08001134 Slog.w(TAG, "Got exception parsing permissions.", e);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001135 } catch (IOException e) {
Jeff Sharkey1c4ae802014-12-19 11:08:55 -08001136 Slog.w(TAG, "Got exception parsing permissions.", e);
1137 } finally {
1138 IoUtils.closeQuietly(permReader);
1139 }
1140
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001141 // Some devices can be field-converted to FBE, so offer to splice in
1142 // those features if not already defined by the static config
Paul Lawrence20be5d62016-02-26 13:51:17 -08001143 if (StorageManager.isFileEncryptedNativeOnly()) {
Jeff Sharkey115d2c12016-02-15 17:25:57 -07001144 addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
1145 addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001146 }
1147
Jeff Sharkey8eb783b2018-01-04 16:46:48 -07001148 // Help legacy devices that may not have updated their static config
1149 if (StorageManager.hasAdoptable()) {
1150 addFeature(PackageManager.FEATURE_ADOPTABLE_STORAGE, 0);
1151 }
1152
Dianne Hackborn2a103f12017-08-08 15:50:31 -07001153 if (ActivityManager.isLowRamDeviceStatic()) {
1154 addFeature(PackageManager.FEATURE_RAM_LOW, 0);
1155 } else {
1156 addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
1157 }
1158
Alex Buynytskyy8e9e6a32020-02-08 14:26:45 -08001159 if (IncrementalManager.isFeatureEnabled()) {
Alex Buynytskyyd8b25b82020-02-04 11:44:20 -08001160 addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY, 0);
1161 }
1162
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001163 for (String featureName : mUnavailableFeatures) {
1164 removeFeature(featureName);
1165 }
1166 }
1167
Jeff Sharkey115d2c12016-02-15 17:25:57 -07001168 private void addFeature(String name, int version) {
1169 FeatureInfo fi = mAvailableFeatures.get(name);
1170 if (fi == null) {
1171 fi = new FeatureInfo();
1172 fi.name = name;
1173 fi.version = version;
1174 mAvailableFeatures.put(name, fi);
1175 } else {
1176 fi.version = Math.max(fi.version, version);
Jeff Sharkeyb92b05b2016-01-28 09:50:00 -07001177 }
1178 }
1179
Jeff Sharkey115d2c12016-02-15 17:25:57 -07001180 private void removeFeature(String name) {
1181 if (mAvailableFeatures.remove(name) != null) {
1182 Slog.d(TAG, "Removed unavailable feature " + name);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001183 }
1184 }
1185
1186 void readPermission(XmlPullParser parser, String name)
1187 throws IOException, XmlPullParserException {
Jeff Sharkey00f39042015-03-23 16:51:22 -07001188 if (mPermissions.containsKey(name)) {
1189 throw new IllegalStateException("Duplicate permission definition for " + name);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001190 }
Jeff Sharkey00f39042015-03-23 16:51:22 -07001191
1192 final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
1193 final PermissionEntry perm = new PermissionEntry(name, perUser);
1194 mPermissions.put(name, perm);
1195
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001196 int outerDepth = parser.getDepth();
1197 int type;
1198 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1199 && (type != XmlPullParser.END_TAG
1200 || parser.getDepth() > outerDepth)) {
1201 if (type == XmlPullParser.END_TAG
1202 || type == XmlPullParser.TEXT) {
1203 continue;
1204 }
1205
1206 String tagName = parser.getName();
1207 if ("group".equals(tagName)) {
1208 String gidStr = parser.getAttributeValue(null, "gid");
1209 if (gidStr != null) {
1210 int gid = Process.getGidForName(gidStr);
1211 perm.gids = appendInt(perm.gids, gid);
1212 } else {
1213 Slog.w(TAG, "<group> without gid at "
1214 + parser.getPositionDescription());
1215 }
1216 }
1217 XmlUtils.skipCurrentTag(parser);
1218 }
1219 }
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001220
Jiyong Park002fdbd2017-02-13 20:50:31 +09001221 private void readPrivAppPermissions(XmlPullParser parser,
1222 ArrayMap<String, ArraySet<String>> grantMap,
1223 ArrayMap<String, ArraySet<String>> denyMap)
1224 throws IOException, XmlPullParserException {
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001225 String packageName = parser.getAttributeValue(null, "package");
1226 if (TextUtils.isEmpty(packageName)) {
1227 Slog.w(TAG, "package is required for <privapp-permissions> in "
1228 + parser.getPositionDescription());
1229 return;
1230 }
1231
Jiyong Park002fdbd2017-02-13 20:50:31 +09001232 ArraySet<String> permissions = grantMap.get(packageName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001233 if (permissions == null) {
1234 permissions = new ArraySet<>();
1235 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001236 ArraySet<String> denyPermissions = denyMap.get(packageName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001237 int depth = parser.getDepth();
1238 while (XmlUtils.nextElementWithin(parser, depth)) {
1239 String name = parser.getName();
1240 if ("permission".equals(name)) {
1241 String permName = parser.getAttributeValue(null, "name");
1242 if (TextUtils.isEmpty(permName)) {
1243 Slog.w(TAG, "name is required for <permission> in "
1244 + parser.getPositionDescription());
1245 continue;
1246 }
1247 permissions.add(permName);
Todd Kennedy74629e32017-08-15 14:48:07 -07001248 } else if ("deny-permission".equals(name)) {
1249 String permName = parser.getAttributeValue(null, "name");
1250 if (TextUtils.isEmpty(permName)) {
1251 Slog.w(TAG, "name is required for <deny-permission> in "
1252 + parser.getPositionDescription());
1253 continue;
1254 }
1255 if (denyPermissions == null) {
1256 denyPermissions = new ArraySet<>();
1257 }
1258 denyPermissions.add(permName);
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001259 }
1260 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001261 grantMap.put(packageName, permissions);
Todd Kennedy74629e32017-08-15 14:48:07 -07001262 if (denyPermissions != null) {
Jiyong Park002fdbd2017-02-13 20:50:31 +09001263 denyMap.put(packageName, denyPermissions);
Todd Kennedy74629e32017-08-15 14:48:07 -07001264 }
Fyodor Kupolov964d2eb2016-11-09 14:32:27 -08001265 }
Svet Ganov087dce22017-09-07 15:42:16 -07001266
Bookatz04d7ae52019-08-05 14:07:12 -07001267 private void readInstallInUserType(XmlPullParser parser,
1268 Map<String, Set<String>> doInstallMap,
1269 Map<String, Set<String>> nonInstallMap)
1270 throws IOException, XmlPullParserException {
1271 final String packageName = parser.getAttributeValue(null, "package");
1272 if (TextUtils.isEmpty(packageName)) {
1273 Slog.w(TAG, "package is required for <install-in-user-type> in "
1274 + parser.getPositionDescription());
1275 return;
1276 }
1277
1278 Set<String> userTypesYes = doInstallMap.get(packageName);
1279 Set<String> userTypesNo = nonInstallMap.get(packageName);
1280 final int depth = parser.getDepth();
1281 while (XmlUtils.nextElementWithin(parser, depth)) {
1282 final String name = parser.getName();
1283 if ("install-in".equals(name)) {
1284 final String userType = parser.getAttributeValue(null, "user-type");
1285 if (TextUtils.isEmpty(userType)) {
1286 Slog.w(TAG, "user-type is required for <install-in-user-type> in "
1287 + parser.getPositionDescription());
1288 continue;
1289 }
1290 if (userTypesYes == null) {
1291 userTypesYes = new ArraySet<>();
1292 doInstallMap.put(packageName, userTypesYes);
1293 }
1294 userTypesYes.add(userType);
1295 } else if ("do-not-install-in".equals(name)) {
1296 final String userType = parser.getAttributeValue(null, "user-type");
1297 if (TextUtils.isEmpty(userType)) {
1298 Slog.w(TAG, "user-type is required for <install-in-user-type> in "
1299 + parser.getPositionDescription());
1300 continue;
1301 }
1302 if (userTypesNo == null) {
1303 userTypesNo = new ArraySet<>();
1304 nonInstallMap.put(packageName, userTypesNo);
1305 }
1306 userTypesNo.add(userType);
1307 } else {
1308 Slog.w(TAG, "unrecognized tag in <install-in-user-type> in "
1309 + parser.getPositionDescription());
1310 }
1311 }
1312 }
1313
Svet Ganov087dce22017-09-07 15:42:16 -07001314 void readOemPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
1315 final String packageName = parser.getAttributeValue(null, "package");
1316 if (TextUtils.isEmpty(packageName)) {
1317 Slog.w(TAG, "package is required for <oem-permissions> in "
1318 + parser.getPositionDescription());
1319 return;
1320 }
1321
1322 ArrayMap<String, Boolean> permissions = mOemPermissions.get(packageName);
1323 if (permissions == null) {
1324 permissions = new ArrayMap<>();
1325 }
1326 final int depth = parser.getDepth();
1327 while (XmlUtils.nextElementWithin(parser, depth)) {
1328 final String name = parser.getName();
1329 if ("permission".equals(name)) {
1330 final String permName = parser.getAttributeValue(null, "name");
1331 if (TextUtils.isEmpty(permName)) {
1332 Slog.w(TAG, "name is required for <permission> in "
1333 + parser.getPositionDescription());
1334 continue;
1335 }
1336 permissions.put(permName, Boolean.TRUE);
1337 } else if ("deny-permission".equals(name)) {
1338 String permName = parser.getAttributeValue(null, "name");
1339 if (TextUtils.isEmpty(permName)) {
1340 Slog.w(TAG, "name is required for <deny-permission> in "
1341 + parser.getPositionDescription());
1342 continue;
1343 }
1344 permissions.put(permName, Boolean.FALSE);
1345 }
1346 }
1347 mOemPermissions.put(packageName, permissions);
1348 }
Zimuzocc2932f2018-10-29 16:04:41 +00001349
1350 private void readSplitPermission(XmlPullParser parser, File permFile)
1351 throws IOException, XmlPullParserException {
1352 String splitPerm = parser.getAttributeValue(null, "name");
1353 if (splitPerm == null) {
1354 Slog.w(TAG, "<split-permission> without name in " + permFile + " at "
1355 + parser.getPositionDescription());
1356 XmlUtils.skipCurrentTag(parser);
1357 return;
1358 }
1359 String targetSdkStr = parser.getAttributeValue(null, "targetSdk");
1360 int targetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT + 1;
1361 if (!TextUtils.isEmpty(targetSdkStr)) {
1362 try {
1363 targetSdk = Integer.parseInt(targetSdkStr);
1364 } catch (NumberFormatException e) {
1365 Slog.w(TAG, "<split-permission> targetSdk not an integer in " + permFile + " at "
1366 + parser.getPositionDescription());
1367 XmlUtils.skipCurrentTag(parser);
1368 return;
1369 }
1370 }
1371 final int depth = parser.getDepth();
1372 List<String> newPermissions = new ArrayList<>();
1373 while (XmlUtils.nextElementWithin(parser, depth)) {
1374 String name = parser.getName();
1375 if ("new-permission".equals(name)) {
1376 final String newName = parser.getAttributeValue(null, "name");
1377 if (TextUtils.isEmpty(newName)) {
1378 Slog.w(TAG, "name is required for <new-permission> in "
1379 + parser.getPositionDescription());
1380 continue;
1381 }
1382 newPermissions.add(newName);
1383 } else {
1384 XmlUtils.skipCurrentTag(parser);
1385 }
1386 }
1387 if (!newPermissions.isEmpty()) {
1388 mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
1389 }
1390 }
Anthony Hughde787d42019-08-22 15:35:48 -07001391
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -07001392 private void readComponentOverrides(XmlPullParser parser, File permFile)
1393 throws IOException, XmlPullParserException {
1394 String pkgname = parser.getAttributeValue(null, "package");
1395 if (pkgname == null) {
1396 Slog.w(TAG, "<component-override> without package in "
1397 + permFile + " at " + parser.getPositionDescription());
1398 return;
1399 }
1400
1401 pkgname = pkgname.intern();
1402
1403 final int depth = parser.getDepth();
1404 while (XmlUtils.nextElementWithin(parser, depth)) {
Ryan Mitchell1ba81d62020-02-07 14:08:26 -08001405 if ("component".equals(parser.getName())) {
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -07001406 String clsname = parser.getAttributeValue(null, "class");
1407 String enabled = parser.getAttributeValue(null, "enabled");
1408 if (clsname == null) {
1409 Slog.w(TAG, "<component> without class in "
1410 + permFile + " at " + parser.getPositionDescription());
1411 return;
1412 } else if (enabled == null) {
1413 Slog.w(TAG, "<component> without enabled in "
1414 + permFile + " at " + parser.getPositionDescription());
1415 return;
1416 }
1417
1418 if (clsname.startsWith(".")) {
1419 clsname = pkgname + clsname;
1420 }
1421
1422 clsname = clsname.intern();
1423
1424 ArrayMap<String, Boolean> componentEnabledStates =
1425 mPackageComponentEnabledState.get(pkgname);
1426 if (componentEnabledStates == null) {
1427 componentEnabledStates = new ArrayMap<>();
1428 mPackageComponentEnabledState.put(pkgname,
1429 componentEnabledStates);
1430 }
1431
1432 componentEnabledStates.put(clsname, !"false".equals(enabled));
Ryan Mitchell4fd8e6f2019-10-07 16:31:34 -07001433 }
1434 }
1435 }
1436
Anthony Hughde787d42019-08-22 15:35:48 -07001437 private static boolean isSystemProcess() {
1438 return Process.myUid() == Process.SYSTEM_UID;
1439 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001440}