1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
22 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
23 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
24 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
25 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
26 import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
27 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
28 import static android.content.pm.PackageManager.UNINSTALL_REASON_USER_TYPE;
29 import static android.os.Process.PACKAGE_INFO_GID;
30 import static android.os.Process.SYSTEM_UID;
31 
32 import static com.android.server.pm.PackageManagerService.DEBUG_DOMAIN_VERIFICATION;
33 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
34 
35 import android.annotation.NonNull;
36 import android.annotation.Nullable;
37 import android.annotation.UserIdInt;
38 import android.app.compat.ChangeIdStateCache;
39 import android.content.ComponentName;
40 import android.content.Intent;
41 import android.content.IntentFilter;
42 import android.content.pm.ActivityInfo;
43 import android.content.pm.ApplicationInfo;
44 import android.content.pm.ComponentInfo;
45 import android.content.pm.IntentFilterVerificationInfo;
46 import android.content.pm.PackageManager;
47 import android.content.pm.PackageManagerInternal;
48 import android.content.pm.PackageUserState;
49 import android.content.pm.PermissionInfo;
50 import android.content.pm.ResolveInfo;
51 import android.content.pm.Signature;
52 import android.content.pm.SuspendDialogInfo;
53 import android.content.pm.UserInfo;
54 import android.content.pm.VerifierDeviceIdentity;
55 import android.content.pm.parsing.PackageInfoWithoutStateUtils;
56 import android.content.pm.parsing.component.ParsedComponent;
57 import android.content.pm.parsing.component.ParsedIntentInfo;
58 import android.content.pm.parsing.component.ParsedMainComponent;
59 import android.content.pm.parsing.component.ParsedPermission;
60 import android.content.pm.parsing.component.ParsedProcess;
61 import android.net.Uri;
62 import android.os.Binder;
63 import android.os.Build;
64 import android.os.Environment;
65 import android.os.FileUtils;
66 import android.os.Handler;
67 import android.os.Message;
68 import android.os.PatternMatcher;
69 import android.os.PersistableBundle;
70 import android.os.Process;
71 import android.os.SELinux;
72 import android.os.SystemClock;
73 import android.os.Trace;
74 import android.os.UserHandle;
75 import android.os.UserManager;
76 import android.os.storage.StorageManager;
77 import android.service.pm.PackageServiceDumpProto;
78 import android.text.TextUtils;
79 import android.util.ArrayMap;
80 import android.util.ArraySet;
81 import android.util.AtomicFile;
82 import android.util.Log;
83 import android.util.LogPrinter;
84 import android.util.Pair;
85 import android.util.Slog;
86 import android.util.SparseArray;
87 import android.util.SparseBooleanArray;
88 import android.util.SparseIntArray;
89 import android.util.SparseLongArray;
90 import android.util.Xml;
91 import android.util.proto.ProtoOutputStream;
92 
93 import com.android.internal.annotations.GuardedBy;
94 import com.android.internal.annotations.VisibleForTesting;
95 import com.android.internal.os.BackgroundThread;
96 import com.android.internal.util.ArrayUtils;
97 import com.android.internal.util.CollectionUtils;
98 import com.android.internal.util.FastXmlSerializer;
99 import com.android.internal.util.IndentingPrintWriter;
100 import com.android.internal.util.JournaledFile;
101 import com.android.internal.util.XmlUtils;
102 import com.android.permission.persistence.RuntimePermissionsPersistence;
103 import com.android.permission.persistence.RuntimePermissionsState;
104 import com.android.server.LocalServices;
105 import com.android.server.pm.Installer.InstallerException;
106 import com.android.server.pm.parsing.PackageInfoUtils;
107 import com.android.server.pm.parsing.pkg.AndroidPackage;
108 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
109 import com.android.server.pm.permission.BasePermission;
110 import com.android.server.pm.permission.PermissionSettings;
111 import com.android.server.pm.permission.PermissionsState;
112 import com.android.server.pm.permission.PermissionsState.PermissionState;
113 import com.android.server.utils.TimingsTraceAndSlog;
114 
115 import libcore.io.IoUtils;
116 
117 import org.xmlpull.v1.XmlPullParser;
118 import org.xmlpull.v1.XmlPullParserException;
119 import org.xmlpull.v1.XmlSerializer;
120 
121 import java.io.BufferedInputStream;
122 import java.io.BufferedOutputStream;
123 import java.io.BufferedWriter;
124 import java.io.File;
125 import java.io.FileInputStream;
126 import java.io.FileNotFoundException;
127 import java.io.FileOutputStream;
128 import java.io.IOException;
129 import java.io.InputStream;
130 import java.io.OutputStreamWriter;
131 import java.io.PrintWriter;
132 import java.nio.charset.Charset;
133 import java.nio.charset.StandardCharsets;
134 import java.text.SimpleDateFormat;
135 import java.util.ArrayList;
136 import java.util.Arrays;
137 import java.util.Collection;
138 import java.util.Collections;
139 import java.util.Date;
140 import java.util.Iterator;
141 import java.util.List;
142 import java.util.Map;
143 import java.util.Map.Entry;
144 import java.util.Objects;
145 import java.util.Set;
146 
147 /**
148  * Holds information about dynamic settings.
149  */
150 public final class Settings {
151     private static final String TAG = "PackageSettings";
152 
153     /**
154      * Current version of the package database. Set it to the latest version in
155      * the {@link DatabaseVersion} class below to ensure the database upgrade
156      * doesn't happen repeatedly.
157      * <p>
158      * Note that care should be taken to make sure all database upgrades are
159      * idempotent.
160      */
161     public static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
162 
163     /**
164      * This class contains constants that can be referred to from upgrade code.
165      * Insert constant values here that describe the upgrade reason. The version
166      * code must be monotonically increasing.
167      */
168     public static class DatabaseVersion {
169         /**
170          * The initial version of the database.
171          */
172         public static final int FIRST_VERSION = 1;
173 
174         /**
175          * Migrating the Signature array from the entire certificate chain to
176          * just the signing certificate.
177          */
178         public static final int SIGNATURE_END_ENTITY = 2;
179 
180         /**
181          * There was a window of time in
182          * {@link android.os.Build.VERSION_CODES#LOLLIPOP} where we persisted
183          * certificates after potentially mutating them. To switch back to the
184          * original untouched certificates, we need to force a collection pass.
185          */
186         public static final int SIGNATURE_MALFORMED_RECOVER = 3;
187     }
188 
189     private static final boolean DEBUG_STOPPED = false;
190     private static final boolean DEBUG_MU = false;
191     private static final boolean DEBUG_KERNEL = false;
192     private static final boolean DEBUG_PARSER = false;
193 
194     private static final String RUNTIME_PERMISSIONS_FILE_NAME = "runtime-permissions.xml";
195 
196     private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
197     private static final String ATTR_ENFORCEMENT = "enforcement";
198 
199     public static final String TAG_ITEM = "item";
200     private static final String TAG_DISABLED_COMPONENTS = "disabled-components";
201     private static final String TAG_ENABLED_COMPONENTS = "enabled-components";
202     private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions";
203     private static final String TAG_PACKAGE = "pkg";
204     private static final String TAG_SHARED_USER = "shared-user";
205     private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions";
206     private static final String TAG_PERMISSIONS = "perms";
207     private static final String TAG_CHILD_PACKAGE = "child-package";
208     private static final String TAG_USES_STATIC_LIB = "uses-static-lib";
209     private static final String TAG_BLOCK_UNINSTALL_PACKAGES = "block-uninstall-packages";
210     private static final String TAG_BLOCK_UNINSTALL = "block-uninstall";
211 
212     private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
213             "persistent-preferred-activities";
214     static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
215             "crossProfile-intent-filters";
216     private static final String TAG_DOMAIN_VERIFICATION = "domain-verification";
217     private static final String TAG_DEFAULT_APPS = "default-apps";
218     private static final String TAG_ALL_INTENT_FILTER_VERIFICATION =
219             "all-intent-filter-verifications";
220     private static final String TAG_DEFAULT_BROWSER = "default-browser";
221     private static final String TAG_DEFAULT_DIALER = "default-dialer";
222     private static final String TAG_VERSION = "version";
223     /**
224      * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams}
225      */
226     @Deprecated
227     private static final String TAG_SUSPENDED_DIALOG_INFO = "suspended-dialog-info";
228     /**
229      * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams}
230      */
231     @Deprecated
232     private static final String TAG_SUSPENDED_APP_EXTRAS = "suspended-app-extras";
233     /**
234      * @deprecated Moved to {@link android.content.pm.PackageUserState.SuspendParams}
235      */
236     @Deprecated
237     private static final String TAG_SUSPENDED_LAUNCHER_EXTRAS = "suspended-launcher-extras";
238     private static final String TAG_SUSPEND_PARAMS = "suspend-params";
239     private static final String TAG_MIME_GROUP = "mime-group";
240     private static final String TAG_MIME_TYPE = "mime-type";
241 
242     public static final String ATTR_NAME = "name";
243     public static final String ATTR_PACKAGE = "package";
244     private static final String ATTR_GRANTED = "granted";
245     private static final String ATTR_FLAGS = "flags";
246     private static final String ATTR_VERSION = "version";
247 
248     private static final String ATTR_CE_DATA_INODE = "ceDataInode";
249     private static final String ATTR_INSTALLED = "inst";
250     private static final String ATTR_STOPPED = "stopped";
251     private static final String ATTR_NOT_LAUNCHED = "nl";
252     // Legacy, here for reading older versions of the package-restrictions.
253     private static final String ATTR_BLOCKED = "blocked";
254     // New name for the above attribute.
255     private static final String ATTR_HIDDEN = "hidden";
256     private static final String ATTR_DISTRACTION_FLAGS = "distraction_flags";
257     private static final String ATTR_SUSPENDED = "suspended";
258     private static final String ATTR_SUSPENDING_PACKAGE = "suspending-package";
259     /**
260      * @deprecated Legacy attribute, kept only for upgrading from P builds.
261      */
262     @Deprecated
263     private static final String ATTR_SUSPEND_DIALOG_MESSAGE = "suspend_dialog_message";
264     // Legacy, uninstall blocks are stored separately.
265     @Deprecated
266     private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
267     private static final String ATTR_ENABLED = "enabled";
268     private static final String ATTR_ENABLED_CALLER = "enabledCaller";
269     private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
270     private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
271     private static final String ATTR_INSTALL_REASON = "install-reason";
272     private static final String ATTR_UNINSTALL_REASON = "uninstall-reason";
273     private static final String ATTR_INSTANT_APP = "instant-app";
274     private static final String ATTR_VIRTUAL_PRELOAD = "virtual-preload";
275     private static final String ATTR_HARMFUL_APP_WARNING = "harmful-app-warning";
276 
277     private static final String ATTR_PACKAGE_NAME = "packageName";
278     private static final String ATTR_FINGERPRINT = "fingerprint";
279     private static final String ATTR_VOLUME_UUID = "volumeUuid";
280     private static final String ATTR_SDK_VERSION = "sdkVersion";
281     private static final String ATTR_DATABASE_VERSION = "databaseVersion";
282     private static final String ATTR_VALUE = "value";
283 
284     private final Object mLock;
285 
286     private final RuntimePermissionPersistence mRuntimePermissionsPersistence;
287 
288     private final File mSettingsFilename;
289     private final File mBackupSettingsFilename;
290     private final File mPackageListFilename;
291     private final File mStoppedPackagesFilename;
292     private final File mBackupStoppedPackagesFilename;
293     /** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */
294     private final File mKernelMappingFilename;
295 
296     /** Map from package name to settings */
297     final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>();
298 
299     /**
300      * List of packages that were involved in installing other packages, i.e. are listed
301      * in at least one app's InstallSource.
302      */
303     private final ArraySet<String> mInstallerPackages = new ArraySet<>();
304 
305     /** Map from package name to appId and excluded userids */
306     private final ArrayMap<String, KernelPackageState> mKernelMapping = new ArrayMap<>();
307 
308     // List of replaced system applications
309     private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
310         new ArrayMap<String, PackageSetting>();
311 
312     /** List of packages that are blocked for uninstall for specific users */
313     private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>();
314 
315     // Set of restored intent-filter verification states
316     private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
317             new ArrayMap<String, IntentFilterVerificationInfo>();
318 
319     private static final class KernelPackageState {
320         int appId;
321         int[] excludedUserIds;
322     }
323 
324     private static int mFirstAvailableUid = 0;
325 
326     /** Map from volume UUID to {@link VersionInfo} */
327     private ArrayMap<String, VersionInfo> mVersion = new ArrayMap<>();
328 
329     /**
330      * Version details for a storage volume that may hold apps.
331      */
332     public static class VersionInfo {
333         /**
334          * These are the last platform API version we were using for the apps
335          * installed on internal and external storage. It is used to grant newer
336          * permissions one time during a system upgrade.
337          */
338         int sdkVersion;
339 
340         /**
341          * The current database version for apps on internal storage. This is
342          * used to upgrade the format of the packages.xml database not
343          * necessarily tied to an SDK version.
344          */
345         int databaseVersion;
346 
347         /**
348          * Last known value of {@link Build#FINGERPRINT}. Used to determine when
349          * an system update has occurred, meaning we need to clear code caches.
350          */
351         String fingerprint;
352 
353         /**
354          * Force all version information to match current system values,
355          * typically after resolving any required upgrade steps.
356          */
forceCurrent()357         public void forceCurrent() {
358             sdkVersion = Build.VERSION.SDK_INT;
359             databaseVersion = CURRENT_DATABASE_VERSION;
360             fingerprint = Build.FINGERPRINT;
361         }
362     }
363 
364     Boolean mReadExternalStorageEnforced;
365 
366     /** Device identity for the purpose of package verification. */
367     private VerifierDeviceIdentity mVerifierDeviceIdentity;
368 
369     // The user's preferred activities associated with particular intent
370     // filters.
371     final SparseArray<PreferredIntentResolver> mPreferredActivities =
372             new SparseArray<PreferredIntentResolver>();
373 
374     // The persistent preferred activities of the user's profile/device owner
375     // associated with particular intent filters.
376     final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
377             new SparseArray<PersistentPreferredIntentResolver>();
378 
379     // For every user, it is used to find to which other users the intent can be forwarded.
380     final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
381             new SparseArray<CrossProfileIntentResolver>();
382 
383     final ArrayMap<String, SharedUserSetting> mSharedUsers = new ArrayMap<>();
384     private final ArrayList<SettingBase> mAppIds = new ArrayList<>();
385     private final SparseArray<SettingBase> mOtherAppIds = new SparseArray<>();
386 
387     // For reading/writing settings file.
388     private final ArrayList<Signature> mPastSignatures =
389             new ArrayList<Signature>();
390     private final ArrayMap<Long, Integer> mKeySetRefs =
391             new ArrayMap<Long, Integer>();
392 
393     // Packages that have been renamed since they were first installed.
394     // Keys are the new names of the packages, values are the original
395     // names.  The packages appear everywhere else under their original
396     // names.
397     private final ArrayMap<String, String> mRenamedPackages = new ArrayMap<String, String>();
398 
399     // For every user, it is used to find the package name of the default Browser App.
400     final SparseArray<String> mDefaultBrowserApp = new SparseArray<String>();
401 
402     // App-link priority tracking, per-user
403     final SparseIntArray mNextAppLinkGeneration = new SparseIntArray();
404 
405     final StringBuilder mReadMessages = new StringBuilder();
406 
407     /**
408      * Used to track packages that have a shared user ID that hasn't been read
409      * in yet.
410      * <p>
411      * TODO: make this just a local variable that is passed in during package
412      * scanning to make it less confusing.
413      */
414     private final ArrayList<PackageSetting> mPendingPackages = new ArrayList<>();
415 
416     private final File mSystemDir;
417 
418     public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
419     /** Settings and other information about permissions */
420     final PermissionSettings mPermissions;
421 
422     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
Settings(Map<String, PackageSetting> pkgSettings)423     public Settings(Map<String, PackageSetting> pkgSettings) {
424         mLock = new Object();
425         mPackages.putAll(pkgSettings);
426         mSystemDir = null;
427         mPermissions = null;
428         mRuntimePermissionsPersistence = null;
429         mSettingsFilename = null;
430         mBackupSettingsFilename = null;
431         mPackageListFilename = null;
432         mStoppedPackagesFilename = null;
433         mBackupStoppedPackagesFilename = null;
434         mKernelMappingFilename = null;
435     }
436 
Settings(File dataDir, PermissionSettings permission, Object lock)437     Settings(File dataDir, PermissionSettings permission,
438             Object lock) {
439         mLock = lock;
440         mPermissions = permission;
441         mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
442 
443         mSystemDir = new File(dataDir, "system");
444         mSystemDir.mkdirs();
445         FileUtils.setPermissions(mSystemDir.toString(),
446                 FileUtils.S_IRWXU|FileUtils.S_IRWXG
447                 |FileUtils.S_IROTH|FileUtils.S_IXOTH,
448                 -1, -1);
449         mSettingsFilename = new File(mSystemDir, "packages.xml");
450         mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
451         mPackageListFilename = new File(mSystemDir, "packages.list");
452         FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
453 
454         final File kernelDir = new File("/config/sdcardfs");
455         mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
456 
457         // Deprecated: Needed for migration
458         mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
459         mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
460     }
461 
invalidatePackageCache()462     private static void invalidatePackageCache() {
463         PackageManager.invalidatePackageInfoCache();
464         ChangeIdStateCache.invalidate();
465     }
466 
getPackageLPr(String pkgName)467     PackageSetting getPackageLPr(String pkgName) {
468         return mPackages.get(pkgName);
469     }
470 
getRenamedPackageLPr(String pkgName)471     String getRenamedPackageLPr(String pkgName) {
472         return mRenamedPackages.get(pkgName);
473     }
474 
addRenamedPackageLPw(String pkgName, String origPkgName)475     String addRenamedPackageLPw(String pkgName, String origPkgName) {
476         return mRenamedPackages.put(pkgName, origPkgName);
477     }
478 
canPropagatePermissionToInstantApp(String permName)479     public boolean canPropagatePermissionToInstantApp(String permName) {
480         return mPermissions.canPropagatePermissionToInstantApp(permName);
481     }
482 
483     /** Gets and optionally creates a new shared user id. */
getSharedUserLPw(String name, int pkgFlags, int pkgPrivateFlags, boolean create)484     SharedUserSetting getSharedUserLPw(String name, int pkgFlags, int pkgPrivateFlags,
485             boolean create) throws PackageManagerException {
486         SharedUserSetting s = mSharedUsers.get(name);
487         if (s == null && create) {
488             s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
489             s.userId = acquireAndRegisterNewAppIdLPw(s);
490             if (s.userId < 0) {
491                 // < 0 means we couldn't assign a userid; throw exception
492                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
493                         "Creating shared user " + name + " failed");
494             }
495             Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
496             mSharedUsers.put(name, s);
497         }
498         return s;
499     }
500 
getAllSharedUsersLPw()501     Collection<SharedUserSetting> getAllSharedUsersLPw() {
502         return mSharedUsers.values();
503     }
504 
disableSystemPackageLPw(String name, boolean replaced)505     boolean disableSystemPackageLPw(String name, boolean replaced) {
506         final PackageSetting p = mPackages.get(name);
507         if(p == null) {
508             Log.w(PackageManagerService.TAG, "Package " + name + " is not an installed package");
509             return false;
510         }
511         final PackageSetting dp = mDisabledSysPackages.get(name);
512         // always make sure the system package code and resource paths dont change
513         if (dp == null && p.pkg != null && p.pkg.isSystem()
514                 && !p.getPkgState().isUpdatedSystemApp()) {
515             p.getPkgState().setUpdatedSystemApp(true);
516             final PackageSetting disabled;
517             if (replaced) {
518                 // a little trick...  when we install the new package, we don't
519                 // want to modify the existing PackageSetting for the built-in
520                 // version.  so at this point we make a copy to place into the
521                 // disabled set.
522                 disabled = new PackageSetting(p);
523             } else {
524                 disabled = p;
525             }
526             mDisabledSysPackages.put(name, disabled);
527 
528             return true;
529         }
530         return false;
531     }
532 
enableSystemPackageLPw(String name)533     PackageSetting enableSystemPackageLPw(String name) {
534         PackageSetting p = mDisabledSysPackages.get(name);
535         if(p == null) {
536             Log.w(PackageManagerService.TAG, "Package " + name + " is not disabled");
537             return null;
538         }
539         p.getPkgState().setUpdatedSystemApp(false);
540         PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
541                 p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
542                 p.secondaryCpuAbiString, p.cpuAbiOverrideString,
543                 p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
544                 p.usesStaticLibraries, p.usesStaticLibrariesVersions, p.mimeGroups);
545         if (ret != null) {
546             ret.getPkgState().setUpdatedSystemApp(false);
547         }
548         mDisabledSysPackages.remove(name);
549         return ret;
550     }
551 
isDisabledSystemPackageLPr(String name)552     boolean isDisabledSystemPackageLPr(String name) {
553         return mDisabledSysPackages.containsKey(name);
554     }
555 
removeDisabledSystemPackageLPw(String name)556     void removeDisabledSystemPackageLPw(String name) {
557         mDisabledSysPackages.remove(name);
558     }
559 
addPackageLPw(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries, long[] usesStaticLibraryNames, Map<String, ArraySet<String>> mimeGroups)560     PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
561             String legacyNativeLibraryPathString, String primaryCpuAbiString,
562             String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int
563             pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries,
564             long[] usesStaticLibraryNames, Map<String, ArraySet<String>> mimeGroups) {
565         PackageSetting p = mPackages.get(name);
566         if (p != null) {
567             if (p.appId == uid) {
568                 return p;
569             }
570             PackageManagerService.reportSettingsProblem(Log.ERROR,
571                     "Adding duplicate package, keeping first: " + name);
572             return null;
573         }
574         p = new PackageSetting(name, realName, codePath, resourcePath,
575                 legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString,
576                 cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags,
577                 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames,
578                 mimeGroups);
579         p.appId = uid;
580         if (registerExistingAppIdLPw(uid, p, name)) {
581             mPackages.put(name, p);
582             return p;
583         }
584         return null;
585     }
586 
addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags)587     SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
588         SharedUserSetting s = mSharedUsers.get(name);
589         if (s != null) {
590             if (s.userId == uid) {
591                 return s;
592             }
593             PackageManagerService.reportSettingsProblem(Log.ERROR,
594                     "Adding duplicate shared user, keeping first: " + name);
595             return null;
596         }
597         s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
598         s.userId = uid;
599         if (registerExistingAppIdLPw(uid, s, name)) {
600             mSharedUsers.put(name, s);
601             return s;
602         }
603         return null;
604     }
605 
pruneSharedUsersLPw()606     void pruneSharedUsersLPw() {
607         ArrayList<String> removeStage = new ArrayList<String>();
608         for (Map.Entry<String,SharedUserSetting> entry : mSharedUsers.entrySet()) {
609             final SharedUserSetting sus = entry.getValue();
610             if (sus == null) {
611                 removeStage.add(entry.getKey());
612                 continue;
613             }
614             // remove packages that are no longer installed
615             for (Iterator<PackageSetting> iter = sus.packages.iterator(); iter.hasNext();) {
616                 PackageSetting ps = iter.next();
617                 if (mPackages.get(ps.name) == null) {
618                     iter.remove();
619                 }
620             }
621             if (sus.packages.size() == 0) {
622                 removeStage.add(entry.getKey());
623             }
624         }
625         for (int i = 0; i < removeStage.size(); i++) {
626             mSharedUsers.remove(removeStage.get(i));
627         }
628     }
629 
630     /**
631      * Creates a new {@code PackageSetting} object.
632      * Use this method instead of the constructor to ensure a settings object is created
633      * with the correct base.
634      */
createNewSetting(String pkgName, PackageSetting originalPkg, PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser, File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi, String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags, UserHandle installUser, boolean allowInstall, boolean instantApp, boolean virtualPreload, UserManagerService userManager, String[] usesStaticLibraries, long[] usesStaticLibrariesVersions, Set<String> mimeGroupNames)635     static @NonNull PackageSetting createNewSetting(String pkgName, PackageSetting originalPkg,
636             PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser,
637             File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi,
638             String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags,
639             UserHandle installUser, boolean allowInstall, boolean instantApp,
640             boolean virtualPreload, UserManagerService userManager,
641             String[] usesStaticLibraries, long[] usesStaticLibrariesVersions,
642             Set<String> mimeGroupNames) {
643         final PackageSetting pkgSetting;
644         if (originalPkg != null) {
645             if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
646                     + pkgName + " is adopting original package " + originalPkg.name);
647             pkgSetting = new PackageSetting(originalPkg, pkgName /*realPkgName*/);
648             pkgSetting.codePath = codePath;
649             pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath;
650             pkgSetting.pkgFlags = pkgFlags;
651             pkgSetting.pkgPrivateFlags = pkgPrivateFlags;
652             pkgSetting.primaryCpuAbiString = primaryCpuAbi;
653             pkgSetting.resourcePath = resourcePath;
654             pkgSetting.secondaryCpuAbiString = secondaryCpuAbi;
655             // NOTE: Create a deeper copy of the package signatures so we don't
656             // overwrite the signatures in the original package setting.
657             pkgSetting.signatures = new PackageSignatures();
658             pkgSetting.versionCode = versionCode;
659             pkgSetting.usesStaticLibraries = usesStaticLibraries;
660             pkgSetting.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
661             // Update new package state.
662             pkgSetting.setTimeStamp(codePath.lastModified());
663         } else {
664             pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, resourcePath,
665                     legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi,
666                     null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags,
667                     0 /*sharedUserId*/, usesStaticLibraries,
668                     usesStaticLibrariesVersions, createMimeGroups(mimeGroupNames));
669             pkgSetting.setTimeStamp(codePath.lastModified());
670             pkgSetting.sharedUser = sharedUser;
671             // If this is not a system app, it starts out stopped.
672             if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
673                 if (DEBUG_STOPPED) {
674                     RuntimeException e = new RuntimeException("here");
675                     e.fillInStackTrace();
676                     Slog.i(PackageManagerService.TAG, "Stopping package " + pkgName, e);
677                 }
678                 List<UserInfo> users = getAllUsers(userManager);
679                 final int installUserId = installUser != null ? installUser.getIdentifier() : 0;
680                 if (users != null && allowInstall) {
681                     for (UserInfo user : users) {
682                         // By default we consider this app to be installed
683                         // for the user if no user has been specified (which
684                         // means to leave it at its original value, and the
685                         // original default value is true), or we are being
686                         // asked to install for all users, or this is the
687                         // user we are installing for.
688                         final boolean installed = installUser == null
689                                 || (installUserId == UserHandle.USER_ALL
690                                     && !isAdbInstallDisallowed(userManager, user.id))
691                                 || installUserId == user.id;
692                         pkgSetting.setUserState(user.id, 0, COMPONENT_ENABLED_STATE_DEFAULT,
693                                 installed,
694                                 true /*stopped*/,
695                                 true /*notLaunched*/,
696                                 false /*hidden*/,
697                                 0 /*distractionFlags*/,
698                                 false /*suspended*/,
699                                 null /*suspendParams*/,
700                                 instantApp,
701                                 virtualPreload,
702                                 null /*lastDisableAppCaller*/,
703                                 null /*enabledComponents*/,
704                                 null /*disabledComponents*/,
705                                 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
706                                 0 /*linkGeneration*/,
707                                 PackageManager.INSTALL_REASON_UNKNOWN,
708                                 PackageManager.UNINSTALL_REASON_UNKNOWN,
709                                 null /*harmfulAppWarning*/);
710                     }
711                 }
712             }
713             if (sharedUser != null) {
714                 pkgSetting.appId = sharedUser.userId;
715             } else {
716                 // Clone the setting here for disabled system packages
717                 if (disabledPkg != null) {
718                     // For disabled packages a new setting is created
719                     // from the existing user id. This still has to be
720                     // added to list of user id's
721                     // Copy signatures from previous setting
722                     pkgSetting.signatures = new PackageSignatures(disabledPkg.signatures);
723                     pkgSetting.appId = disabledPkg.appId;
724                     // Clone permissions
725                     pkgSetting.getPermissionsState().copyFrom(disabledPkg.getPermissionsState());
726                     // Clone component info
727                     List<UserInfo> users = getAllUsers(userManager);
728                     if (users != null) {
729                         for (UserInfo user : users) {
730                             final int userId = user.id;
731                             pkgSetting.setDisabledComponentsCopy(
732                                     disabledPkg.getDisabledComponents(userId), userId);
733                             pkgSetting.setEnabledComponentsCopy(
734                                     disabledPkg.getEnabledComponents(userId), userId);
735                         }
736                     }
737                 }
738             }
739         }
740         return pkgSetting;
741     }
742 
createMimeGroups(Set<String> mimeGroupNames)743     private static Map<String, ArraySet<String>> createMimeGroups(Set<String> mimeGroupNames) {
744         if (mimeGroupNames == null) {
745             return null;
746         }
747 
748         return new KeySetToValueMap<>(mimeGroupNames, new ArraySet<>());
749     }
750 
751     /**
752      * Updates the given package setting using the provided information.
753      * <p>
754      * WARNING: The provided PackageSetting object may be mutated.
755      */
updatePackageSetting(@onNull PackageSetting pkgSetting, @Nullable PackageSetting disabledPkg, @Nullable SharedUserSetting sharedUser, @NonNull File codePath, File resourcePath, @Nullable String legacyNativeLibraryPath, @Nullable String primaryCpuAbi, @Nullable String secondaryCpuAbi, int pkgFlags, int pkgPrivateFlags, @NonNull UserManagerService userManager, @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions, @Nullable Set<String> mimeGroupNames)756     static void updatePackageSetting(@NonNull PackageSetting pkgSetting,
757             @Nullable PackageSetting disabledPkg, @Nullable SharedUserSetting sharedUser,
758             @NonNull File codePath, File resourcePath,
759             @Nullable String legacyNativeLibraryPath, @Nullable String primaryCpuAbi,
760             @Nullable String secondaryCpuAbi, int pkgFlags, int pkgPrivateFlags,
761             @NonNull UserManagerService userManager,
762             @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions,
763             @Nullable Set<String> mimeGroupNames)
764                     throws PackageManagerException {
765         final String pkgName = pkgSetting.name;
766         if (pkgSetting.sharedUser != sharedUser) {
767             PackageManagerService.reportSettingsProblem(Log.WARN,
768                     "Package " + pkgName + " shared user changed from "
769                     + (pkgSetting.sharedUser != null ? pkgSetting.sharedUser.name : "<nothing>")
770                     + " to " + (sharedUser != null ? sharedUser.name : "<nothing>"));
771             throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
772                     "Updating application package " + pkgName + " failed");
773         }
774 
775         if (!pkgSetting.codePath.equals(codePath)) {
776             final boolean isSystem = pkgSetting.isSystem();
777             Slog.i(PackageManagerService.TAG,
778                     "Update" + (isSystem ? " system" : "")
779                     + " package " + pkgName
780                     + " code path from " + pkgSetting.codePathString
781                     + " to " + codePath.toString()
782                     + "; Retain data and using new");
783             if (!isSystem) {
784                 // The package isn't considered as installed if the application was
785                 // first installed by another user. Update the installed flag when the
786                 // application ever becomes part of the system.
787                 if ((pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0 && disabledPkg == null) {
788                     final List<UserInfo> allUserInfos = getAllUsers(userManager);
789                     if (allUserInfos != null) {
790                         for (UserInfo userInfo : allUserInfos) {
791                             pkgSetting.setInstalled(true, userInfo.id);
792                             pkgSetting.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userInfo.id);
793                         }
794                     }
795                 }
796 
797                 // Since we've changed paths, prefer the new native library path over
798                 // the one stored in the package settings since we might have moved from
799                 // internal to external storage or vice versa.
800                 pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath;
801             }
802             pkgSetting.codePath = codePath;
803             pkgSetting.codePathString = codePath.toString();
804         }
805         if (!pkgSetting.resourcePath.equals(resourcePath)) {
806             final boolean isSystem = pkgSetting.isSystem();
807             Slog.i(PackageManagerService.TAG,
808                     "Update" + (isSystem ? " system" : "")
809                     + " package " + pkgName
810                     + " resource path from " + pkgSetting.resourcePathString
811                     + " to " + resourcePath.toString()
812                     + "; Retain data and using new");
813             pkgSetting.resourcePath = resourcePath;
814             pkgSetting.resourcePathString = resourcePath.toString();
815         }
816         // If what we are scanning is a system (and possibly privileged) package,
817         // then make it so, regardless of whether it was previously installed only
818         // in the data partition. Reset first.
819         pkgSetting.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
820         pkgSetting.pkgPrivateFlags &= ~(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
821                 | ApplicationInfo.PRIVATE_FLAG_OEM
822                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
823                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
824                 | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
825                 | ApplicationInfo.PRIVATE_FLAG_ODM);
826         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
827         pkgSetting.pkgPrivateFlags |=
828                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
829         pkgSetting.pkgPrivateFlags |=
830                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM;
831         pkgSetting.pkgPrivateFlags |=
832                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR;
833         pkgSetting.pkgPrivateFlags |=
834                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT;
835         pkgSetting.pkgPrivateFlags |=
836                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
837         pkgSetting.pkgPrivateFlags |=
838                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
839         pkgSetting.primaryCpuAbiString = primaryCpuAbi;
840         pkgSetting.secondaryCpuAbiString = secondaryCpuAbi;
841         // Update static shared library dependencies if needed
842         if (usesStaticLibraries != null && usesStaticLibrariesVersions != null
843                 && usesStaticLibraries.length == usesStaticLibrariesVersions.length) {
844             pkgSetting.usesStaticLibraries = usesStaticLibraries;
845             pkgSetting.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
846         } else {
847             pkgSetting.usesStaticLibraries = null;
848             pkgSetting.usesStaticLibrariesVersions = null;
849         }
850         pkgSetting.updateMimeGroups(mimeGroupNames);
851     }
852 
853     /**
854      * Registers a user ID with the system. Potentially allocates a new user ID.
855      * @return {@code true} if a new app ID was created in the process. {@code false} can be
856      *         returned in the case that a shared user ID already exists or the explicit app ID is
857      *         already registered.
858      * @throws PackageManagerException If a user ID could not be allocated.
859      */
registerAppIdLPw(PackageSetting p)860     boolean registerAppIdLPw(PackageSetting p) throws PackageManagerException {
861         final boolean createdNew;
862         if (p.appId == 0) {
863             // Assign new user ID
864             p.appId = acquireAndRegisterNewAppIdLPw(p);
865             createdNew = true;
866         } else {
867             // Add new setting to list of user IDs
868             createdNew = registerExistingAppIdLPw(p.appId, p, p.name);
869         }
870         if (p.appId < 0) {
871             PackageManagerService.reportSettingsProblem(Log.WARN,
872                     "Package " + p.name + " could not be assigned a valid UID");
873             throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
874                     "Package " + p.name + " could not be assigned a valid UID");
875         }
876         return createdNew;
877     }
878 
879     /**
880      * Writes per-user package restrictions if the user state has changed. If the user
881      * state has not changed, this does nothing.
882      */
writeUserRestrictionsLPw(PackageSetting newPackage, PackageSetting oldPackage)883     void writeUserRestrictionsLPw(PackageSetting newPackage, PackageSetting oldPackage) {
884         // package doesn't exist; do nothing
885         if (getPackageLPr(newPackage.name) == null) {
886             return;
887         }
888         // no users defined; do nothing
889         final List<UserInfo> allUsers = getAllUsers(UserManagerService.getInstance());
890         if (allUsers == null) {
891             return;
892         }
893         for (UserInfo user : allUsers) {
894             final PackageUserState oldUserState = oldPackage == null
895                     ? PackageSettingBase.DEFAULT_USER_STATE
896                     : oldPackage.readUserState(user.id);
897             if (!oldUserState.equals(newPackage.readUserState(user.id))) {
898                 writePackageRestrictionsLPr(user.id);
899             }
900         }
901     }
902 
isAdbInstallDisallowed(UserManagerService userManager, int userId)903     static boolean isAdbInstallDisallowed(UserManagerService userManager, int userId) {
904         return userManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
905                 userId);
906     }
907 
908     // TODO: Move to scanPackageOnlyLI() after verifying signatures are setup correctly
909     // by that time.
insertPackageSettingLPw(PackageSetting p, AndroidPackage pkg)910     void insertPackageSettingLPw(PackageSetting p, AndroidPackage pkg) {
911         // Update signatures if needed.
912         if (p.signatures.mSigningDetails.signatures == null) {
913             p.signatures.mSigningDetails = pkg.getSigningDetails();
914         }
915         // If this app defines a shared user id initialize
916         // the shared user signatures as well.
917         if (p.sharedUser != null && p.sharedUser.signatures.mSigningDetails.signatures == null) {
918             p.sharedUser.signatures.mSigningDetails = pkg.getSigningDetails();
919         }
920         addPackageSettingLPw(p, p.sharedUser);
921     }
922 
923     // Utility method that adds a PackageSetting to mPackages and
924     // completes updating the shared user attributes and any restored
925     // app link verification state
addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser)926     private void addPackageSettingLPw(PackageSetting p, SharedUserSetting sharedUser) {
927         mPackages.put(p.name, p);
928         if (sharedUser != null) {
929             if (p.sharedUser != null && p.sharedUser != sharedUser) {
930                 PackageManagerService.reportSettingsProblem(Log.ERROR,
931                         "Package " + p.name + " was user "
932                         + p.sharedUser + " but is now " + sharedUser
933                         + "; I am not changing its files so it will probably fail!");
934                 p.sharedUser.removePackage(p);
935             } else if (p.appId != sharedUser.userId) {
936                 PackageManagerService.reportSettingsProblem(Log.ERROR,
937                     "Package " + p.name + " was user id " + p.appId
938                     + " but is now user " + sharedUser
939                     + " with id " + sharedUser.userId
940                     + "; I am not changing its files so it will probably fail!");
941             }
942 
943             sharedUser.addPackage(p);
944             p.sharedUser = sharedUser;
945             p.appId = sharedUser.userId;
946         }
947 
948         // If the we know about this user id, we have to update it as it
949         // has to point to the same PackageSetting instance as the package.
950         Object userIdPs = getSettingLPr(p.appId);
951         if (sharedUser == null) {
952             if (userIdPs != null && userIdPs != p) {
953                 replaceAppIdLPw(p.appId, p);
954             }
955         } else {
956             if (userIdPs != null && userIdPs != sharedUser) {
957                 replaceAppIdLPw(p.appId, sharedUser);
958             }
959         }
960 
961         IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(p.name);
962         if (ivi != null) {
963             if (DEBUG_DOMAIN_VERIFICATION) {
964                 Slog.i(TAG, "Applying restored IVI for " + p.name + " : " + ivi.getStatusString());
965             }
966             mRestoredIntentFilterVerifications.remove(p.name);
967             p.setIntentFilterVerificationInfo(ivi);
968         }
969     }
970 
971     /*
972      * Update the shared user setting when a package with a shared user id is removed. The gids
973      * associated with each permission of the deleted package are removed from the shared user'
974      * gid list only if its not in use by other permissions of packages in the shared user setting.
975      *
976      * @return the affected user id
977      */
978     @UserIdInt
updateSharedUserPermsLPw(PackageSetting deletedPs, int userId)979     int updateSharedUserPermsLPw(PackageSetting deletedPs, int userId) {
980         if ((deletedPs == null) || (deletedPs.pkg == null)) {
981             Slog.i(PackageManagerService.TAG,
982                     "Trying to update info for null package. Just ignoring");
983             return UserHandle.USER_NULL;
984         }
985 
986         // No sharedUserId
987         if (deletedPs.sharedUser == null) {
988             return UserHandle.USER_NULL;
989         }
990 
991         SharedUserSetting sus = deletedPs.sharedUser;
992 
993         int affectedUserId = UserHandle.USER_NULL;
994         // Update permissions
995         for (String eachPerm : deletedPs.pkg.getRequestedPermissions()) {
996             BasePermission bp = mPermissions.getPermission(eachPerm);
997             if (bp == null) {
998                 continue;
999             }
1000 
1001             // Check if another package in the shared user needs the permission.
1002             boolean used = false;
1003             for (PackageSetting pkg : sus.packages) {
1004                 if (pkg.pkg != null
1005                         && !pkg.pkg.getPackageName().equals(deletedPs.pkg.getPackageName())
1006                         && pkg.pkg.getRequestedPermissions().contains(eachPerm)) {
1007                     used = true;
1008                     break;
1009                 }
1010             }
1011             if (used) {
1012                 continue;
1013             }
1014 
1015             PermissionsState permissionsState = sus.getPermissionsState();
1016             PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.getPackageName());
1017 
1018             // If the package is shadowing is a disabled system package,
1019             // do not drop permissions that the shadowed package requests.
1020             if (disabledPs != null) {
1021                 boolean reqByDisabledSysPkg = false;
1022                 for (String permission : disabledPs.pkg.getRequestedPermissions()) {
1023                     if (permission.equals(eachPerm)) {
1024                         reqByDisabledSysPkg = true;
1025                         break;
1026                     }
1027                 }
1028                 if (reqByDisabledSysPkg) {
1029                     continue;
1030                 }
1031             }
1032 
1033             // Try to revoke as an install permission which is for all users.
1034             // The package is gone - no need to keep flags for applying policy.
1035             permissionsState.updatePermissionFlags(bp, userId,
1036                     PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
1037 
1038             if (permissionsState.revokeInstallPermission(bp) ==
1039                     PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
1040                 affectedUserId = UserHandle.USER_ALL;
1041             }
1042 
1043             // Try to revoke as an install permission which is per user.
1044             if (permissionsState.revokeRuntimePermission(bp, userId) ==
1045                     PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
1046                 if (affectedUserId == UserHandle.USER_NULL) {
1047                     affectedUserId = userId;
1048                 } else if (affectedUserId != userId) {
1049                     // Multiple users affected.
1050                     affectedUserId = UserHandle.USER_ALL;
1051                 }
1052             }
1053         }
1054 
1055         return affectedUserId;
1056     }
1057 
removePackageLPw(String name)1058     int removePackageLPw(String name) {
1059         final PackageSetting p = mPackages.get(name);
1060         if (p != null) {
1061             mPackages.remove(name);
1062             removeInstallerPackageStatus(name);
1063             if (p.sharedUser != null) {
1064                 p.sharedUser.removePackage(p);
1065                 if (p.sharedUser.packages.size() == 0) {
1066                     mSharedUsers.remove(p.sharedUser.name);
1067                     removeAppIdLPw(p.sharedUser.userId);
1068                     return p.sharedUser.userId;
1069                 }
1070             } else {
1071                 removeAppIdLPw(p.appId);
1072                 return p.appId;
1073             }
1074         }
1075         return -1;
1076     }
1077 
1078     /**
1079      * Checks if {@param packageName} is an installer package and if so, clear the installer
1080      * package name of the packages that are installed by this.
1081      */
removeInstallerPackageStatus(String packageName)1082     private void removeInstallerPackageStatus(String packageName) {
1083         // Check if the package to be removed is an installer package.
1084         if (!mInstallerPackages.contains(packageName)) {
1085             return;
1086         }
1087         for (int i = 0; i < mPackages.size(); i++) {
1088             mPackages.valueAt(i).removeInstallerPackage(packageName);
1089         }
1090         mInstallerPackages.remove(packageName);
1091     }
1092 
1093     /** Returns true if the requested AppID was valid and not already registered. */
registerExistingAppIdLPw(int appId, SettingBase obj, Object name)1094     private boolean registerExistingAppIdLPw(int appId, SettingBase obj, Object name) {
1095         if (appId > Process.LAST_APPLICATION_UID) {
1096             return false;
1097         }
1098 
1099         if (appId >= Process.FIRST_APPLICATION_UID) {
1100             int size = mAppIds.size();
1101             final int index = appId - Process.FIRST_APPLICATION_UID;
1102             // fill the array until our index becomes valid
1103             while (index >= size) {
1104                 mAppIds.add(null);
1105                 size++;
1106             }
1107             if (mAppIds.get(index) != null) {
1108                 PackageManagerService.reportSettingsProblem(Log.ERROR,
1109                         "Adding duplicate app id: " + appId
1110                         + " name=" + name);
1111                 return false;
1112             }
1113             mAppIds.set(index, obj);
1114         } else {
1115             if (mOtherAppIds.get(appId) != null) {
1116                 PackageManagerService.reportSettingsProblem(Log.ERROR,
1117                         "Adding duplicate shared id: " + appId
1118                                 + " name=" + name);
1119                 return false;
1120             }
1121             mOtherAppIds.put(appId, obj);
1122         }
1123         return true;
1124     }
1125 
1126     /** Gets the setting associated with the provided App ID */
getSettingLPr(int appId)1127     public SettingBase getSettingLPr(int appId) {
1128         if (appId >= Process.FIRST_APPLICATION_UID) {
1129             final int size = mAppIds.size();
1130             final int index = appId - Process.FIRST_APPLICATION_UID;
1131             return index < size ? mAppIds.get(index) : null;
1132         } else {
1133             return mOtherAppIds.get(appId);
1134         }
1135     }
1136 
1137     /** Unregisters the provided app ID. */
removeAppIdLPw(int appId)1138     void removeAppIdLPw(int appId) {
1139         if (appId >= Process.FIRST_APPLICATION_UID) {
1140             final int size = mAppIds.size();
1141             final int index = appId - Process.FIRST_APPLICATION_UID;
1142             if (index < size) mAppIds.set(index, null);
1143         } else {
1144             mOtherAppIds.remove(appId);
1145         }
1146         setFirstAvailableUid(appId + 1);
1147     }
1148 
replaceAppIdLPw(int appId, SettingBase obj)1149     private void replaceAppIdLPw(int appId, SettingBase obj) {
1150         if (appId >= Process.FIRST_APPLICATION_UID) {
1151             final int size = mAppIds.size();
1152             final int index = appId - Process.FIRST_APPLICATION_UID;
1153             if (index < size) mAppIds.set(index, obj);
1154         } else {
1155             mOtherAppIds.put(appId, obj);
1156         }
1157     }
1158 
editPreferredActivitiesLPw(int userId)1159     PreferredIntentResolver editPreferredActivitiesLPw(int userId) {
1160         PreferredIntentResolver pir = mPreferredActivities.get(userId);
1161         if (pir == null) {
1162             pir = new PreferredIntentResolver();
1163             mPreferredActivities.put(userId, pir);
1164         }
1165         return pir;
1166     }
1167 
editPersistentPreferredActivitiesLPw(int userId)1168     PersistentPreferredIntentResolver editPersistentPreferredActivitiesLPw(int userId) {
1169         PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1170         if (ppir == null) {
1171             ppir = new PersistentPreferredIntentResolver();
1172             mPersistentPreferredActivities.put(userId, ppir);
1173         }
1174         return ppir;
1175     }
1176 
editCrossProfileIntentResolverLPw(int userId)1177     CrossProfileIntentResolver editCrossProfileIntentResolverLPw(int userId) {
1178         CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1179         if (cpir == null) {
1180             cpir = new CrossProfileIntentResolver();
1181             mCrossProfileIntentResolvers.put(userId, cpir);
1182         }
1183         return cpir;
1184     }
1185 
1186     /**
1187      * The following functions suppose that you have a lock for managing access to the
1188      * mIntentFiltersVerifications map.
1189      */
1190 
1191     /* package protected */
getIntentFilterVerificationLPr(String packageName)1192     IntentFilterVerificationInfo getIntentFilterVerificationLPr(String packageName) {
1193         PackageSetting ps = mPackages.get(packageName);
1194         if (ps == null) {
1195             if (DEBUG_DOMAIN_VERIFICATION) {
1196                 Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
1197             }
1198             return null;
1199         }
1200         return ps.getIntentFilterVerificationInfo();
1201     }
1202 
1203     /* package protected */
createIntentFilterVerificationIfNeededLPw(String packageName, ArraySet<String> domains)1204     IntentFilterVerificationInfo createIntentFilterVerificationIfNeededLPw(String packageName,
1205             ArraySet<String> domains) {
1206         PackageSetting ps = mPackages.get(packageName);
1207         if (ps == null) {
1208             if (DEBUG_DOMAIN_VERIFICATION) {
1209                 Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
1210             }
1211             return null;
1212         }
1213         IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
1214         if (ivi == null) {
1215             ivi = new IntentFilterVerificationInfo(packageName, domains);
1216             ps.setIntentFilterVerificationInfo(ivi);
1217             if (DEBUG_DOMAIN_VERIFICATION) {
1218                 Slog.d(PackageManagerService.TAG,
1219                         "Creating new IntentFilterVerificationInfo for pkg: " + packageName);
1220             }
1221         } else {
1222             ivi.setDomains(domains);
1223             if (DEBUG_DOMAIN_VERIFICATION) {
1224                 Slog.d(PackageManagerService.TAG,
1225                         "Setting domains to existing IntentFilterVerificationInfo for pkg: " +
1226                                 packageName + " and with domains: " + ivi.getDomainsString());
1227             }
1228         }
1229         return ivi;
1230     }
1231 
getIntentFilterVerificationStatusLPr(String packageName, int userId)1232     int getIntentFilterVerificationStatusLPr(String packageName, int userId) {
1233         PackageSetting ps = mPackages.get(packageName);
1234         if (ps == null) {
1235             if (DEBUG_DOMAIN_VERIFICATION) {
1236                 Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
1237             }
1238             return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1239         }
1240         return (int)(ps.getDomainVerificationStatusForUser(userId) >> 32);
1241     }
1242 
updateIntentFilterVerificationStatusLPw(String packageName, final int status, int userId)1243     boolean updateIntentFilterVerificationStatusLPw(String packageName, final int status, int userId) {
1244         // Update the status for the current package
1245         PackageSetting current = mPackages.get(packageName);
1246         if (current == null) {
1247             if (DEBUG_DOMAIN_VERIFICATION) {
1248                 Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
1249             }
1250             return false;
1251         }
1252 
1253         final int alwaysGeneration;
1254         if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
1255             alwaysGeneration = mNextAppLinkGeneration.get(userId) + 1;
1256             mNextAppLinkGeneration.put(userId, alwaysGeneration);
1257         } else {
1258             alwaysGeneration = 0;
1259         }
1260 
1261         current.setDomainVerificationStatusForUser(status, alwaysGeneration, userId);
1262         return true;
1263     }
1264 
1265     /**
1266      * Used for Settings App and PackageManagerService dump. Should be read only.
1267      */
getIntentFilterVerificationsLPr( String packageName)1268     List<IntentFilterVerificationInfo> getIntentFilterVerificationsLPr(
1269             String packageName) {
1270         if (packageName == null) {
1271             return Collections.<IntentFilterVerificationInfo>emptyList();
1272         }
1273         ArrayList<IntentFilterVerificationInfo> result = new ArrayList<>();
1274         for (PackageSetting ps : mPackages.values()) {
1275             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
1276             if (ivi == null || TextUtils.isEmpty(ivi.getPackageName()) ||
1277                     !ivi.getPackageName().equalsIgnoreCase(packageName)) {
1278                 continue;
1279             }
1280             result.add(ivi);
1281         }
1282         return result;
1283     }
1284 
removeIntentFilterVerificationLPw(String packageName, int userId, boolean alsoResetStatus)1285     boolean removeIntentFilterVerificationLPw(String packageName, int userId,
1286             boolean alsoResetStatus) {
1287         PackageSetting ps = mPackages.get(packageName);
1288         if (ps == null) {
1289             if (DEBUG_DOMAIN_VERIFICATION) {
1290                 Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
1291             }
1292             return false;
1293         }
1294         if (alsoResetStatus) {
1295             ps.clearDomainVerificationStatusForUser(userId);
1296         }
1297         ps.setIntentFilterVerificationInfo(null);
1298         return true;
1299     }
1300 
removeIntentFilterVerificationLPw(String packageName, int[] userIds)1301     boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) {
1302         boolean result = false;
1303         for (int userId : userIds) {
1304             result |= removeIntentFilterVerificationLPw(packageName, userId, true);
1305         }
1306         return result;
1307     }
1308 
removeDefaultBrowserPackageNameLPw(int userId)1309     String removeDefaultBrowserPackageNameLPw(int userId) {
1310         return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId);
1311     }
1312 
getUserPackagesStateFile(int userId)1313     private File getUserPackagesStateFile(int userId) {
1314         // TODO: Implement a cleaner solution when adding tests.
1315         // This instead of Environment.getUserSystemDirectory(userId) to support testing.
1316         File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
1317         return new File(userDir, "package-restrictions.xml");
1318     }
1319 
getUserRuntimePermissionsFile(int userId)1320     private File getUserRuntimePermissionsFile(int userId) {
1321         // TODO: Implement a cleaner solution when adding tests.
1322         // This instead of Environment.getUserSystemDirectory(userId) to support testing.
1323         File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
1324         return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
1325     }
1326 
getUserPackagesStateBackupFile(int userId)1327     private File getUserPackagesStateBackupFile(int userId) {
1328         return new File(Environment.getUserSystemDirectory(userId),
1329                 "package-restrictions-backup.xml");
1330     }
1331 
writeAllUsersPackageRestrictionsLPr()1332     void writeAllUsersPackageRestrictionsLPr() {
1333         List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
1334         if (users == null) return;
1335 
1336         for (UserInfo user : users) {
1337             writePackageRestrictionsLPr(user.id);
1338         }
1339     }
1340 
writeAllRuntimePermissionsLPr()1341     void writeAllRuntimePermissionsLPr() {
1342         for (int userId : UserManagerService.getInstance().getUserIds()) {
1343             mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
1344         }
1345     }
1346 
isPermissionUpgradeNeededLPr(int userId)1347     boolean isPermissionUpgradeNeededLPr(int userId) {
1348         return mRuntimePermissionsPersistence.isPermissionUpgradeNeeded(userId);
1349     }
1350 
updateRuntimePermissionsFingerprintLPr(@serIdInt int userId)1351     void updateRuntimePermissionsFingerprintLPr(@UserIdInt int userId) {
1352         mRuntimePermissionsPersistence.updateRuntimePermissionsFingerprintLPr(userId);
1353     }
1354 
getDefaultRuntimePermissionsVersionLPr(int userId)1355     int getDefaultRuntimePermissionsVersionLPr(int userId) {
1356         return mRuntimePermissionsPersistence.getVersionLPr(userId);
1357     }
1358 
setDefaultRuntimePermissionsVersionLPr(int version, int userId)1359     void setDefaultRuntimePermissionsVersionLPr(int version, int userId) {
1360         mRuntimePermissionsPersistence.setVersionLPr(version, userId);
1361     }
1362 
setPermissionControllerVersion(long version)1363     void setPermissionControllerVersion(long version) {
1364         mRuntimePermissionsPersistence.setPermissionControllerVersion(version);
1365     }
1366 
findOrCreateVersion(String volumeUuid)1367     public VersionInfo findOrCreateVersion(String volumeUuid) {
1368         VersionInfo ver = mVersion.get(volumeUuid);
1369         if (ver == null) {
1370             ver = new VersionInfo();
1371             mVersion.put(volumeUuid, ver);
1372         }
1373         return ver;
1374     }
1375 
getInternalVersion()1376     public VersionInfo getInternalVersion() {
1377         return mVersion.get(StorageManager.UUID_PRIVATE_INTERNAL);
1378     }
1379 
getExternalVersion()1380     public VersionInfo getExternalVersion() {
1381         return mVersion.get(StorageManager.UUID_PRIMARY_PHYSICAL);
1382     }
1383 
onVolumeForgotten(String fsUuid)1384     public void onVolumeForgotten(String fsUuid) {
1385         mVersion.remove(fsUuid);
1386     }
1387 
1388     /**
1389      * Applies the preferred activity state described by the given XML.  This code
1390      * also supports the restore-from-backup code path.
1391      *
1392      * @see PreferredActivityBackupHelper
1393      */
readPreferredActivitiesLPw(XmlPullParser parser, int userId)1394     void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
1395             throws XmlPullParserException, IOException {
1396         int outerDepth = parser.getDepth();
1397         int type;
1398         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1399                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1400             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1401                 continue;
1402             }
1403 
1404             String tagName = parser.getName();
1405             if (tagName.equals(TAG_ITEM)) {
1406                 PreferredActivity pa = new PreferredActivity(parser);
1407                 if (pa.mPref.getParseError() == null) {
1408                     final PreferredIntentResolver resolver = editPreferredActivitiesLPw(userId);
1409                     ArrayList<PreferredActivity> pal = resolver.findFilters(pa);
1410                     if (pal == null || pal.size() == 0 || pa.mPref.mAlways) {
1411                         resolver.addFilter(pa);
1412                     }
1413                 } else {
1414                     PackageManagerService.reportSettingsProblem(Log.WARN,
1415                             "Error in package manager settings: <preferred-activity> "
1416                                     + pa.mPref.getParseError() + " at "
1417                                     + parser.getPositionDescription());
1418                 }
1419             } else {
1420                 PackageManagerService.reportSettingsProblem(Log.WARN,
1421                         "Unknown element under <preferred-activities>: " + parser.getName());
1422                 XmlUtils.skipCurrentTag(parser);
1423             }
1424         }
1425     }
1426 
readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)1427     private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)
1428             throws XmlPullParserException, IOException {
1429         int outerDepth = parser.getDepth();
1430         int type;
1431         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1432                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1433             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1434                 continue;
1435             }
1436             String tagName = parser.getName();
1437             if (tagName.equals(TAG_ITEM)) {
1438                 PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
1439                 editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
1440             } else {
1441                 PackageManagerService.reportSettingsProblem(Log.WARN,
1442                         "Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: "
1443                         + parser.getName());
1444                 XmlUtils.skipCurrentTag(parser);
1445             }
1446         }
1447     }
1448 
readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)1449     private void readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)
1450             throws XmlPullParserException, IOException {
1451         int outerDepth = parser.getDepth();
1452         int type;
1453         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1454                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1455             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1456                 continue;
1457             }
1458             final String tagName = parser.getName();
1459             if (tagName.equals(TAG_ITEM)) {
1460                 CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
1461                 editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
1462             } else {
1463                 String msg = "Unknown element under " +  TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
1464                         tagName;
1465                 PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1466                 XmlUtils.skipCurrentTag(parser);
1467             }
1468         }
1469     }
1470 
readDomainVerificationLPw(XmlPullParser parser, PackageSettingBase packageSetting)1471     private void readDomainVerificationLPw(XmlPullParser parser, PackageSettingBase packageSetting)
1472             throws XmlPullParserException, IOException {
1473         IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1474         packageSetting.setIntentFilterVerificationInfo(ivi);
1475         if (DEBUG_PARSER) {
1476             Log.d(TAG, "Read domain verification for package: " + ivi.getPackageName());
1477         }
1478     }
1479 
readRestoredIntentFilterVerifications(XmlPullParser parser)1480     private void readRestoredIntentFilterVerifications(XmlPullParser parser)
1481             throws XmlPullParserException, IOException {
1482         int outerDepth = parser.getDepth();
1483         int type;
1484         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1485                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1486             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1487                 continue;
1488             }
1489             final String tagName = parser.getName();
1490             if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
1491                 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1492                 if (DEBUG_DOMAIN_VERIFICATION) {
1493                     Slog.i(TAG, "Restored IVI for " + ivi.getPackageName()
1494                             + " status=" + ivi.getStatusString());
1495                 }
1496                 mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi);
1497             } else {
1498                 Slog.w(TAG, "Unknown element: " + tagName);
1499                 XmlUtils.skipCurrentTag(parser);
1500             }
1501         }
1502     }
1503 
readDefaultAppsLPw(XmlPullParser parser, int userId)1504     void readDefaultAppsLPw(XmlPullParser parser, int userId)
1505             throws XmlPullParserException, IOException {
1506         int outerDepth = parser.getDepth();
1507         int type;
1508         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1509                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1510             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1511                 continue;
1512             }
1513             String tagName = parser.getName();
1514             if (tagName.equals(TAG_DEFAULT_BROWSER)) {
1515                 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
1516                 mDefaultBrowserApp.put(userId, packageName);
1517             } else if (tagName.equals(TAG_DEFAULT_DIALER)) {
1518                 // Ignored.
1519             } else {
1520                 String msg = "Unknown element under " +  TAG_DEFAULT_APPS + ": " +
1521                         parser.getName();
1522                 PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1523                 XmlUtils.skipCurrentTag(parser);
1524             }
1525         }
1526     }
1527 
readBlockUninstallPackagesLPw(XmlPullParser parser, int userId)1528     void readBlockUninstallPackagesLPw(XmlPullParser parser, int userId)
1529             throws XmlPullParserException, IOException {
1530         int outerDepth = parser.getDepth();
1531         int type;
1532         ArraySet<String> packages = new ArraySet<>();
1533         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1534                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1535             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1536                 continue;
1537             }
1538             String tagName = parser.getName();
1539             if (tagName.equals(TAG_BLOCK_UNINSTALL)) {
1540                 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
1541                 packages.add(packageName);
1542             } else {
1543                 String msg = "Unknown element under " +  TAG_BLOCK_UNINSTALL_PACKAGES + ": " +
1544                         parser.getName();
1545                 PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1546                 XmlUtils.skipCurrentTag(parser);
1547             }
1548         }
1549         if (packages.isEmpty()) {
1550             mBlockUninstallPackages.remove(userId);
1551         } else {
1552             mBlockUninstallPackages.put(userId, packages);
1553         }
1554     }
1555 
readPackageRestrictionsLPr(int userId)1556     void readPackageRestrictionsLPr(int userId) {
1557         if (DEBUG_MU) {
1558             Log.i(TAG, "Reading package restrictions for user=" + userId);
1559         }
1560         FileInputStream str = null;
1561         File userPackagesStateFile = getUserPackagesStateFile(userId);
1562         File backupFile = getUserPackagesStateBackupFile(userId);
1563         if (backupFile.exists()) {
1564             try {
1565                 str = new FileInputStream(backupFile);
1566                 mReadMessages.append("Reading from backup stopped packages file\n");
1567                 PackageManagerService.reportSettingsProblem(Log.INFO,
1568                         "Need to read from backup stopped packages file");
1569                 if (userPackagesStateFile.exists()) {
1570                     // If both the backup and normal file exist, we
1571                     // ignore the normal one since it might have been
1572                     // corrupted.
1573                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1574                             + userPackagesStateFile);
1575                     userPackagesStateFile.delete();
1576                 }
1577             } catch (java.io.IOException e) {
1578                 // We'll try for the normal settings file.
1579             }
1580         }
1581 
1582         try {
1583             if (str == null) {
1584                 if (!userPackagesStateFile.exists()) {
1585                     mReadMessages.append("No stopped packages file found\n");
1586                     PackageManagerService.reportSettingsProblem(Log.INFO,
1587                             "No stopped packages file; "
1588                             + "assuming all started");
1589                     // At first boot, make sure no packages are stopped.
1590                     // We usually want to have third party apps initialize
1591                     // in the stopped state, but not at first boot.  Also
1592                     // consider all applications to be installed.
1593                     for (PackageSetting pkg : mPackages.values()) {
1594                         pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
1595                                 true  /*installed*/,
1596                                 false /*stopped*/,
1597                                 false /*notLaunched*/,
1598                                 false /*hidden*/,
1599                                 0 /*distractionFlags*/,
1600                                 false /*suspended*/,
1601                                 null /*suspendParams*/,
1602                                 false /*instantApp*/,
1603                                 false /*virtualPreload*/,
1604                                 null /*lastDisableAppCaller*/,
1605                                 null /*enabledComponents*/,
1606                                 null /*disabledComponents*/,
1607                                 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
1608                                 0 /*linkGeneration*/,
1609                                 PackageManager.INSTALL_REASON_UNKNOWN,
1610                                 PackageManager.UNINSTALL_REASON_UNKNOWN,
1611                                 null /*harmfulAppWarning*/);
1612                     }
1613                     return;
1614                 }
1615                 str = new FileInputStream(userPackagesStateFile);
1616             }
1617             final XmlPullParser parser = Xml.newPullParser();
1618             parser.setInput(str, StandardCharsets.UTF_8.name());
1619 
1620             int type;
1621             while ((type=parser.next()) != XmlPullParser.START_TAG
1622                        && type != XmlPullParser.END_DOCUMENT) {
1623                 ;
1624             }
1625 
1626             if (type != XmlPullParser.START_TAG) {
1627                 mReadMessages.append("No start tag found in package restrictions file\n");
1628                 PackageManagerService.reportSettingsProblem(Log.WARN,
1629                         "No start tag found in package manager stopped packages");
1630                 return;
1631             }
1632 
1633             int maxAppLinkGeneration = 0;
1634 
1635             int outerDepth = parser.getDepth();
1636             PackageSetting ps = null;
1637             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1638                    && (type != XmlPullParser.END_TAG
1639                            || parser.getDepth() > outerDepth)) {
1640                 if (type == XmlPullParser.END_TAG
1641                         || type == XmlPullParser.TEXT) {
1642                     continue;
1643                 }
1644 
1645                 String tagName = parser.getName();
1646                 if (tagName.equals(TAG_PACKAGE)) {
1647                     String name = parser.getAttributeValue(null, ATTR_NAME);
1648                     ps = mPackages.get(name);
1649                     if (ps == null) {
1650                         Slog.w(PackageManagerService.TAG, "No package known for stopped package "
1651                                 + name);
1652                         XmlUtils.skipCurrentTag(parser);
1653                         continue;
1654                     }
1655 
1656                     final long ceDataInode = XmlUtils.readLongAttribute(parser, ATTR_CE_DATA_INODE,
1657                             0);
1658                     final boolean installed = XmlUtils.readBooleanAttribute(parser, ATTR_INSTALLED,
1659                             true);
1660                     final boolean stopped = XmlUtils.readBooleanAttribute(parser, ATTR_STOPPED,
1661                             false);
1662                     final boolean notLaunched = XmlUtils.readBooleanAttribute(parser,
1663                             ATTR_NOT_LAUNCHED, false);
1664 
1665                     // For backwards compatibility with the previous name of "blocked", which
1666                     // now means hidden, read the old attribute as well.
1667                     final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
1668                     boolean hidden = blockedStr == null
1669                             ? false : Boolean.parseBoolean(blockedStr);
1670                     final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN);
1671                     hidden = hiddenStr == null
1672                             ? hidden : Boolean.parseBoolean(hiddenStr);
1673 
1674                     final int distractionFlags = XmlUtils.readIntAttribute(parser,
1675                             ATTR_DISTRACTION_FLAGS, 0);
1676                     final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED,
1677                             false);
1678                     String oldSuspendingPackage = parser.getAttributeValue(null,
1679                             ATTR_SUSPENDING_PACKAGE);
1680                     final String dialogMessage = parser.getAttributeValue(null,
1681                             ATTR_SUSPEND_DIALOG_MESSAGE);
1682                     if (suspended && oldSuspendingPackage == null) {
1683                         oldSuspendingPackage = PLATFORM_PACKAGE_NAME;
1684                     }
1685 
1686                     final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser,
1687                             ATTR_BLOCK_UNINSTALL, false);
1688                     final boolean instantApp = XmlUtils.readBooleanAttribute(parser,
1689                             ATTR_INSTANT_APP, false);
1690                     final boolean virtualPreload = XmlUtils.readBooleanAttribute(parser,
1691                             ATTR_VIRTUAL_PRELOAD, false);
1692                     final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED,
1693                             COMPONENT_ENABLED_STATE_DEFAULT);
1694                     final String enabledCaller = parser.getAttributeValue(null,
1695                             ATTR_ENABLED_CALLER);
1696                     final String harmfulAppWarning =
1697                             parser.getAttributeValue(null, ATTR_HARMFUL_APP_WARNING);
1698                     final int verifState = XmlUtils.readIntAttribute(parser,
1699                             ATTR_DOMAIN_VERIFICATON_STATE,
1700                             PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
1701                     final int linkGeneration = XmlUtils.readIntAttribute(parser,
1702                             ATTR_APP_LINK_GENERATION, 0);
1703                     if (linkGeneration > maxAppLinkGeneration) {
1704                         maxAppLinkGeneration = linkGeneration;
1705                     }
1706                     final int installReason = XmlUtils.readIntAttribute(parser,
1707                             ATTR_INSTALL_REASON, PackageManager.INSTALL_REASON_UNKNOWN);
1708                     final int uninstallReason = XmlUtils.readIntAttribute(parser,
1709                             ATTR_UNINSTALL_REASON, PackageManager.UNINSTALL_REASON_UNKNOWN);
1710 
1711                     ArraySet<String> enabledComponents = null;
1712                     ArraySet<String> disabledComponents = null;
1713                     PersistableBundle suspendedAppExtras = null;
1714                     PersistableBundle suspendedLauncherExtras = null;
1715                     SuspendDialogInfo oldSuspendDialogInfo = null;
1716 
1717                     int packageDepth = parser.getDepth();
1718                     ArrayMap<String, PackageUserState.SuspendParams> suspendParamsMap = null;
1719                     while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1720                             && (type != XmlPullParser.END_TAG
1721                             || parser.getDepth() > packageDepth)) {
1722                         if (type == XmlPullParser.END_TAG
1723                                 || type == XmlPullParser.TEXT) {
1724                             continue;
1725                         }
1726                         switch (parser.getName()) {
1727                             case TAG_ENABLED_COMPONENTS:
1728                                 enabledComponents = readComponentsLPr(parser);
1729                                 break;
1730                             case TAG_DISABLED_COMPONENTS:
1731                                 disabledComponents = readComponentsLPr(parser);
1732                                 break;
1733                             case TAG_SUSPENDED_APP_EXTRAS:
1734                                 suspendedAppExtras = PersistableBundle.restoreFromXml(parser);
1735                                 break;
1736                             case TAG_SUSPENDED_LAUNCHER_EXTRAS:
1737                                 suspendedLauncherExtras = PersistableBundle.restoreFromXml(parser);
1738                                 break;
1739                             case TAG_SUSPENDED_DIALOG_INFO:
1740                                 oldSuspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
1741                                 break;
1742                             case TAG_SUSPEND_PARAMS:
1743                                 final String suspendingPackage = parser.getAttributeValue(null,
1744                                         ATTR_SUSPENDING_PACKAGE);
1745                                 if (suspendingPackage == null) {
1746                                     Slog.wtf(TAG, "No suspendingPackage found inside tag "
1747                                             + TAG_SUSPEND_PARAMS);
1748                                     continue;
1749                                 }
1750                                 if (suspendParamsMap == null) {
1751                                     suspendParamsMap = new ArrayMap<>();
1752                                 }
1753                                 suspendParamsMap.put(suspendingPackage,
1754                                         PackageUserState.SuspendParams.restoreFromXml(parser));
1755                                 break;
1756                             default:
1757                                 Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
1758                                         + TAG_PACKAGE);
1759                         }
1760                     }
1761                     if (oldSuspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
1762                         oldSuspendDialogInfo = new SuspendDialogInfo.Builder()
1763                                 .setMessage(dialogMessage)
1764                                 .build();
1765                     }
1766                     if (suspended && suspendParamsMap == null) {
1767                         final PackageUserState.SuspendParams suspendParams =
1768                                 PackageUserState.SuspendParams.getInstanceOrNull(
1769                                         oldSuspendDialogInfo,
1770                                         suspendedAppExtras,
1771                                         suspendedLauncherExtras);
1772                         suspendParamsMap = new ArrayMap<>();
1773                         suspendParamsMap.put(oldSuspendingPackage, suspendParams);
1774                     }
1775 
1776                     if (blockUninstall) {
1777                         setBlockUninstallLPw(userId, name, true);
1778                     }
1779                     ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
1780                             hidden, distractionFlags, suspended, suspendParamsMap,
1781                             instantApp, virtualPreload,
1782                             enabledCaller, enabledComponents, disabledComponents, verifState,
1783                             linkGeneration, installReason, uninstallReason, harmfulAppWarning);
1784                 } else if (tagName.equals("preferred-activities")) {
1785                     readPreferredActivitiesLPw(parser, userId);
1786                 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1787                     readPersistentPreferredActivitiesLPw(parser, userId);
1788                 } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
1789                     readCrossProfileIntentFiltersLPw(parser, userId);
1790                 } else if (tagName.equals(TAG_DEFAULT_APPS)) {
1791                     readDefaultAppsLPw(parser, userId);
1792                 } else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) {
1793                     readBlockUninstallPackagesLPw(parser, userId);
1794                 } else {
1795                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1796                           + parser.getName());
1797                     XmlUtils.skipCurrentTag(parser);
1798                 }
1799             }
1800 
1801             str.close();
1802 
1803             mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1);
1804 
1805         } catch (XmlPullParserException e) {
1806             mReadMessages.append("Error reading: " + e.toString());
1807             PackageManagerService.reportSettingsProblem(Log.ERROR,
1808                     "Error reading stopped packages: " + e);
1809             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1810                     e);
1811 
1812         } catch (java.io.IOException e) {
1813             mReadMessages.append("Error reading: " + e.toString());
1814             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1815             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1816                     e);
1817         }
1818     }
1819 
setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall)1820     void setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall) {
1821         ArraySet<String> packages = mBlockUninstallPackages.get(userId);
1822         if (blockUninstall) {
1823             if (packages == null) {
1824                 packages = new ArraySet<String>();
1825                 mBlockUninstallPackages.put(userId, packages);
1826             }
1827             packages.add(packageName);
1828         } else if (packages != null) {
1829             packages.remove(packageName);
1830             if (packages.isEmpty()) {
1831                 mBlockUninstallPackages.remove(userId);
1832             }
1833         }
1834     }
1835 
clearBlockUninstallLPw(int userId)1836     void clearBlockUninstallLPw(int userId) {
1837         mBlockUninstallPackages.remove(userId);
1838     }
1839 
getBlockUninstallLPr(int userId, String packageName)1840     boolean getBlockUninstallLPr(int userId, String packageName) {
1841         ArraySet<String> packages = mBlockUninstallPackages.get(userId);
1842         if (packages == null) {
1843             return false;
1844         }
1845         return packages.contains(packageName);
1846     }
1847 
readComponentsLPr(XmlPullParser parser)1848     private ArraySet<String> readComponentsLPr(XmlPullParser parser)
1849             throws IOException, XmlPullParserException {
1850         ArraySet<String> components = null;
1851         int type;
1852         int outerDepth = parser.getDepth();
1853         String tagName;
1854         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1855                 && (type != XmlPullParser.END_TAG
1856                 || parser.getDepth() > outerDepth)) {
1857             if (type == XmlPullParser.END_TAG
1858                     || type == XmlPullParser.TEXT) {
1859                 continue;
1860             }
1861             tagName = parser.getName();
1862             if (tagName.equals(TAG_ITEM)) {
1863                 String componentName = parser.getAttributeValue(null, ATTR_NAME);
1864                 if (componentName != null) {
1865                     if (components == null) {
1866                         components = new ArraySet<String>();
1867                     }
1868                     components.add(componentName);
1869                 }
1870             }
1871         }
1872         return components;
1873     }
1874 
1875     /**
1876      * Record the state of preferred activity configuration into XML.  This is used both
1877      * for recording packages.xml internally and for supporting backup/restore of the
1878      * preferred activity configuration.
1879      */
writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)1880     void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
1881             throws IllegalArgumentException, IllegalStateException, IOException {
1882         serializer.startTag(null, "preferred-activities");
1883         PreferredIntentResolver pir = mPreferredActivities.get(userId);
1884         if (pir != null) {
1885             for (final PreferredActivity pa : pir.filterSet()) {
1886                 serializer.startTag(null, TAG_ITEM);
1887                 pa.writeToXml(serializer, full);
1888                 serializer.endTag(null, TAG_ITEM);
1889             }
1890         }
1891         serializer.endTag(null, "preferred-activities");
1892     }
1893 
writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)1894     void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
1895             throws IllegalArgumentException, IllegalStateException, IOException {
1896         serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1897         PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1898         if (ppir != null) {
1899             for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
1900                 serializer.startTag(null, TAG_ITEM);
1901                 ppa.writeToXml(serializer);
1902                 serializer.endTag(null, TAG_ITEM);
1903             }
1904         }
1905         serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1906     }
1907 
writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)1908     void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)
1909             throws IllegalArgumentException, IllegalStateException, IOException {
1910         serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1911         CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1912         if (cpir != null) {
1913             for (final CrossProfileIntentFilter cpif : cpir.filterSet()) {
1914                 serializer.startTag(null, TAG_ITEM);
1915                 cpif.writeToXml(serializer);
1916                 serializer.endTag(null, TAG_ITEM);
1917             }
1918         }
1919         serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1920     }
1921 
writeDomainVerificationsLPr(XmlSerializer serializer, IntentFilterVerificationInfo verificationInfo)1922     void writeDomainVerificationsLPr(XmlSerializer serializer,
1923                                      IntentFilterVerificationInfo verificationInfo)
1924             throws IllegalArgumentException, IllegalStateException, IOException {
1925         if (verificationInfo != null && verificationInfo.getPackageName() != null) {
1926             serializer.startTag(null, TAG_DOMAIN_VERIFICATION);
1927             verificationInfo.writeToXml(serializer);
1928             if (DEBUG_DOMAIN_VERIFICATION) {
1929                 Slog.d(TAG, "Wrote domain verification for package: "
1930                         + verificationInfo.getPackageName());
1931             }
1932             serializer.endTag(null, TAG_DOMAIN_VERIFICATION);
1933         }
1934     }
1935 
1936     // Specifically for backup/restore
writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)1937     void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)
1938             throws IllegalArgumentException, IllegalStateException, IOException {
1939         serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
1940         final int N = mPackages.size();
1941         for (int i = 0; i < N; i++) {
1942             PackageSetting ps = mPackages.valueAt(i);
1943             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
1944             if (ivi != null) {
1945                 writeDomainVerificationsLPr(serializer, ivi);
1946             }
1947         }
1948         serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
1949     }
1950 
1951     // Specifically for backup/restore
readAllDomainVerificationsLPr(XmlPullParser parser, int userId)1952     void readAllDomainVerificationsLPr(XmlPullParser parser, int userId)
1953             throws XmlPullParserException, IOException {
1954         mRestoredIntentFilterVerifications.clear();
1955 
1956         int outerDepth = parser.getDepth();
1957         int type;
1958         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1959                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1960             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1961                 continue;
1962             }
1963 
1964             String tagName = parser.getName();
1965             if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
1966                 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1967                 final String pkgName = ivi.getPackageName();
1968                 final PackageSetting ps = mPackages.get(pkgName);
1969                 if (ps != null) {
1970                     // known/existing package; update in place
1971                     ps.setIntentFilterVerificationInfo(ivi);
1972                     if (DEBUG_DOMAIN_VERIFICATION) {
1973                         Slog.d(TAG, "Restored IVI for existing app " + pkgName
1974                                 + " status=" + ivi.getStatusString());
1975                     }
1976                 } else {
1977                     mRestoredIntentFilterVerifications.put(pkgName, ivi);
1978                     if (DEBUG_DOMAIN_VERIFICATION) {
1979                         Slog.d(TAG, "Restored IVI for pending app " + pkgName
1980                                 + " status=" + ivi.getStatusString());
1981                     }
1982                 }
1983             } else {
1984                 PackageManagerService.reportSettingsProblem(Log.WARN,
1985                         "Unknown element under <all-intent-filter-verification>: "
1986                         + parser.getName());
1987                 XmlUtils.skipCurrentTag(parser);
1988             }
1989         }
1990     }
1991 
writeDefaultAppsLPr(XmlSerializer serializer, int userId)1992     void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
1993             throws IllegalArgumentException, IllegalStateException, IOException {
1994         serializer.startTag(null, TAG_DEFAULT_APPS);
1995         String defaultBrowser = mDefaultBrowserApp.get(userId);
1996         if (!TextUtils.isEmpty(defaultBrowser)) {
1997             serializer.startTag(null, TAG_DEFAULT_BROWSER);
1998             serializer.attribute(null, ATTR_PACKAGE_NAME, defaultBrowser);
1999             serializer.endTag(null, TAG_DEFAULT_BROWSER);
2000         }
2001         serializer.endTag(null, TAG_DEFAULT_APPS);
2002     }
2003 
writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId)2004     void writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId)
2005             throws IOException  {
2006         ArraySet<String> packages = mBlockUninstallPackages.get(userId);
2007         if (packages != null) {
2008             serializer.startTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
2009             for (int i = 0; i < packages.size(); i++) {
2010                  serializer.startTag(null, TAG_BLOCK_UNINSTALL);
2011                  serializer.attribute(null, ATTR_PACKAGE_NAME, packages.valueAt(i));
2012                  serializer.endTag(null, TAG_BLOCK_UNINSTALL);
2013             }
2014             serializer.endTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
2015         }
2016     }
2017 
writePackageRestrictionsLPr(int userId)2018     void writePackageRestrictionsLPr(int userId) {
2019         invalidatePackageCache();
2020 
2021         if (DEBUG_MU) {
2022             Log.i(TAG, "Writing package restrictions for user=" + userId);
2023         }
2024         final long startTime = SystemClock.uptimeMillis();
2025 
2026         // Keep the old stopped packages around until we know the new ones have
2027         // been successfully written.
2028         File userPackagesStateFile = getUserPackagesStateFile(userId);
2029         File backupFile = getUserPackagesStateBackupFile(userId);
2030         new File(userPackagesStateFile.getParent()).mkdirs();
2031         if (userPackagesStateFile.exists()) {
2032             // Presence of backup settings file indicates that we failed
2033             // to persist packages earlier. So preserve the older
2034             // backup for future reference since the current packages
2035             // might have been corrupted.
2036             if (!backupFile.exists()) {
2037                 if (!userPackagesStateFile.renameTo(backupFile)) {
2038                     Slog.wtf(PackageManagerService.TAG,
2039                             "Unable to backup user packages state file, "
2040                             + "current changes will be lost at reboot");
2041                     return;
2042                 }
2043             } else {
2044                 userPackagesStateFile.delete();
2045                 Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
2046             }
2047         }
2048 
2049         try {
2050             final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
2051             final BufferedOutputStream str = new BufferedOutputStream(fstr);
2052 
2053             final XmlSerializer serializer = new FastXmlSerializer();
2054             serializer.setOutput(str, StandardCharsets.UTF_8.name());
2055             serializer.startDocument(null, true);
2056             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2057 
2058             serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
2059 
2060             for (final PackageSetting pkg : mPackages.values()) {
2061                 final PackageUserState ustate = pkg.readUserState(userId);
2062                 if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
2063 
2064                 serializer.startTag(null, TAG_PACKAGE);
2065                 serializer.attribute(null, ATTR_NAME, pkg.name);
2066                 if (ustate.ceDataInode != 0) {
2067                     XmlUtils.writeLongAttribute(serializer, ATTR_CE_DATA_INODE, ustate.ceDataInode);
2068                 }
2069                 if (!ustate.installed) {
2070                     serializer.attribute(null, ATTR_INSTALLED, "false");
2071                 }
2072                 if (ustate.stopped) {
2073                     serializer.attribute(null, ATTR_STOPPED, "true");
2074                 }
2075                 if (ustate.notLaunched) {
2076                     serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
2077                 }
2078                 if (ustate.hidden) {
2079                     serializer.attribute(null, ATTR_HIDDEN, "true");
2080                 }
2081                 if (ustate.distractionFlags != 0) {
2082                     serializer.attribute(null, ATTR_DISTRACTION_FLAGS,
2083                             Integer.toString(ustate.distractionFlags));
2084                 }
2085                 if (ustate.suspended) {
2086                     serializer.attribute(null, ATTR_SUSPENDED, "true");
2087                 }
2088                 if (ustate.instantApp) {
2089                     serializer.attribute(null, ATTR_INSTANT_APP, "true");
2090                 }
2091                 if (ustate.virtualPreload) {
2092                     serializer.attribute(null, ATTR_VIRTUAL_PRELOAD, "true");
2093                 }
2094                 if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
2095                     serializer.attribute(null, ATTR_ENABLED,
2096                             Integer.toString(ustate.enabled));
2097                     if (ustate.lastDisableAppCaller != null) {
2098                         serializer.attribute(null, ATTR_ENABLED_CALLER,
2099                                 ustate.lastDisableAppCaller);
2100                     }
2101                 }
2102                 if (ustate.domainVerificationStatus !=
2103                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
2104                     XmlUtils.writeIntAttribute(serializer, ATTR_DOMAIN_VERIFICATON_STATE,
2105                             ustate.domainVerificationStatus);
2106                 }
2107                 if (ustate.appLinkGeneration != 0) {
2108                     XmlUtils.writeIntAttribute(serializer, ATTR_APP_LINK_GENERATION,
2109                             ustate.appLinkGeneration);
2110                 }
2111                 if (ustate.installReason != PackageManager.INSTALL_REASON_UNKNOWN) {
2112                     serializer.attribute(null, ATTR_INSTALL_REASON,
2113                             Integer.toString(ustate.installReason));
2114                 }
2115                 if (ustate.uninstallReason != PackageManager.UNINSTALL_REASON_UNKNOWN) {
2116                     serializer.attribute(null, ATTR_UNINSTALL_REASON,
2117                             Integer.toString(ustate.uninstallReason));
2118                 }
2119                 if (ustate.harmfulAppWarning != null) {
2120                     serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
2121                             ustate.harmfulAppWarning);
2122                 }
2123                 if (ustate.suspended) {
2124                     for (int i = 0; i < ustate.suspendParams.size(); i++) {
2125                         final String suspendingPackage = ustate.suspendParams.keyAt(i);
2126                         serializer.startTag(null, TAG_SUSPEND_PARAMS);
2127                         serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, suspendingPackage);
2128                         final PackageUserState.SuspendParams params =
2129                                 ustate.suspendParams.valueAt(i);
2130                         if (params != null) {
2131                             params.saveToXml(serializer);
2132                         }
2133                         serializer.endTag(null, TAG_SUSPEND_PARAMS);
2134                     }
2135                 }
2136                 if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
2137                     serializer.startTag(null, TAG_ENABLED_COMPONENTS);
2138                     for (final String name : ustate.enabledComponents) {
2139                         serializer.startTag(null, TAG_ITEM);
2140                         serializer.attribute(null, ATTR_NAME, name);
2141                         serializer.endTag(null, TAG_ITEM);
2142                     }
2143                     serializer.endTag(null, TAG_ENABLED_COMPONENTS);
2144                 }
2145                 if (!ArrayUtils.isEmpty(ustate.disabledComponents)) {
2146                     serializer.startTag(null, TAG_DISABLED_COMPONENTS);
2147                     for (final String name : ustate.disabledComponents) {
2148                         serializer.startTag(null, TAG_ITEM);
2149                         serializer.attribute(null, ATTR_NAME, name);
2150                         serializer.endTag(null, TAG_ITEM);
2151                     }
2152                     serializer.endTag(null, TAG_DISABLED_COMPONENTS);
2153                 }
2154 
2155                 serializer.endTag(null, TAG_PACKAGE);
2156             }
2157 
2158             writePreferredActivitiesLPr(serializer, userId, true);
2159             writePersistentPreferredActivitiesLPr(serializer, userId);
2160             writeCrossProfileIntentFiltersLPr(serializer, userId);
2161             writeDefaultAppsLPr(serializer, userId);
2162             writeBlockUninstallPackagesLPr(serializer, userId);
2163 
2164             serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
2165 
2166             serializer.endDocument();
2167 
2168             str.flush();
2169             FileUtils.sync(fstr);
2170             str.close();
2171 
2172             // New settings successfully written, old ones are no longer
2173             // needed.
2174             backupFile.delete();
2175             FileUtils.setPermissions(userPackagesStateFile.toString(),
2176                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
2177                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2178                     -1, -1);
2179 
2180             com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
2181                     "package-user-" + userId, SystemClock.uptimeMillis() - startTime);
2182 
2183             // Done, all is good!
2184             return;
2185         } catch(java.io.IOException e) {
2186             Slog.wtf(PackageManagerService.TAG,
2187                     "Unable to write package manager user packages state, "
2188                     + " current changes will be lost at reboot", e);
2189         }
2190 
2191         // Clean up partially written files
2192         if (userPackagesStateFile.exists()) {
2193             if (!userPackagesStateFile.delete()) {
2194                 Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
2195                         + mStoppedPackagesFilename);
2196             }
2197         }
2198     }
2199 
readInstallPermissionsLPr(XmlPullParser parser, PermissionsState permissionsState)2200     void readInstallPermissionsLPr(XmlPullParser parser,
2201             PermissionsState permissionsState) throws IOException, XmlPullParserException {
2202         int outerDepth = parser.getDepth();
2203         int type;
2204         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2205                 && (type != XmlPullParser.END_TAG
2206                 || parser.getDepth() > outerDepth)) {
2207             if (type == XmlPullParser.END_TAG
2208                     || type == XmlPullParser.TEXT) {
2209                 continue;
2210             }
2211             String tagName = parser.getName();
2212             if (tagName.equals(TAG_ITEM)) {
2213                 String name = parser.getAttributeValue(null, ATTR_NAME);
2214 
2215                 BasePermission bp = mPermissions.getPermission(name);
2216                 if (bp == null) {
2217                     Slog.w(PackageManagerService.TAG, "Unknown permission: " + name);
2218                     XmlUtils.skipCurrentTag(parser);
2219                     continue;
2220                 }
2221 
2222                 String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
2223                 final boolean granted = grantedStr == null
2224                         || Boolean.parseBoolean(grantedStr);
2225 
2226                 String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
2227                 final int flags = (flagsStr != null)
2228                         ? Integer.parseInt(flagsStr, 16) : 0;
2229 
2230                 if (granted) {
2231                     if (permissionsState.grantInstallPermission(bp) ==
2232                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
2233                         Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2234                         XmlUtils.skipCurrentTag(parser);
2235                     } else {
2236                         permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2237                                 PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
2238                     }
2239                 } else {
2240                     if (permissionsState.revokeInstallPermission(bp) ==
2241                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
2242                         Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2243                         XmlUtils.skipCurrentTag(parser);
2244                     } else {
2245                         permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2246                                 PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
2247                     }
2248                 }
2249             } else {
2250                 Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: "
2251                         + parser.getName());
2252                 XmlUtils.skipCurrentTag(parser);
2253             }
2254         }
2255     }
2256 
writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates)2257     void writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates)
2258             throws IOException {
2259         if (permissionStates.isEmpty()) {
2260             return;
2261         }
2262 
2263         serializer.startTag(null, TAG_PERMISSIONS);
2264 
2265         for (PermissionState permissionState : permissionStates) {
2266             serializer.startTag(null, TAG_ITEM);
2267             serializer.attribute(null, ATTR_NAME, permissionState.getName());
2268             serializer.attribute(null, ATTR_GRANTED, String.valueOf(permissionState.isGranted()));
2269             serializer.attribute(null, ATTR_FLAGS, Integer.toHexString(permissionState.getFlags()));
2270             serializer.endTag(null, TAG_ITEM);
2271         }
2272 
2273         serializer.endTag(null, TAG_PERMISSIONS);
2274     }
2275 
readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)2276     void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)
2277             throws IOException, XmlPullParserException {
2278         int outerDepth = parser.getDepth();
2279         int type;
2280         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2281                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2282             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2283                 continue;
2284             }
2285             String libName = parser.getAttributeValue(null, ATTR_NAME);
2286             String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
2287 
2288             long libVersion = -1;
2289             try {
2290                 libVersion = Long.parseLong(libVersionStr);
2291             } catch (NumberFormatException e) {
2292                 // ignore
2293             }
2294 
2295             if (libName != null && libVersion >= 0) {
2296                 outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
2297                         outPs.usesStaticLibraries, libName);
2298                 outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong(
2299                         outPs.usesStaticLibrariesVersions, libVersion);
2300             }
2301 
2302             XmlUtils.skipCurrentTag(parser);
2303         }
2304     }
2305 
writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries, long[] usesStaticLibraryVersions)2306     void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries,
2307             long[] usesStaticLibraryVersions) throws IOException {
2308         if (ArrayUtils.isEmpty(usesStaticLibraries) || ArrayUtils.isEmpty(usesStaticLibraryVersions)
2309                 || usesStaticLibraries.length != usesStaticLibraryVersions.length) {
2310             return;
2311         }
2312         final int libCount = usesStaticLibraries.length;
2313         for (int i = 0; i < libCount; i++) {
2314             final String libName = usesStaticLibraries[i];
2315             final long libVersion = usesStaticLibraryVersions[i];
2316             serializer.startTag(null, TAG_USES_STATIC_LIB);
2317             serializer.attribute(null, ATTR_NAME, libName);
2318             serializer.attribute(null, ATTR_VERSION, Long.toString(libVersion));
2319             serializer.endTag(null, TAG_USES_STATIC_LIB);
2320         }
2321     }
2322 
2323     // Note: assumed "stopped" field is already cleared in all packages.
2324     // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
readStoppedLPw()2325     void readStoppedLPw() {
2326         FileInputStream str = null;
2327         if (mBackupStoppedPackagesFilename.exists()) {
2328             try {
2329                 str = new FileInputStream(mBackupStoppedPackagesFilename);
2330                 mReadMessages.append("Reading from backup stopped packages file\n");
2331                 PackageManagerService.reportSettingsProblem(Log.INFO,
2332                         "Need to read from backup stopped packages file");
2333                 if (mSettingsFilename.exists()) {
2334                     // If both the backup and normal file exist, we
2335                     // ignore the normal one since it might have been
2336                     // corrupted.
2337                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
2338                             + mStoppedPackagesFilename);
2339                     mStoppedPackagesFilename.delete();
2340                 }
2341             } catch (java.io.IOException e) {
2342                 // We'll try for the normal settings file.
2343             }
2344         }
2345 
2346         try {
2347             if (str == null) {
2348                 if (!mStoppedPackagesFilename.exists()) {
2349                     mReadMessages.append("No stopped packages file found\n");
2350                     PackageManagerService.reportSettingsProblem(Log.INFO,
2351                             "No stopped packages file file; assuming all started");
2352                     // At first boot, make sure no packages are stopped.
2353                     // We usually want to have third party apps initialize
2354                     // in the stopped state, but not at first boot.
2355                     for (PackageSetting pkg : mPackages.values()) {
2356                         pkg.setStopped(false, 0);
2357                         pkg.setNotLaunched(false, 0);
2358                     }
2359                     return;
2360                 }
2361                 str = new FileInputStream(mStoppedPackagesFilename);
2362             }
2363             final XmlPullParser parser = Xml.newPullParser();
2364             parser.setInput(str, null);
2365 
2366             int type;
2367             while ((type=parser.next()) != XmlPullParser.START_TAG
2368                        && type != XmlPullParser.END_DOCUMENT) {
2369                 ;
2370             }
2371 
2372             if (type != XmlPullParser.START_TAG) {
2373                 mReadMessages.append("No start tag found in stopped packages file\n");
2374                 PackageManagerService.reportSettingsProblem(Log.WARN,
2375                         "No start tag found in package manager stopped packages");
2376                 return;
2377             }
2378 
2379             int outerDepth = parser.getDepth();
2380             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2381                    && (type != XmlPullParser.END_TAG
2382                            || parser.getDepth() > outerDepth)) {
2383                 if (type == XmlPullParser.END_TAG
2384                         || type == XmlPullParser.TEXT) {
2385                     continue;
2386                 }
2387 
2388                 String tagName = parser.getName();
2389                 if (tagName.equals(TAG_PACKAGE)) {
2390                     String name = parser.getAttributeValue(null, ATTR_NAME);
2391                     PackageSetting ps = mPackages.get(name);
2392                     if (ps != null) {
2393                         ps.setStopped(true, 0);
2394                         if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
2395                             ps.setNotLaunched(true, 0);
2396                         }
2397                     } else {
2398                         Slog.w(PackageManagerService.TAG,
2399                                 "No package known for stopped package " + name);
2400                     }
2401                     XmlUtils.skipCurrentTag(parser);
2402                 } else {
2403                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
2404                           + parser.getName());
2405                     XmlUtils.skipCurrentTag(parser);
2406                 }
2407             }
2408 
2409             str.close();
2410 
2411         } catch (XmlPullParserException e) {
2412             mReadMessages.append("Error reading: " + e.toString());
2413             PackageManagerService.reportSettingsProblem(Log.ERROR,
2414                     "Error reading stopped packages: " + e);
2415             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2416                     e);
2417 
2418         } catch (java.io.IOException e) {
2419             mReadMessages.append("Error reading: " + e.toString());
2420             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2421             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2422                     e);
2423 
2424         }
2425     }
2426 
writeLPr()2427     void writeLPr() {
2428         //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
2429 
2430         final long startTime = SystemClock.uptimeMillis();
2431 
2432         // Whenever package manager changes something on the system, it writes out whatever it
2433         // changed in the form of a settings object change, and it does so under its internal
2434         // lock --- so if we invalidate the package cache here, we end up invalidating at the
2435         // right time.
2436         invalidatePackageCache();
2437 
2438         // Keep the old settings around until we know the new ones have
2439         // been successfully written.
2440         if (mSettingsFilename.exists()) {
2441             // Presence of backup settings file indicates that we failed
2442             // to persist settings earlier. So preserve the older
2443             // backup for future reference since the current settings
2444             // might have been corrupted.
2445             if (!mBackupSettingsFilename.exists()) {
2446                 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
2447                     Slog.wtf(PackageManagerService.TAG,
2448                             "Unable to backup package manager settings, "
2449                             + " current changes will be lost at reboot");
2450                     return;
2451                 }
2452             } else {
2453                 mSettingsFilename.delete();
2454                 Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
2455             }
2456         }
2457 
2458         mPastSignatures.clear();
2459 
2460         try {
2461             FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
2462             BufferedOutputStream str = new BufferedOutputStream(fstr);
2463 
2464             //XmlSerializer serializer = XmlUtils.serializerInstance();
2465             XmlSerializer serializer = new FastXmlSerializer();
2466             serializer.setOutput(str, StandardCharsets.UTF_8.name());
2467             serializer.startDocument(null, true);
2468             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2469 
2470             serializer.startTag(null, "packages");
2471 
2472             for (int i = 0; i < mVersion.size(); i++) {
2473                 final String volumeUuid = mVersion.keyAt(i);
2474                 final VersionInfo ver = mVersion.valueAt(i);
2475 
2476                 serializer.startTag(null, TAG_VERSION);
2477                 XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid);
2478                 XmlUtils.writeIntAttribute(serializer, ATTR_SDK_VERSION, ver.sdkVersion);
2479                 XmlUtils.writeIntAttribute(serializer, ATTR_DATABASE_VERSION, ver.databaseVersion);
2480                 XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint);
2481                 serializer.endTag(null, TAG_VERSION);
2482             }
2483 
2484             if (mVerifierDeviceIdentity != null) {
2485                 serializer.startTag(null, "verifier");
2486                 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
2487                 serializer.endTag(null, "verifier");
2488             }
2489 
2490             if (mReadExternalStorageEnforced != null) {
2491                 serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
2492                 serializer.attribute(
2493                         null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
2494                 serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
2495             }
2496 
2497             serializer.startTag(null, "permission-trees");
2498             mPermissions.writePermissionTrees(serializer);
2499             serializer.endTag(null, "permission-trees");
2500 
2501             serializer.startTag(null, "permissions");
2502             mPermissions.writePermissions(serializer);
2503             serializer.endTag(null, "permissions");
2504 
2505             for (final PackageSetting pkg : mPackages.values()) {
2506                 writePackageLPr(serializer, pkg);
2507             }
2508 
2509             for (final PackageSetting pkg : mDisabledSysPackages.values()) {
2510                 writeDisabledSysPackageLPr(serializer, pkg);
2511             }
2512 
2513             for (final SharedUserSetting usr : mSharedUsers.values()) {
2514                 serializer.startTag(null, "shared-user");
2515                 serializer.attribute(null, ATTR_NAME, usr.name);
2516                 serializer.attribute(null, "userId",
2517                         Integer.toString(usr.userId));
2518                 usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
2519                 writePermissionsLPr(serializer, usr.getPermissionsState()
2520                         .getInstallPermissionStates());
2521                 serializer.endTag(null, "shared-user");
2522             }
2523 
2524             if (mRenamedPackages.size() > 0) {
2525                 for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
2526                     serializer.startTag(null, "renamed-package");
2527                     serializer.attribute(null, "new", e.getKey());
2528                     serializer.attribute(null, "old", e.getValue());
2529                     serializer.endTag(null, "renamed-package");
2530                 }
2531             }
2532 
2533             final int numIVIs = mRestoredIntentFilterVerifications.size();
2534             if (numIVIs > 0) {
2535                 if (DEBUG_DOMAIN_VERIFICATION) {
2536                     Slog.i(TAG, "Writing restored-ivi entries to packages.xml");
2537                 }
2538                 serializer.startTag(null, "restored-ivi");
2539                 for (int i = 0; i < numIVIs; i++) {
2540                     IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i);
2541                     writeDomainVerificationsLPr(serializer, ivi);
2542                 }
2543                 serializer.endTag(null, "restored-ivi");
2544             } else {
2545                 if (DEBUG_DOMAIN_VERIFICATION) {
2546                     Slog.i(TAG, "  no restored IVI entries to write");
2547                 }
2548             }
2549 
2550             mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
2551 
2552             serializer.endTag(null, "packages");
2553 
2554             serializer.endDocument();
2555 
2556             str.flush();
2557             FileUtils.sync(fstr);
2558             str.close();
2559 
2560             // New settings successfully written, old ones are no longer
2561             // needed.
2562             mBackupSettingsFilename.delete();
2563             FileUtils.setPermissions(mSettingsFilename.toString(),
2564                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
2565                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2566                     -1, -1);
2567 
2568             writeKernelMappingLPr();
2569             writePackageListLPr();
2570             writeAllUsersPackageRestrictionsLPr();
2571             writeAllRuntimePermissionsLPr();
2572             com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
2573                     "package", SystemClock.uptimeMillis() - startTime);
2574             return;
2575 
2576         } catch(java.io.IOException e) {
2577             Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
2578                     + "current changes will be lost at reboot", e);
2579         }
2580         // Clean up partially written files
2581         if (mSettingsFilename.exists()) {
2582             if (!mSettingsFilename.delete()) {
2583                 Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
2584                         + mSettingsFilename);
2585             }
2586         }
2587         //Debug.stopMethodTracing();
2588     }
2589 
writeKernelRemoveUserLPr(int userId)2590     private void writeKernelRemoveUserLPr(int userId) {
2591         if (mKernelMappingFilename == null) return;
2592 
2593         File removeUserIdFile = new File(mKernelMappingFilename, "remove_userid");
2594         if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + userId + " to " + removeUserIdFile
2595                 .getAbsolutePath());
2596         writeIntToFile(removeUserIdFile, userId);
2597     }
2598 
writeKernelMappingLPr()2599     void writeKernelMappingLPr() {
2600         if (mKernelMappingFilename == null) return;
2601 
2602         final String[] known = mKernelMappingFilename.list();
2603         final ArraySet<String> knownSet = new ArraySet<>(known.length);
2604         for (String name : known) {
2605             knownSet.add(name);
2606         }
2607 
2608         for (final PackageSetting ps : mPackages.values()) {
2609             // Package is actively claimed
2610             knownSet.remove(ps.name);
2611             writeKernelMappingLPr(ps);
2612         }
2613 
2614         // Remove any unclaimed mappings
2615         for (int i = 0; i < knownSet.size(); i++) {
2616             final String name = knownSet.valueAt(i);
2617             if (DEBUG_KERNEL) Slog.d(TAG, "Dropping mapping " + name);
2618 
2619             mKernelMapping.remove(name);
2620             new File(mKernelMappingFilename, name).delete();
2621         }
2622     }
2623 
writeKernelMappingLPr(PackageSetting ps)2624     void writeKernelMappingLPr(PackageSetting ps) {
2625         if (mKernelMappingFilename == null || ps == null || ps.name == null) return;
2626 
2627         writeKernelMappingLPr(ps.name, ps.appId, ps.getNotInstalledUserIds());
2628     }
2629 
writeKernelMappingLPr(String name, int appId, int[] excludedUserIds)2630     void writeKernelMappingLPr(String name, int appId, int[] excludedUserIds) {
2631         KernelPackageState cur = mKernelMapping.get(name);
2632         final boolean firstTime = cur == null;
2633         final boolean userIdsChanged = firstTime
2634                 || !Arrays.equals(excludedUserIds, cur.excludedUserIds);
2635 
2636         // Package directory
2637         final File dir = new File(mKernelMappingFilename, name);
2638 
2639         if (firstTime) {
2640             dir.mkdir();
2641             // Create a new mapping state
2642             cur = new KernelPackageState();
2643             mKernelMapping.put(name, cur);
2644         }
2645 
2646         // If mapping is incorrect or non-existent, write the appid file
2647         if (cur.appId != appId) {
2648             final File appIdFile = new File(dir, "appid");
2649             writeIntToFile(appIdFile, appId);
2650             if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + name + " to " + appId);
2651         }
2652 
2653         if (userIdsChanged) {
2654             // Build the exclusion list -- the ids to add to the exclusion list
2655             for (int i = 0; i < excludedUserIds.length; i++) {
2656                 if (cur.excludedUserIds == null || !ArrayUtils.contains(cur.excludedUserIds,
2657                         excludedUserIds[i])) {
2658                     writeIntToFile(new File(dir, "excluded_userids"), excludedUserIds[i]);
2659                     if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + excludedUserIds[i] + " to "
2660                             + name + "/excluded_userids");
2661                 }
2662             }
2663             // Build the inclusion list -- the ids to remove from the exclusion list
2664             if (cur.excludedUserIds != null) {
2665                 for (int i = 0; i < cur.excludedUserIds.length; i++) {
2666                     if (!ArrayUtils.contains(excludedUserIds, cur.excludedUserIds[i])) {
2667                         writeIntToFile(new File(dir, "clear_userid"),
2668                                 cur.excludedUserIds[i]);
2669                         if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + cur.excludedUserIds[i] + " to "
2670                                 + name + "/clear_userid");
2671 
2672                     }
2673                 }
2674             }
2675             cur.excludedUserIds = excludedUserIds;
2676         }
2677     }
2678 
writeIntToFile(File file, int value)2679     private void writeIntToFile(File file, int value) {
2680         try {
2681             FileUtils.bytesToFile(file.getAbsolutePath(),
2682                     Integer.toString(value).getBytes(StandardCharsets.US_ASCII));
2683         } catch (IOException ignored) {
2684             Slog.w(TAG, "Couldn't write " + value + " to " + file.getAbsolutePath());
2685         }
2686     }
2687 
writePackageListLPr()2688     void writePackageListLPr() {
2689         writePackageListLPr(-1);
2690     }
2691 
writePackageListLPr(int creatingUserId)2692     void writePackageListLPr(int creatingUserId) {
2693         String filename = mPackageListFilename.getAbsolutePath();
2694         String ctx = SELinux.fileSelabelLookup(filename);
2695         if (ctx == null) {
2696             Slog.wtf(TAG, "Failed to get SELinux context for " +
2697                 mPackageListFilename.getAbsolutePath());
2698         }
2699 
2700         if (!SELinux.setFSCreateContext(ctx)) {
2701             Slog.wtf(TAG, "Failed to set packages.list SELinux context");
2702         }
2703         try {
2704             writePackageListLPrInternal(creatingUserId);
2705         } finally {
2706             SELinux.setFSCreateContext(null);
2707         }
2708     }
2709 
writePackageListLPrInternal(int creatingUserId)2710     private void writePackageListLPrInternal(int creatingUserId) {
2711         // Only derive GIDs for active users (not dying)
2712         final List<UserInfo> users = getUsers(UserManagerService.getInstance(), true);
2713         int[] userIds = new int[users.size()];
2714         for (int i = 0; i < userIds.length; i++) {
2715             userIds[i] = users.get(i).id;
2716         }
2717         if (creatingUserId != -1) {
2718             userIds = ArrayUtils.appendInt(userIds, creatingUserId);
2719         }
2720 
2721         // Write package list file now, use a JournaledFile.
2722         File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
2723         JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
2724 
2725         final File writeTarget = journal.chooseForWrite();
2726         FileOutputStream fstr;
2727         BufferedWriter writer = null;
2728         try {
2729             fstr = new FileOutputStream(writeTarget);
2730             writer = new BufferedWriter(new OutputStreamWriter(fstr, Charset.defaultCharset()));
2731             FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
2732 
2733             StringBuilder sb = new StringBuilder();
2734             for (final PackageSetting pkg : mPackages.values()) {
2735                 // TODO(b/135203078): This doesn't handle multiple users
2736                 final String dataPath = pkg.pkg == null ? null :
2737                         PackageInfoWithoutStateUtils.getDataDir(pkg.pkg,
2738                                 UserHandle.USER_SYSTEM).getAbsolutePath();
2739 
2740                 if (pkg.pkg == null || dataPath == null) {
2741                     if (!"android".equals(pkg.name)) {
2742                         Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
2743                     }
2744                     continue;
2745                 }
2746 
2747                 final boolean isDebug = pkg.pkg.isDebuggable();
2748                 final int[] gids = pkg.getPermissionsState().computeGids(userIds);
2749 
2750                 // Avoid any application that has a space in its path.
2751                 if (dataPath.indexOf(' ') >= 0)
2752                     continue;
2753 
2754                 // we store on each line the following information for now:
2755                 //
2756                 // pkgName    - package name
2757                 // userId     - application-specific user id
2758                 // debugFlag  - 0 or 1 if the package is debuggable.
2759                 // dataPath   - path to package's data path
2760                 // seinfo     - seinfo label for the app (assigned at install time)
2761                 // gids       - supplementary gids this app launches with
2762                 // profileableFromShellFlag  - 0 or 1 if the package is profileable from shell.
2763                 // longVersionCode - integer version of the package.
2764                 //
2765                 // NOTE: We prefer not to expose all ApplicationInfo flags for now.
2766                 //
2767                 // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
2768                 // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
2769                 //   system/core/libpackagelistparser
2770                 //
2771                 sb.setLength(0);
2772                 sb.append(pkg.pkg.getPackageName());
2773                 sb.append(" ");
2774                 sb.append(pkg.pkg.getUid());
2775                 sb.append(isDebug ? " 1 " : " 0 ");
2776                 sb.append(dataPath);
2777                 sb.append(" ");
2778                 sb.append(AndroidPackageUtils.getSeInfo(pkg.pkg, pkg));
2779                 sb.append(" ");
2780                 if (gids != null && gids.length > 0) {
2781                     sb.append(gids[0]);
2782                     for (int i = 1; i < gids.length; i++) {
2783                         sb.append(",");
2784                         sb.append(gids[i]);
2785                     }
2786                 } else {
2787                     sb.append("none");
2788                 }
2789                 sb.append(" ");
2790                 sb.append(pkg.pkg.isProfileableByShell() ? "1" : "0");
2791                 sb.append(" ");
2792                 sb.append(pkg.pkg.getLongVersionCode());
2793                 sb.append("\n");
2794                 writer.append(sb);
2795             }
2796             writer.flush();
2797             FileUtils.sync(fstr);
2798             writer.close();
2799             journal.commit();
2800         } catch (Exception e) {
2801             Slog.wtf(TAG, "Failed to write packages.list", e);
2802             IoUtils.closeQuietly(writer);
2803             journal.rollback();
2804         }
2805     }
2806 
writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)2807     void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2808             throws java.io.IOException {
2809         serializer.startTag(null, "updated-package");
2810         serializer.attribute(null, ATTR_NAME, pkg.name);
2811         if (pkg.realName != null) {
2812             serializer.attribute(null, "realName", pkg.realName);
2813         }
2814         serializer.attribute(null, "codePath", pkg.codePathString);
2815         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2816         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2817         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2818         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2819         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2820             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2821         }
2822         if (pkg.legacyNativeLibraryPathString != null) {
2823             serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2824         }
2825         if (pkg.primaryCpuAbiString != null) {
2826            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2827         }
2828         if (pkg.secondaryCpuAbiString != null) {
2829             serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2830         }
2831         if (pkg.cpuAbiOverrideString != null) {
2832             serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2833         }
2834 
2835         if (pkg.sharedUser == null) {
2836             serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2837         } else {
2838             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2839         }
2840 
2841         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
2842 
2843         // If this is a shared user, the permissions will be written there.
2844         if (pkg.sharedUser == null) {
2845             writePermissionsLPr(serializer, pkg.getPermissionsState()
2846                     .getInstallPermissionStates());
2847         }
2848 
2849         serializer.endTag(null, "updated-package");
2850     }
2851 
writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)2852     void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2853             throws java.io.IOException {
2854         serializer.startTag(null, "package");
2855         serializer.attribute(null, ATTR_NAME, pkg.name);
2856         if (pkg.realName != null) {
2857             serializer.attribute(null, "realName", pkg.realName);
2858         }
2859         serializer.attribute(null, "codePath", pkg.codePathString);
2860         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2861             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2862         }
2863 
2864         if (pkg.legacyNativeLibraryPathString != null) {
2865             serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2866         }
2867         if (pkg.primaryCpuAbiString != null) {
2868             serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2869         }
2870         if (pkg.secondaryCpuAbiString != null) {
2871             serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2872         }
2873         if (pkg.cpuAbiOverrideString != null) {
2874             serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2875         }
2876 
2877         serializer.attribute(null, "publicFlags", Integer.toString(pkg.pkgFlags));
2878         serializer.attribute(null, "privateFlags", Integer.toString(pkg.pkgPrivateFlags));
2879         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2880         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2881         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2882         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2883         if (pkg.sharedUser == null) {
2884             serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2885         } else {
2886             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2887         }
2888         if (pkg.uidError) {
2889             serializer.attribute(null, "uidError", "true");
2890         }
2891         InstallSource installSource = pkg.installSource;
2892         if (installSource.installerPackageName != null) {
2893             serializer.attribute(null, "installer", installSource.installerPackageName);
2894         }
2895         if (installSource.isOrphaned) {
2896             serializer.attribute(null, "isOrphaned", "true");
2897         }
2898         if (installSource.initiatingPackageName != null) {
2899             serializer.attribute(null, "installInitiator", installSource.initiatingPackageName);
2900         }
2901         if (installSource.isInitiatingPackageUninstalled) {
2902             serializer.attribute(null, "installInitiatorUninstalled", "true");
2903         }
2904         if (installSource.originatingPackageName != null) {
2905             serializer.attribute(null, "installOriginator", installSource.originatingPackageName);
2906         }
2907         if (pkg.volumeUuid != null) {
2908             serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
2909         }
2910         if (pkg.categoryHint != ApplicationInfo.CATEGORY_UNDEFINED) {
2911             serializer.attribute(null, "categoryHint", Integer.toString(pkg.categoryHint));
2912         }
2913         if (pkg.updateAvailable) {
2914             serializer.attribute(null, "updateAvailable", "true");
2915         }
2916         if (pkg.forceQueryableOverride) {
2917             serializer.attribute(null, "forceQueryable", "true");
2918         }
2919 
2920         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
2921 
2922         pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
2923 
2924         if (installSource.initiatingPackageSignatures != null) {
2925             installSource.initiatingPackageSignatures.writeXml(
2926                     serializer, "install-initiator-sigs", mPastSignatures);
2927         }
2928 
2929         writePermissionsLPr(serializer, pkg.getPermissionsState().getInstallPermissionStates());
2930 
2931         writeSigningKeySetLPr(serializer, pkg.keySetData);
2932         writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
2933         writeKeySetAliasesLPr(serializer, pkg.keySetData);
2934         writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
2935         writeMimeGroupLPr(serializer, pkg.mimeGroups);
2936 
2937         serializer.endTag(null, "package");
2938     }
2939 
writeSigningKeySetLPr(XmlSerializer serializer, PackageKeySetData data)2940     void writeSigningKeySetLPr(XmlSerializer serializer,
2941             PackageKeySetData data) throws IOException {
2942         serializer.startTag(null, "proper-signing-keyset");
2943         serializer.attribute(null, "identifier",
2944                 Long.toString(data.getProperSigningKeySet()));
2945         serializer.endTag(null, "proper-signing-keyset");
2946     }
2947 
writeUpgradeKeySetsLPr(XmlSerializer serializer, PackageKeySetData data)2948     void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2949             PackageKeySetData data) throws IOException {
2950         if (data.isUsingUpgradeKeySets()) {
2951             for (long id : data.getUpgradeKeySets()) {
2952                 serializer.startTag(null, "upgrade-keyset");
2953                 serializer.attribute(null, "identifier", Long.toString(id));
2954                 serializer.endTag(null, "upgrade-keyset");
2955             }
2956         }
2957     }
2958 
writeKeySetAliasesLPr(XmlSerializer serializer, PackageKeySetData data)2959     void writeKeySetAliasesLPr(XmlSerializer serializer,
2960             PackageKeySetData data) throws IOException {
2961         for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2962             serializer.startTag(null, "defined-keyset");
2963             serializer.attribute(null, "alias", e.getKey());
2964             serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2965             serializer.endTag(null, "defined-keyset");
2966         }
2967     }
2968 
writePermissionLPr(XmlSerializer serializer, BasePermission bp)2969     void writePermissionLPr(XmlSerializer serializer, BasePermission bp) throws IOException {
2970         bp.writeLPr(serializer);
2971     }
2972 
readLPw(@onNull List<UserInfo> users)2973     boolean readLPw(@NonNull List<UserInfo> users) {
2974         FileInputStream str = null;
2975         if (mBackupSettingsFilename.exists()) {
2976             try {
2977                 str = new FileInputStream(mBackupSettingsFilename);
2978                 mReadMessages.append("Reading from backup settings file\n");
2979                 PackageManagerService.reportSettingsProblem(Log.INFO,
2980                         "Need to read from backup settings file");
2981                 if (mSettingsFilename.exists()) {
2982                     // If both the backup and settings file exist, we
2983                     // ignore the settings since it might have been
2984                     // corrupted.
2985                     Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2986                             + mSettingsFilename);
2987                     mSettingsFilename.delete();
2988                 }
2989             } catch (java.io.IOException e) {
2990                 // We'll try for the normal settings file.
2991             }
2992         }
2993 
2994         mPendingPackages.clear();
2995         mPastSignatures.clear();
2996         mKeySetRefs.clear();
2997         mInstallerPackages.clear();
2998 
2999         try {
3000             if (str == null) {
3001                 if (!mSettingsFilename.exists()) {
3002                     mReadMessages.append("No settings file found\n");
3003                     PackageManagerService.reportSettingsProblem(Log.INFO,
3004                             "No settings file; creating initial state");
3005                     // It's enough to just touch version details to create them
3006                     // with default values
3007                     findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
3008                     findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
3009                     return false;
3010                 }
3011                 str = new FileInputStream(mSettingsFilename);
3012             }
3013             XmlPullParser parser = Xml.newPullParser();
3014             parser.setInput(str, StandardCharsets.UTF_8.name());
3015 
3016             int type;
3017             while ((type = parser.next()) != XmlPullParser.START_TAG
3018                     && type != XmlPullParser.END_DOCUMENT) {
3019                 ;
3020             }
3021 
3022             if (type != XmlPullParser.START_TAG) {
3023                 mReadMessages.append("No start tag found in settings file\n");
3024                 PackageManagerService.reportSettingsProblem(Log.WARN,
3025                         "No start tag found in package manager settings");
3026                 Slog.wtf(PackageManagerService.TAG,
3027                         "No start tag found in package manager settings");
3028                 return false;
3029             }
3030 
3031             int outerDepth = parser.getDepth();
3032             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3033                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3034                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3035                     continue;
3036                 }
3037 
3038                 String tagName = parser.getName();
3039                 if (tagName.equals("package")) {
3040                     readPackageLPw(parser);
3041                 } else if (tagName.equals("permissions")) {
3042                     mPermissions.readPermissions(parser);
3043                 } else if (tagName.equals("permission-trees")) {
3044                     mPermissions.readPermissionTrees(parser);
3045                 } else if (tagName.equals("shared-user")) {
3046                     readSharedUserLPw(parser);
3047                 } else if (tagName.equals("preferred-packages")) {
3048                     // no longer used.
3049                 } else if (tagName.equals("preferred-activities")) {
3050                     // Upgrading from old single-user implementation;
3051                     // these are the preferred activities for user 0.
3052                     readPreferredActivitiesLPw(parser, 0);
3053                 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
3054                     // TODO: check whether this is okay! as it is very
3055                     // similar to how preferred-activities are treated
3056                     readPersistentPreferredActivitiesLPw(parser, 0);
3057                 } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
3058                     // TODO: check whether this is okay! as it is very
3059                     // similar to how preferred-activities are treated
3060                     readCrossProfileIntentFiltersLPw(parser, 0);
3061                 } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
3062                     readDefaultAppsLPw(parser, 0);
3063                 } else if (tagName.equals("updated-package")) {
3064                     readDisabledSysPackageLPw(parser);
3065                 } else if (tagName.equals("renamed-package")) {
3066                     String nname = parser.getAttributeValue(null, "new");
3067                     String oname = parser.getAttributeValue(null, "old");
3068                     if (nname != null && oname != null) {
3069                         mRenamedPackages.put(nname, oname);
3070                     }
3071                 } else if (tagName.equals("restored-ivi")) {
3072                     readRestoredIntentFilterVerifications(parser);
3073                 } else if (tagName.equals("last-platform-version")) {
3074                     // Upgrade from older XML schema
3075                     final VersionInfo internal = findOrCreateVersion(
3076                             StorageManager.UUID_PRIVATE_INTERNAL);
3077                     final VersionInfo external = findOrCreateVersion(
3078                             StorageManager.UUID_PRIMARY_PHYSICAL);
3079 
3080                     internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
3081                     external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
3082                     internal.fingerprint = external.fingerprint =
3083                             XmlUtils.readStringAttribute(parser, "fingerprint");
3084 
3085                 } else if (tagName.equals("database-version")) {
3086                     // Upgrade from older XML schema
3087                     final VersionInfo internal = findOrCreateVersion(
3088                             StorageManager.UUID_PRIVATE_INTERNAL);
3089                     final VersionInfo external = findOrCreateVersion(
3090                             StorageManager.UUID_PRIMARY_PHYSICAL);
3091 
3092                     internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
3093                     external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);
3094 
3095                 } else if (tagName.equals("verifier")) {
3096                     final String deviceIdentity = parser.getAttributeValue(null, "device");
3097                     try {
3098                         mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
3099                     } catch (IllegalArgumentException e) {
3100                         Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
3101                                 + e.getMessage());
3102                     }
3103                 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
3104                     final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
3105                     mReadExternalStorageEnforced =
3106                             "1".equals(enforcement) ? Boolean.TRUE : Boolean.FALSE;
3107                 } else if (tagName.equals("keyset-settings")) {
3108                     mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
3109                 } else if (TAG_VERSION.equals(tagName)) {
3110                     final String volumeUuid = XmlUtils.readStringAttribute(parser,
3111                             ATTR_VOLUME_UUID);
3112                     final VersionInfo ver = findOrCreateVersion(volumeUuid);
3113                     ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
3114                     ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_DATABASE_VERSION);
3115                     ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
3116                 } else {
3117                     Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
3118                             + parser.getName());
3119                     XmlUtils.skipCurrentTag(parser);
3120                 }
3121             }
3122 
3123             str.close();
3124 
3125         } catch (XmlPullParserException e) {
3126             mReadMessages.append("Error reading: " + e.toString());
3127             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
3128             Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
3129 
3130         } catch (java.io.IOException e) {
3131             mReadMessages.append("Error reading: " + e.toString());
3132             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
3133             Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
3134         }
3135 
3136         // If the build is setup to drop runtime permissions
3137         // on update drop the files before loading them.
3138         if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
3139             final VersionInfo internal = getInternalVersion();
3140             if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
3141                 for (UserInfo user : users) {
3142                     mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
3143                 }
3144             }
3145         }
3146 
3147         final int N = mPendingPackages.size();
3148 
3149         for (int i = 0; i < N; i++) {
3150             final PackageSetting p = mPendingPackages.get(i);
3151             final int sharedUserId = p.getSharedUserId();
3152             final Object idObj = getSettingLPr(sharedUserId);
3153             if (idObj instanceof SharedUserSetting) {
3154                 final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
3155                 p.sharedUser = sharedUser;
3156                 p.appId = sharedUser.userId;
3157                 addPackageSettingLPw(p, sharedUser);
3158             } else if (idObj != null) {
3159                 String msg = "Bad package setting: package " + p.name + " has shared uid "
3160                         + sharedUserId + " that is not a shared uid\n";
3161                 mReadMessages.append(msg);
3162                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
3163             } else {
3164                 String msg = "Bad package setting: package " + p.name + " has shared uid "
3165                         + sharedUserId + " that is not defined\n";
3166                 mReadMessages.append(msg);
3167                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
3168             }
3169         }
3170         mPendingPackages.clear();
3171 
3172         if (mBackupStoppedPackagesFilename.exists()
3173                 || mStoppedPackagesFilename.exists()) {
3174             // Read old file
3175             readStoppedLPw();
3176             mBackupStoppedPackagesFilename.delete();
3177             mStoppedPackagesFilename.delete();
3178             // Migrate to new file format
3179             writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
3180         } else {
3181             for (UserInfo user : users) {
3182                 readPackageRestrictionsLPr(user.id);
3183             }
3184         }
3185 
3186         for (UserInfo user : users) {
3187             mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
3188         }
3189 
3190         /*
3191          * Make sure all the updated system packages have their shared users
3192          * associated with them.
3193          */
3194         final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
3195         while (disabledIt.hasNext()) {
3196             final PackageSetting disabledPs = disabledIt.next();
3197             final Object id = getSettingLPr(disabledPs.appId);
3198             if (id != null && id instanceof SharedUserSetting) {
3199                 disabledPs.sharedUser = (SharedUserSetting) id;
3200             }
3201         }
3202 
3203         mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
3204                 + mSharedUsers.size() + " shared uids\n");
3205 
3206         writeKernelMappingLPr();
3207 
3208         return true;
3209     }
3210 
readPermissionStateForUserSyncLPr(@serIdInt int userId)3211     void readPermissionStateForUserSyncLPr(@UserIdInt int userId) {
3212         mRuntimePermissionsPersistence.readStateForUserSyncLPr(userId);
3213     }
3214 
applyDefaultPreferredAppsLPw(int userId)3215     void applyDefaultPreferredAppsLPw(int userId) {
3216         // First pull data from any pre-installed apps.
3217         final PackageManagerInternal pmInternal =
3218                 LocalServices.getService(PackageManagerInternal.class);
3219         for (PackageSetting ps : mPackages.values()) {
3220             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
3221                     && !ps.pkg.getPreferredActivityFilters().isEmpty()) {
3222                 List<Pair<String, ParsedIntentInfo>> intents
3223                         = ps.pkg.getPreferredActivityFilters();
3224                 for (int i=0; i<intents.size(); i++) {
3225                     Pair<String, ParsedIntentInfo> pair = intents.get(i);
3226                     applyDefaultPreferredActivityLPw(pmInternal, pair.second, new ComponentName(
3227                             ps.name, pair.first), userId);
3228                 }
3229             }
3230         }
3231 
3232         // Read preferred apps from .../etc/preferred-apps directories.
3233         int size = PackageManagerService.SYSTEM_PARTITIONS.size();
3234         for (int index = 0; index < size; index++) {
3235             PackageManagerService.ScanPartition partition =
3236                     PackageManagerService.SYSTEM_PARTITIONS.get(index);
3237 
3238             File preferredDir = new File(partition.getFolder(), "etc/preferred-apps");
3239             if (!preferredDir.exists() || !preferredDir.isDirectory()) {
3240                 continue;
3241             }
3242 
3243             if (!preferredDir.canRead()) {
3244                 Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
3245                 continue;
3246             }
3247 
3248             // Iterate over the files in the directory and scan .xml files
3249             File[] files = preferredDir.listFiles();
3250             if (ArrayUtils.isEmpty(files)) {
3251                 continue;
3252             }
3253 
3254             for (File f : files) {
3255                 if (!f.getPath().endsWith(".xml")) {
3256                     Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir
3257                             + " directory, ignoring");
3258                     continue;
3259                 }
3260                 if (!f.canRead()) {
3261                     Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
3262                     continue;
3263                 }
3264                 if (PackageManagerService.DEBUG_PREFERRED) {
3265                     Log.d(TAG, "Reading default preferred " + f);
3266                 }
3267 
3268                 try (InputStream str = new BufferedInputStream(new FileInputStream(f))) {
3269                     XmlPullParser parser = Xml.newPullParser();
3270                     parser.setInput(str, null);
3271 
3272                     int type;
3273                     while ((type = parser.next()) != XmlPullParser.START_TAG
3274                             && type != XmlPullParser.END_DOCUMENT) {
3275                         ;
3276                     }
3277 
3278                     if (type != XmlPullParser.START_TAG) {
3279                         Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
3280                         continue;
3281                     }
3282                     if (!"preferred-activities".equals(parser.getName())) {
3283                         Slog.w(TAG, "Preferred apps file " + f
3284                                 + " does not start with 'preferred-activities'");
3285                         continue;
3286                     }
3287                     readDefaultPreferredActivitiesLPw(parser, userId);
3288                 } catch (XmlPullParserException e) {
3289                     Slog.w(TAG, "Error reading apps file " + f, e);
3290                 } catch (IOException e) {
3291                     Slog.w(TAG, "Error reading apps file " + f, e);
3292                 }
3293             }
3294         }
3295     }
3296 
applyDefaultPreferredActivityLPw( PackageManagerInternal pmInternal, IntentFilter tmpPa, ComponentName cn, int userId)3297     private void applyDefaultPreferredActivityLPw(
3298             PackageManagerInternal pmInternal, IntentFilter tmpPa, ComponentName cn, int userId) {
3299         // The initial preferences only specify the target activity
3300         // component and intent-filter, not the set of matches.  So we
3301         // now need to query for the matches to build the correct
3302         // preferred activity entry.
3303         if (PackageManagerService.DEBUG_PREFERRED) {
3304             Log.d(TAG, "Processing preferred:");
3305             tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
3306         }
3307         Intent intent = new Intent();
3308         int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE
3309                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
3310         intent.setAction(tmpPa.getAction(0));
3311         for (int i=0; i<tmpPa.countCategories(); i++) {
3312             String cat = tmpPa.getCategory(i);
3313             if (cat.equals(Intent.CATEGORY_DEFAULT)) {
3314                 flags |= MATCH_DEFAULT_ONLY;
3315             } else {
3316                 intent.addCategory(cat);
3317             }
3318         }
3319 
3320         boolean doNonData = true;
3321         boolean hasSchemes = false;
3322 
3323         final int dataSchemesCount = tmpPa.countDataSchemes();
3324         for (int ischeme = 0; ischeme < dataSchemesCount; ischeme++) {
3325             boolean doScheme = true;
3326             final String scheme = tmpPa.getDataScheme(ischeme);
3327             if (scheme != null && !scheme.isEmpty()) {
3328                 hasSchemes = true;
3329             }
3330             final int dataSchemeSpecificPartsCount = tmpPa.countDataSchemeSpecificParts();
3331             for (int issp = 0; issp < dataSchemeSpecificPartsCount; issp++) {
3332                 Uri.Builder builder = new Uri.Builder();
3333                 builder.scheme(scheme);
3334                 PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
3335                 builder.opaquePart(ssp.getPath());
3336                 Intent finalIntent = new Intent(intent);
3337                 finalIntent.setData(builder.build());
3338                 applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
3339                         scheme, ssp, null, null, userId);
3340                 doScheme = false;
3341             }
3342             final int dataAuthoritiesCount = tmpPa.countDataAuthorities();
3343             for (int iauth = 0; iauth < dataAuthoritiesCount; iauth++) {
3344                 boolean doAuth = true;
3345                 final IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
3346                 final int dataPathsCount = tmpPa.countDataPaths();
3347                 for (int ipath = 0; ipath < dataPathsCount; ipath++) {
3348                     Uri.Builder builder = new Uri.Builder();
3349                     builder.scheme(scheme);
3350                     if (auth.getHost() != null) {
3351                         builder.authority(auth.getHost());
3352                     }
3353                     PatternMatcher path = tmpPa.getDataPath(ipath);
3354                     builder.path(path.getPath());
3355                     Intent finalIntent = new Intent(intent);
3356                     finalIntent.setData(builder.build());
3357                     applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
3358                             scheme, null, auth, path, userId);
3359                     doAuth = doScheme = false;
3360                 }
3361                 if (doAuth) {
3362                     Uri.Builder builder = new Uri.Builder();
3363                     builder.scheme(scheme);
3364                     if (auth.getHost() != null) {
3365                         builder.authority(auth.getHost());
3366                     }
3367                     Intent finalIntent = new Intent(intent);
3368                     finalIntent.setData(builder.build());
3369                     applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
3370                             scheme, null, auth, null, userId);
3371                     doScheme = false;
3372                 }
3373             }
3374             if (doScheme) {
3375                 Uri.Builder builder = new Uri.Builder();
3376                 builder.scheme(scheme);
3377                 Intent finalIntent = new Intent(intent);
3378                 finalIntent.setData(builder.build());
3379                 applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
3380                         scheme, null, null, null, userId);
3381             }
3382             doNonData = false;
3383         }
3384 
3385         for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
3386             String mimeType = tmpPa.getDataType(idata);
3387             if (hasSchemes) {
3388                 Uri.Builder builder = new Uri.Builder();
3389                 for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3390                     String scheme = tmpPa.getDataScheme(ischeme);
3391                     if (scheme != null && !scheme.isEmpty()) {
3392                         Intent finalIntent = new Intent(intent);
3393                         builder.scheme(scheme);
3394                         finalIntent.setDataAndType(builder.build(), mimeType);
3395                         applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
3396                                 scheme, null, null, null, userId);
3397                     }
3398                 }
3399             } else {
3400                 Intent finalIntent = new Intent(intent);
3401                 finalIntent.setType(mimeType);
3402                 applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
3403                         null, null, null, null, userId);
3404             }
3405             doNonData = false;
3406         }
3407 
3408         if (doNonData) {
3409             applyDefaultPreferredActivityLPw(pmInternal, intent, flags, cn,
3410                     null, null, null, null, userId);
3411         }
3412     }
3413 
applyDefaultPreferredActivityLPw(PackageManagerInternal pmInternal, Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp, IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId)3414     private void applyDefaultPreferredActivityLPw(PackageManagerInternal pmInternal, Intent intent,
3415             int flags, ComponentName cn, String scheme, PatternMatcher ssp,
3416             IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
3417         final List<ResolveInfo> ri =
3418                 pmInternal.queryIntentActivities(
3419                         intent, intent.getType(), flags, Binder.getCallingUid(), 0);
3420         if (PackageManagerService.DEBUG_PREFERRED) {
3421             Log.d(TAG, "Queried " + intent + " results: " + ri);
3422         }
3423         int systemMatch = 0;
3424         int thirdPartyMatch = 0;
3425         final int numMatches = (ri == null ? 0 : ri.size());
3426         if (numMatches <= 1) {
3427             Slog.w(TAG, "No potential matches found for " + intent
3428                     + " while setting preferred " + cn.flattenToShortString());
3429             return;
3430         }
3431         boolean haveAct = false;
3432         ComponentName haveNonSys = null;
3433         ComponentName[] set = new ComponentName[ri.size()];
3434         for (int i = 0; i < numMatches; i++) {
3435             final ActivityInfo ai = ri.get(i).activityInfo;
3436             set[i] = new ComponentName(ai.packageName, ai.name);
3437             if ((ai.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
3438                 if (ri.get(i).match >= thirdPartyMatch) {
3439                     // Keep track of the best match we find of all third
3440                     // party apps, for use later to determine if we actually
3441                     // want to set a preferred app for this intent.
3442                     if (PackageManagerService.DEBUG_PREFERRED) {
3443                         Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": non-system!");
3444                     }
3445                     haveNonSys = set[i];
3446                     break;
3447                 }
3448             } else if (cn.getPackageName().equals(ai.packageName)
3449                     && cn.getClassName().equals(ai.name)) {
3450                 if (PackageManagerService.DEBUG_PREFERRED) {
3451                     Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": default!");
3452                 }
3453                 haveAct = true;
3454                 systemMatch = ri.get(i).match;
3455             } else {
3456                 if (PackageManagerService.DEBUG_PREFERRED) {
3457                     Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": skipped");
3458                 }
3459             }
3460         }
3461         if (haveNonSys != null && thirdPartyMatch < systemMatch) {
3462             // If we have a matching third party app, but its match is not as
3463             // good as the built-in system app, then we don't want to actually
3464             // consider it a match because presumably the built-in app is still
3465             // the thing we want users to see by default.
3466             haveNonSys = null;
3467         }
3468         if (haveAct && haveNonSys == null) {
3469             IntentFilter filter = new IntentFilter();
3470             if (intent.getAction() != null) {
3471                 filter.addAction(intent.getAction());
3472             }
3473             if (intent.getCategories() != null) {
3474                 for (String cat : intent.getCategories()) {
3475                     filter.addCategory(cat);
3476                 }
3477             }
3478             if ((flags & MATCH_DEFAULT_ONLY) != 0) {
3479                 filter.addCategory(Intent.CATEGORY_DEFAULT);
3480             }
3481             if (scheme != null) {
3482                 filter.addDataScheme(scheme);
3483             }
3484             if (ssp != null) {
3485                 filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
3486             }
3487             if (auth != null) {
3488                 filter.addDataAuthority(auth);
3489             }
3490             if (path != null) {
3491                 filter.addDataPath(path);
3492             }
3493             if (intent.getType() != null) {
3494                 try {
3495                     filter.addDataType(intent.getType());
3496                 } catch (IntentFilter.MalformedMimeTypeException ex) {
3497                     Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
3498                 }
3499             }
3500             PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
3501             editPreferredActivitiesLPw(userId).addFilter(pa);
3502         } else if (haveNonSys == null) {
3503             StringBuilder sb = new StringBuilder();
3504             sb.append("No component ");
3505             sb.append(cn.flattenToShortString());
3506             sb.append(" found setting preferred ");
3507             sb.append(intent);
3508             sb.append("; possible matches are ");
3509             for (int i = 0; i < set.length; i++) {
3510                 if (i > 0) sb.append(", ");
3511                 sb.append(set[i].flattenToShortString());
3512             }
3513             Slog.w(TAG, sb.toString());
3514         } else {
3515             Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
3516                     + haveNonSys.flattenToShortString());
3517         }
3518     }
3519 
readDefaultPreferredActivitiesLPw(XmlPullParser parser, int userId)3520     private void readDefaultPreferredActivitiesLPw(XmlPullParser parser, int userId)
3521             throws XmlPullParserException, IOException {
3522         final PackageManagerInternal pmInternal =
3523                 LocalServices.getService(PackageManagerInternal.class);
3524         int outerDepth = parser.getDepth();
3525         int type;
3526         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3527                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3528             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3529                 continue;
3530             }
3531 
3532             String tagName = parser.getName();
3533             if (tagName.equals(TAG_ITEM)) {
3534                 PreferredActivity tmpPa = new PreferredActivity(parser);
3535                 if (tmpPa.mPref.getParseError() == null) {
3536                     applyDefaultPreferredActivityLPw(
3537                             pmInternal, tmpPa, tmpPa.mPref.mComponent, userId);
3538                 } else {
3539                     PackageManagerService.reportSettingsProblem(Log.WARN,
3540                             "Error in package manager settings: <preferred-activity> "
3541                                     + tmpPa.mPref.getParseError() + " at "
3542                                     + parser.getPositionDescription());
3543                 }
3544             } else {
3545                 PackageManagerService.reportSettingsProblem(Log.WARN,
3546                         "Unknown element under <preferred-activities>: " + parser.getName());
3547                 XmlUtils.skipCurrentTag(parser);
3548             }
3549         }
3550     }
3551 
readDisabledSysPackageLPw(XmlPullParser parser)3552     private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
3553             IOException {
3554         String name = parser.getAttributeValue(null, ATTR_NAME);
3555         String realName = parser.getAttributeValue(null, "realName");
3556         String codePathStr = parser.getAttributeValue(null, "codePath");
3557         String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3558 
3559         String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
3560         String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3561 
3562         String parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3563 
3564         String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
3565         String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
3566         String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
3567 
3568         if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
3569             primaryCpuAbiStr = legacyCpuAbiStr;
3570         }
3571 
3572         if (resourcePathStr == null) {
3573             resourcePathStr = codePathStr;
3574         }
3575         String version = parser.getAttributeValue(null, "version");
3576         long versionCode = 0;
3577         if (version != null) {
3578             try {
3579                 versionCode = Long.parseLong(version);
3580             } catch (NumberFormatException e) {
3581             }
3582         }
3583 
3584         int pkgFlags = 0;
3585         int pkgPrivateFlags = 0;
3586         pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3587         if (codePathStr.contains("/priv-app/")) {
3588             pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3589         }
3590         PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
3591                 new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
3592                 secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
3593                 0 /*sharedUserId*/, null, null, null);
3594         String timeStampStr = parser.getAttributeValue(null, "ft");
3595         if (timeStampStr != null) {
3596             try {
3597                 long timeStamp = Long.parseLong(timeStampStr, 16);
3598                 ps.setTimeStamp(timeStamp);
3599             } catch (NumberFormatException e) {
3600             }
3601         } else {
3602             timeStampStr = parser.getAttributeValue(null, "ts");
3603             if (timeStampStr != null) {
3604                 try {
3605                     long timeStamp = Long.parseLong(timeStampStr);
3606                     ps.setTimeStamp(timeStamp);
3607                 } catch (NumberFormatException e) {
3608                 }
3609             }
3610         }
3611         timeStampStr = parser.getAttributeValue(null, "it");
3612         if (timeStampStr != null) {
3613             try {
3614                 ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
3615             } catch (NumberFormatException e) {
3616             }
3617         }
3618         timeStampStr = parser.getAttributeValue(null, "ut");
3619         if (timeStampStr != null) {
3620             try {
3621                 ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
3622             } catch (NumberFormatException e) {
3623             }
3624         }
3625         String idStr = parser.getAttributeValue(null, "userId");
3626         ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
3627         if (ps.appId <= 0) {
3628             String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3629             ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3630         }
3631 
3632         int outerDepth = parser.getDepth();
3633         int type;
3634         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3635                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3636             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3637                 continue;
3638             }
3639 
3640             if (parser.getName().equals(TAG_PERMISSIONS)) {
3641                 readInstallPermissionsLPr(parser, ps.getPermissionsState());
3642             } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) {
3643                 readUsesStaticLibLPw(parser, ps);
3644             } else {
3645                 PackageManagerService.reportSettingsProblem(Log.WARN,
3646                         "Unknown element under <updated-package>: " + parser.getName());
3647                 XmlUtils.skipCurrentTag(parser);
3648             }
3649         }
3650 
3651         mDisabledSysPackages.put(name, ps);
3652     }
3653 
3654     private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27;
3655     private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
3656     private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
3657 
readPackageLPw(XmlPullParser parser)3658     private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
3659         String name = null;
3660         String realName = null;
3661         String idStr = null;
3662         String sharedIdStr = null;
3663         String codePathStr = null;
3664         String resourcePathStr = null;
3665         String legacyCpuAbiString = null;
3666         String legacyNativeLibraryPathStr = null;
3667         String primaryCpuAbiString = null;
3668         String secondaryCpuAbiString = null;
3669         String cpuAbiOverrideString = null;
3670         String systemStr = null;
3671         String installerPackageName = null;
3672         String isOrphaned = null;
3673         String installOriginatingPackageName = null;
3674         String installInitiatingPackageName = null;
3675         String installInitiatorUninstalled = null;
3676         String volumeUuid = null;
3677         String categoryHintString = null;
3678         String updateAvailable = null;
3679         int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
3680         String uidError = null;
3681         int pkgFlags = 0;
3682         int pkgPrivateFlags = 0;
3683         long timeStamp = 0;
3684         long firstInstallTime = 0;
3685         long lastUpdateTime = 0;
3686         PackageSetting packageSetting = null;
3687         String version = null;
3688         long versionCode = 0;
3689         String installedForceQueryable = null;
3690         try {
3691             name = parser.getAttributeValue(null, ATTR_NAME);
3692             realName = parser.getAttributeValue(null, "realName");
3693             idStr = parser.getAttributeValue(null, "userId");
3694             uidError = parser.getAttributeValue(null, "uidError");
3695             sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3696             codePathStr = parser.getAttributeValue(null, "codePath");
3697             resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3698 
3699             legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
3700 
3701             legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3702             primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
3703             secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
3704             cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
3705             updateAvailable = parser.getAttributeValue(null, "updateAvailable");
3706             installedForceQueryable = parser.getAttributeValue(null, "forceQueryable");
3707 
3708             if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
3709                 primaryCpuAbiString = legacyCpuAbiString;
3710             }
3711 
3712             version = parser.getAttributeValue(null, "version");
3713             if (version != null) {
3714                 try {
3715                     versionCode = Long.parseLong(version);
3716                 } catch (NumberFormatException e) {
3717                 }
3718             }
3719             installerPackageName = parser.getAttributeValue(null, "installer");
3720             isOrphaned = parser.getAttributeValue(null, "isOrphaned");
3721             installInitiatingPackageName = parser.getAttributeValue(null, "installInitiator");
3722             installOriginatingPackageName = parser.getAttributeValue(null, "installOriginator");
3723             installInitiatorUninstalled = parser.getAttributeValue(null,
3724                     "installInitiatorUninstalled");
3725             volumeUuid = parser.getAttributeValue(null, "volumeUuid");
3726             categoryHintString = parser.getAttributeValue(null, "categoryHint");
3727             if (categoryHintString != null) {
3728                 try {
3729                     categoryHint = Integer.parseInt(categoryHintString);
3730                 } catch (NumberFormatException e) {
3731                 }
3732             }
3733 
3734             systemStr = parser.getAttributeValue(null, "publicFlags");
3735             if (systemStr != null) {
3736                 try {
3737                     pkgFlags = Integer.parseInt(systemStr);
3738                 } catch (NumberFormatException e) {
3739                 }
3740                 systemStr = parser.getAttributeValue(null, "privateFlags");
3741                 if (systemStr != null) {
3742                     try {
3743                         pkgPrivateFlags = Integer.parseInt(systemStr);
3744                     } catch (NumberFormatException e) {
3745                     }
3746                 }
3747             } else {
3748                 // Pre-M -- both public and private flags were stored in one "flags" field.
3749                 systemStr = parser.getAttributeValue(null, "flags");
3750                 if (systemStr != null) {
3751                     try {
3752                         pkgFlags = Integer.parseInt(systemStr);
3753                     } catch (NumberFormatException e) {
3754                     }
3755                     if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) {
3756                         pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
3757                     }
3758                     if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) {
3759                         pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
3760                     }
3761                     if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) {
3762                         pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3763                     }
3764                     pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN
3765                             | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE
3766                             | PRE_M_APP_INFO_FLAG_PRIVILEGED);
3767                 } else {
3768                     // For backward compatibility
3769                     systemStr = parser.getAttributeValue(null, "system");
3770                     if (systemStr != null) {
3771                         pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
3772                                 : 0;
3773                     } else {
3774                         // Old settings that don't specify system... just treat
3775                         // them as system, good enough.
3776                         pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3777                     }
3778                 }
3779             }
3780             String timeStampStr = parser.getAttributeValue(null, "ft");
3781             if (timeStampStr != null) {
3782                 try {
3783                     timeStamp = Long.parseLong(timeStampStr, 16);
3784                 } catch (NumberFormatException e) {
3785                 }
3786             } else {
3787                 timeStampStr = parser.getAttributeValue(null, "ts");
3788                 if (timeStampStr != null) {
3789                     try {
3790                         timeStamp = Long.parseLong(timeStampStr);
3791                     } catch (NumberFormatException e) {
3792                     }
3793                 }
3794             }
3795             timeStampStr = parser.getAttributeValue(null, "it");
3796             if (timeStampStr != null) {
3797                 try {
3798                     firstInstallTime = Long.parseLong(timeStampStr, 16);
3799                 } catch (NumberFormatException e) {
3800                 }
3801             }
3802             timeStampStr = parser.getAttributeValue(null, "ut");
3803             if (timeStampStr != null) {
3804                 try {
3805                     lastUpdateTime = Long.parseLong(timeStampStr, 16);
3806                 } catch (NumberFormatException e) {
3807                 }
3808             }
3809             if (PackageManagerService.DEBUG_SETTINGS)
3810                 Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
3811                         + " sharedUserId=" + sharedIdStr);
3812             final int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3813             final int sharedUserId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3814             if (resourcePathStr == null) {
3815                 resourcePathStr = codePathStr;
3816             }
3817             if (realName != null) {
3818                 realName = realName.intern();
3819             }
3820             if (name == null) {
3821                 PackageManagerService.reportSettingsProblem(Log.WARN,
3822                         "Error in package manager settings: <package> has no name at "
3823                                 + parser.getPositionDescription());
3824             } else if (codePathStr == null) {
3825                 PackageManagerService.reportSettingsProblem(Log.WARN,
3826                         "Error in package manager settings: <package> has no codePath at "
3827                                 + parser.getPositionDescription());
3828             } else if (userId > 0) {
3829                 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
3830                         new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
3831                         secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
3832                         pkgPrivateFlags, null /*usesStaticLibraries*/,
3833                         null /*usesStaticLibraryVersions*/, null /*mimeGroups*/);
3834                 if (PackageManagerService.DEBUG_SETTINGS)
3835                     Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
3836                             + userId + " pkg=" + packageSetting);
3837                 if (packageSetting == null) {
3838                     PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
3839                             + userId + " while parsing settings at "
3840                             + parser.getPositionDescription());
3841                 } else {
3842                     packageSetting.setTimeStamp(timeStamp);
3843                     packageSetting.firstInstallTime = firstInstallTime;
3844                     packageSetting.lastUpdateTime = lastUpdateTime;
3845                 }
3846             } else if (sharedIdStr != null) {
3847                 if (sharedUserId > 0) {
3848                     packageSetting = new PackageSetting(name.intern(), realName, new File(
3849                             codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
3850                             primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
3851                             versionCode, pkgFlags, pkgPrivateFlags, sharedUserId,
3852                             null /*usesStaticLibraries*/,
3853                             null /*usesStaticLibraryVersions*/,
3854                             null /*mimeGroups*/);
3855                     packageSetting.setTimeStamp(timeStamp);
3856                     packageSetting.firstInstallTime = firstInstallTime;
3857                     packageSetting.lastUpdateTime = lastUpdateTime;
3858                     mPendingPackages.add(packageSetting);
3859                     if (PackageManagerService.DEBUG_SETTINGS)
3860                         Log.i(PackageManagerService.TAG, "Reading package " + name
3861                                 + ": sharedUserId=" + sharedUserId + " pkg=" + packageSetting);
3862                 } else {
3863                     PackageManagerService.reportSettingsProblem(Log.WARN,
3864                             "Error in package manager settings: package " + name
3865                                     + " has bad sharedId " + sharedIdStr + " at "
3866                                     + parser.getPositionDescription());
3867                 }
3868             } else {
3869                 PackageManagerService.reportSettingsProblem(Log.WARN,
3870                         "Error in package manager settings: package " + name + " has bad userId "
3871                                 + idStr + " at " + parser.getPositionDescription());
3872             }
3873         } catch (NumberFormatException e) {
3874             PackageManagerService.reportSettingsProblem(Log.WARN,
3875                     "Error in package manager settings: package " + name + " has bad userId "
3876                             + idStr + " at " + parser.getPositionDescription());
3877         }
3878         if (packageSetting != null) {
3879             packageSetting.uidError = "true".equals(uidError);
3880             InstallSource installSource = InstallSource.create(
3881                     installInitiatingPackageName, installOriginatingPackageName,
3882                     installerPackageName, "true".equals(isOrphaned),
3883                     "true".equals(installInitiatorUninstalled));
3884             packageSetting.installSource = installSource;
3885             packageSetting.volumeUuid = volumeUuid;
3886             packageSetting.categoryHint = categoryHint;
3887             packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
3888             packageSetting.primaryCpuAbiString = primaryCpuAbiString;
3889             packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
3890             packageSetting.updateAvailable = "true".equals(updateAvailable);
3891             packageSetting.forceQueryableOverride = "true".equals(installedForceQueryable);
3892             // Handle legacy string here for single-user mode
3893             final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
3894             if (enabledStr != null) {
3895                 try {
3896                     packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
3897                 } catch (NumberFormatException e) {
3898                     if (enabledStr.equalsIgnoreCase("true")) {
3899                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
3900                     } else if (enabledStr.equalsIgnoreCase("false")) {
3901                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
3902                     } else if (enabledStr.equalsIgnoreCase("default")) {
3903                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3904                     } else {
3905                         PackageManagerService.reportSettingsProblem(Log.WARN,
3906                                 "Error in package manager settings: package " + name
3907                                         + " has bad enabled value: " + idStr + " at "
3908                                         + parser.getPositionDescription());
3909                     }
3910                 }
3911             } else {
3912                 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3913             }
3914 
3915             addInstallerPackageNames(installSource);
3916 
3917             int outerDepth = parser.getDepth();
3918             int type;
3919             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3920                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3921                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3922                     continue;
3923                 }
3924 
3925                 String tagName = parser.getName();
3926                 // Legacy
3927                 if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
3928                     readDisabledComponentsLPw(packageSetting, parser, 0);
3929                 } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
3930                     readEnabledComponentsLPw(packageSetting, parser, 0);
3931                 } else if (tagName.equals("sigs")) {
3932                     packageSetting.signatures.readXml(parser, mPastSignatures);
3933                 } else if (tagName.equals(TAG_PERMISSIONS)) {
3934                     readInstallPermissionsLPr(parser,
3935                             packageSetting.getPermissionsState());
3936                     packageSetting.installPermissionsFixed = true;
3937                 } else if (tagName.equals("proper-signing-keyset")) {
3938                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3939                     Integer refCt = mKeySetRefs.get(id);
3940                     if (refCt != null) {
3941                         mKeySetRefs.put(id, refCt + 1);
3942                     } else {
3943                         mKeySetRefs.put(id, 1);
3944                     }
3945                     packageSetting.keySetData.setProperSigningKeySet(id);
3946                 } else if (tagName.equals("signing-keyset")) {
3947                     // from v1 of keysetmanagerservice - no longer used
3948                 } else if (tagName.equals("upgrade-keyset")) {
3949                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3950                     packageSetting.keySetData.addUpgradeKeySetById(id);
3951                 } else if (tagName.equals("defined-keyset")) {
3952                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3953                     String alias = parser.getAttributeValue(null, "alias");
3954                     Integer refCt = mKeySetRefs.get(id);
3955                     if (refCt != null) {
3956                         mKeySetRefs.put(id, refCt + 1);
3957                     } else {
3958                         mKeySetRefs.put(id, 1);
3959                     }
3960                     packageSetting.keySetData.addDefinedKeySet(id, alias);
3961                 } else if (tagName.equals("install-initiator-sigs")) {
3962                     final PackageSignatures signatures = new PackageSignatures();
3963                     signatures.readXml(parser, mPastSignatures);
3964                     packageSetting.installSource =
3965                             packageSetting.installSource.setInitiatingPackageSignatures(signatures);
3966                 } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
3967                     readDomainVerificationLPw(parser, packageSetting);
3968                 } else if (tagName.equals(TAG_MIME_GROUP)) {
3969                     packageSetting.mimeGroups = readMimeGroupLPw(parser, packageSetting.mimeGroups);
3970                 } else {
3971                     PackageManagerService.reportSettingsProblem(Log.WARN,
3972                             "Unknown element under <package>: " + parser.getName());
3973                     XmlUtils.skipCurrentTag(parser);
3974                 }
3975             }
3976         } else {
3977             XmlUtils.skipCurrentTag(parser);
3978         }
3979     }
3980 
addInstallerPackageNames(InstallSource installSource)3981     void addInstallerPackageNames(InstallSource installSource) {
3982         if (installSource.installerPackageName != null) {
3983             mInstallerPackages.add(installSource.installerPackageName);
3984         }
3985         if (installSource.initiatingPackageName != null) {
3986             mInstallerPackages.add(installSource.initiatingPackageName);
3987         }
3988         if (installSource.originatingPackageName != null) {
3989             mInstallerPackages.add(installSource.originatingPackageName);
3990         }
3991     }
3992 
readMimeGroupLPw(XmlPullParser parser, Map<String, ArraySet<String>> mimeGroups)3993     private Map<String, ArraySet<String>> readMimeGroupLPw(XmlPullParser parser,
3994             Map<String, ArraySet<String>> mimeGroups) throws XmlPullParserException, IOException {
3995         String groupName = parser.getAttributeValue(null, ATTR_NAME);
3996         if (groupName == null) {
3997             XmlUtils.skipCurrentTag(parser);
3998             return mimeGroups;
3999         }
4000 
4001         if (mimeGroups == null) {
4002             mimeGroups = new ArrayMap<>();
4003         }
4004 
4005         ArraySet<String> mimeTypes = mimeGroups.get(groupName);
4006         if (mimeTypes == null) {
4007             mimeTypes = new ArraySet<>();
4008             mimeGroups.put(groupName, mimeTypes);
4009         }
4010         int outerDepth = parser.getDepth();
4011         int type;
4012         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4013                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4014             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4015                 continue;
4016             }
4017 
4018             String tagName = parser.getName();
4019             if (tagName.equals(TAG_MIME_TYPE)) {
4020                 String typeName = parser.getAttributeValue(null, ATTR_VALUE);
4021                 if (typeName != null) {
4022                     mimeTypes.add(typeName);
4023                 }
4024             } else {
4025                 PackageManagerService.reportSettingsProblem(Log.WARN,
4026                         "Unknown element under <mime-group>: " + parser.getName());
4027                 XmlUtils.skipCurrentTag(parser);
4028             }
4029         }
4030 
4031         return mimeGroups;
4032     }
4033 
writeMimeGroupLPr(XmlSerializer serializer, Map<String, ArraySet<String>> mimeGroups)4034     private void writeMimeGroupLPr(XmlSerializer serializer,
4035             Map<String, ArraySet<String>> mimeGroups) throws IOException {
4036         if (mimeGroups == null) {
4037             return;
4038         }
4039 
4040         for (String mimeGroup: mimeGroups.keySet()) {
4041             serializer.startTag(null, TAG_MIME_GROUP);
4042             serializer.attribute(null, ATTR_NAME, mimeGroup);
4043 
4044             for (String mimeType: mimeGroups.get(mimeGroup)) {
4045                 serializer.startTag(null, TAG_MIME_TYPE);
4046                 serializer.attribute(null, ATTR_VALUE, mimeType);
4047                 serializer.endTag(null, TAG_MIME_TYPE);
4048             }
4049 
4050             serializer.endTag(null, TAG_MIME_GROUP);
4051         }
4052     }
4053 
readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, int userId)4054     private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
4055             int userId) throws IOException, XmlPullParserException {
4056         int outerDepth = parser.getDepth();
4057         int type;
4058         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4059                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4060             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4061                 continue;
4062             }
4063 
4064             String tagName = parser.getName();
4065             if (tagName.equals(TAG_ITEM)) {
4066                 String name = parser.getAttributeValue(null, ATTR_NAME);
4067                 if (name != null) {
4068                     packageSetting.addDisabledComponent(name.intern(), userId);
4069                 } else {
4070                     PackageManagerService.reportSettingsProblem(Log.WARN,
4071                             "Error in package manager settings: <disabled-components> has"
4072                                     + " no name at " + parser.getPositionDescription());
4073                 }
4074             } else {
4075                 PackageManagerService.reportSettingsProblem(Log.WARN,
4076                         "Unknown element under <disabled-components>: " + parser.getName());
4077             }
4078             XmlUtils.skipCurrentTag(parser);
4079         }
4080     }
4081 
readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, int userId)4082     private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
4083             int userId) throws IOException, XmlPullParserException {
4084         int outerDepth = parser.getDepth();
4085         int type;
4086         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4087                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4088             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4089                 continue;
4090             }
4091 
4092             String tagName = parser.getName();
4093             if (tagName.equals(TAG_ITEM)) {
4094                 String name = parser.getAttributeValue(null, ATTR_NAME);
4095                 if (name != null) {
4096                     packageSetting.addEnabledComponent(name.intern(), userId);
4097                 } else {
4098                     PackageManagerService.reportSettingsProblem(Log.WARN,
4099                             "Error in package manager settings: <enabled-components> has"
4100                                     + " no name at " + parser.getPositionDescription());
4101                 }
4102             } else {
4103                 PackageManagerService.reportSettingsProblem(Log.WARN,
4104                         "Unknown element under <enabled-components>: " + parser.getName());
4105             }
4106             XmlUtils.skipCurrentTag(parser);
4107         }
4108     }
4109 
readSharedUserLPw(XmlPullParser parser)4110     private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
4111         String name = null;
4112         String idStr = null;
4113         int pkgFlags = 0;
4114         int pkgPrivateFlags = 0;
4115         SharedUserSetting su = null;
4116         try {
4117             name = parser.getAttributeValue(null, ATTR_NAME);
4118             idStr = parser.getAttributeValue(null, "userId");
4119             int userId = idStr != null ? Integer.parseInt(idStr) : 0;
4120             if ("true".equals(parser.getAttributeValue(null, "system"))) {
4121                 pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
4122             }
4123             if (name == null) {
4124                 PackageManagerService.reportSettingsProblem(Log.WARN,
4125                         "Error in package manager settings: <shared-user> has no name at "
4126                                 + parser.getPositionDescription());
4127             } else if (userId == 0) {
4128                 PackageManagerService.reportSettingsProblem(Log.WARN,
4129                         "Error in package manager settings: shared-user " + name
4130                                 + " has bad userId " + idStr + " at "
4131                                 + parser.getPositionDescription());
4132             } else {
4133                 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
4134                         == null) {
4135                     PackageManagerService
4136                             .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
4137                                     + parser.getPositionDescription());
4138                 }
4139             }
4140         } catch (NumberFormatException e) {
4141             PackageManagerService.reportSettingsProblem(Log.WARN,
4142                     "Error in package manager settings: package " + name + " has bad userId "
4143                             + idStr + " at " + parser.getPositionDescription());
4144         }
4145 
4146         if (su != null) {
4147             int outerDepth = parser.getDepth();
4148             int type;
4149             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4150                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4151                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4152                     continue;
4153                 }
4154 
4155                 String tagName = parser.getName();
4156                 if (tagName.equals("sigs")) {
4157                     su.signatures.readXml(parser, mPastSignatures);
4158                 } else if (tagName.equals("perms")) {
4159                     readInstallPermissionsLPr(parser, su.getPermissionsState());
4160                 } else {
4161                     PackageManagerService.reportSettingsProblem(Log.WARN,
4162                             "Unknown element under <shared-user>: " + parser.getName());
4163                     XmlUtils.skipCurrentTag(parser);
4164                 }
4165             }
4166         } else {
4167             XmlUtils.skipCurrentTag(parser);
4168         }
4169     }
4170 
createNewUserLI(@onNull PackageManagerService service, @NonNull Installer installer, @UserIdInt int userHandle, @Nullable Set<String> userTypeInstallablePackages, String[] disallowedPackages)4171     void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
4172             @UserIdInt int userHandle, @Nullable Set<String> userTypeInstallablePackages,
4173             String[] disallowedPackages) {
4174         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
4175                 Trace.TRACE_TAG_PACKAGE_MANAGER);
4176         t.traceBegin("createNewUser-" + userHandle);
4177         String[] volumeUuids;
4178         String[] names;
4179         int[] appIds;
4180         String[] seinfos;
4181         int[] targetSdkVersions;
4182         int packagesCount;
4183         final boolean skipPackageWhitelist = userTypeInstallablePackages == null;
4184         synchronized (mLock) {
4185             Collection<PackageSetting> packages = mPackages.values();
4186             packagesCount = packages.size();
4187             volumeUuids = new String[packagesCount];
4188             names = new String[packagesCount];
4189             appIds = new int[packagesCount];
4190             seinfos = new String[packagesCount];
4191             targetSdkVersions = new int[packagesCount];
4192             Iterator<PackageSetting> packagesIterator = packages.iterator();
4193             for (int i = 0; i < packagesCount; i++) {
4194                 PackageSetting ps = packagesIterator.next();
4195                 if (ps.pkg == null) {
4196                     continue;
4197                 }
4198                 final boolean shouldMaybeInstall = ps.isSystem() &&
4199                         !ArrayUtils.contains(disallowedPackages, ps.name) &&
4200                         !ps.getPkgState().isHiddenUntilInstalled();
4201                 final boolean shouldReallyInstall = shouldMaybeInstall &&
4202                         (skipPackageWhitelist || userTypeInstallablePackages.contains(ps.name));
4203                 // Only system apps are initially installed.
4204                 ps.setInstalled(shouldReallyInstall, userHandle);
4205                 // If userTypeInstallablePackages is the *only* reason why we're not installing,
4206                 // then uninstallReason is USER_TYPE. If there's a different reason, or if we
4207                 // actually are installing, put UNKNOWN.
4208                 final int uninstallReason = (shouldMaybeInstall && !shouldReallyInstall) ?
4209                         UNINSTALL_REASON_USER_TYPE : UNINSTALL_REASON_UNKNOWN;
4210                 ps.setUninstallReason(uninstallReason, userHandle);
4211                 if (!shouldReallyInstall) {
4212                     writeKernelMappingLPr(ps);
4213                 }
4214                 // Need to create a data directory for all apps under this user. Accumulate all
4215                 // required args and call the installer after mPackages lock has been released
4216                 volumeUuids[i] = ps.volumeUuid;
4217                 names[i] = ps.name;
4218                 appIds[i] = ps.appId;
4219                 seinfos[i] = AndroidPackageUtils.getSeInfo(ps.pkg, ps);
4220                 targetSdkVersions[i] = ps.pkg.getTargetSdkVersion();
4221             }
4222         }
4223         t.traceBegin("createAppData");
4224         final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
4225         try {
4226             installer.createAppDataBatched(volumeUuids, names, userHandle, flags, appIds, seinfos,
4227                     targetSdkVersions);
4228         } catch (InstallerException e) {
4229             Slog.w(TAG, "Failed to prepare app data", e);
4230         }
4231         t.traceEnd(); // createAppData
4232         synchronized (mLock) {
4233             applyDefaultPreferredAppsLPw(userHandle);
4234         }
4235         t.traceEnd(); // createNewUser
4236     }
4237 
removeUserLPw(int userId)4238     void removeUserLPw(int userId) {
4239         Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
4240         for (Entry<String, PackageSetting> entry : entries) {
4241             entry.getValue().removeUser(userId);
4242         }
4243         mPreferredActivities.remove(userId);
4244         File file = getUserPackagesStateFile(userId);
4245         file.delete();
4246         file = getUserPackagesStateBackupFile(userId);
4247         file.delete();
4248         removeCrossProfileIntentFiltersLPw(userId);
4249 
4250         mRuntimePermissionsPersistence.onUserRemovedLPw(userId);
4251 
4252         writePackageListLPr();
4253 
4254         // Inform kernel that the user was removed, so that packages are marked uninstalled
4255         // for sdcardfs
4256         writeKernelRemoveUserLPr(userId);
4257     }
4258 
removeCrossProfileIntentFiltersLPw(int userId)4259     void removeCrossProfileIntentFiltersLPw(int userId) {
4260         synchronized (mCrossProfileIntentResolvers) {
4261             // userId is the source user
4262             if (mCrossProfileIntentResolvers.get(userId) != null) {
4263                 mCrossProfileIntentResolvers.remove(userId);
4264                 writePackageRestrictionsLPr(userId);
4265             }
4266             // userId is the target user
4267             int count = mCrossProfileIntentResolvers.size();
4268             for (int i = 0; i < count; i++) {
4269                 int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
4270                 CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
4271                 boolean needsWriting = false;
4272                 ArraySet<CrossProfileIntentFilter> cpifs =
4273                         new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
4274                 for (CrossProfileIntentFilter cpif : cpifs) {
4275                     if (cpif.getTargetUserId() == userId) {
4276                         needsWriting = true;
4277                         cpir.removeFilter(cpif);
4278                     }
4279                 }
4280                 if (needsWriting) {
4281                     writePackageRestrictionsLPr(sourceUserId);
4282                 }
4283             }
4284         }
4285     }
4286 
4287     // This should be called (at least) whenever an application is removed
setFirstAvailableUid(int uid)4288     private void setFirstAvailableUid(int uid) {
4289         if (uid > mFirstAvailableUid) {
4290             mFirstAvailableUid = uid;
4291         }
4292     }
4293 
4294     /** Returns a new AppID or -1 if we could not find an available AppID to assign */
acquireAndRegisterNewAppIdLPw(SettingBase obj)4295     private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
4296         // Let's be stupidly inefficient for now...
4297         final int size = mAppIds.size();
4298         for (int i = mFirstAvailableUid; i < size; i++) {
4299             if (mAppIds.get(i) == null) {
4300                 mAppIds.set(i, obj);
4301                 return Process.FIRST_APPLICATION_UID + i;
4302             }
4303         }
4304 
4305         // None left?
4306         if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
4307             return -1;
4308         }
4309 
4310         mAppIds.add(obj);
4311         return Process.FIRST_APPLICATION_UID + size;
4312     }
4313 
getVerifierDeviceIdentityLPw()4314     public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
4315         if (mVerifierDeviceIdentity == null) {
4316             mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
4317 
4318             writeLPr();
4319         }
4320 
4321         return mVerifierDeviceIdentity;
4322     }
4323 
4324     /**
4325      * Returns the disabled {@link PackageSetting} for the provided package name if one exists,
4326      * {@code null} otherwise.
4327      */
4328     @Nullable
getDisabledSystemPkgLPr(String name)4329     public PackageSetting getDisabledSystemPkgLPr(String name) {
4330         PackageSetting ps = mDisabledSysPackages.get(name);
4331         return ps;
4332     }
4333 
4334     /**
4335      * Returns the disabled {@link PackageSetting} for the provided enabled {@link PackageSetting}
4336      * if one exists, {@code null} otherwise.
4337      */
4338     @Nullable
getDisabledSystemPkgLPr(PackageSetting enabledPackageSetting)4339     public PackageSetting getDisabledSystemPkgLPr(PackageSetting enabledPackageSetting) {
4340         if (enabledPackageSetting == null) {
4341             return null;
4342         }
4343         return getDisabledSystemPkgLPr(enabledPackageSetting.name);
4344     }
4345 
isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId)4346     boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
4347         final PackageSetting ps = mPackages.get(componentInfo.packageName);
4348         if (ps == null) return false;
4349 
4350         final PackageUserState userState = ps.readUserState(userId);
4351         return userState.isMatch(componentInfo, flags);
4352     }
4353 
4354     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
isEnabledAndMatchLPr(AndroidPackage pkg, ParsedMainComponent component, int flags, int userId)4355     public boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedMainComponent component,
4356             int flags, int userId) {
4357         final PackageSetting ps = mPackages.get(component.getPackageName());
4358         if (ps == null) return false;
4359 
4360         final PackageUserState userState = ps.readUserState(userId);
4361         return userState.isMatch(pkg.isSystem(), pkg.isEnabled(), component, flags);
4362     }
4363 
isOrphaned(String packageName)4364     boolean isOrphaned(String packageName) {
4365         final PackageSetting pkg = mPackages.get(packageName);
4366         if (pkg == null) {
4367             throw new IllegalArgumentException("Unknown package: " + packageName);
4368         }
4369         return pkg.installSource.isOrphaned;
4370     }
4371 
getApplicationEnabledSettingLPr(String packageName, int userId)4372     int getApplicationEnabledSettingLPr(String packageName, int userId)
4373             throws PackageManager.NameNotFoundException {
4374         final PackageSetting pkg = mPackages.get(packageName);
4375         if (pkg == null) {
4376             throw new PackageManager.NameNotFoundException(packageName);
4377         }
4378         return pkg.getEnabled(userId);
4379     }
4380 
getComponentEnabledSettingLPr(ComponentName componentName, int userId)4381     int getComponentEnabledSettingLPr(ComponentName componentName, int userId)
4382             throws PackageManager.NameNotFoundException {
4383         final String packageName = componentName.getPackageName();
4384         final PackageSetting pkg = mPackages.get(packageName);
4385         if (pkg == null) {
4386             throw new PackageManager.NameNotFoundException(componentName.getPackageName());
4387         }
4388         final String classNameStr = componentName.getClassName();
4389         return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
4390     }
4391 
wasPackageEverLaunchedLPr(String packageName, int userId)4392     boolean wasPackageEverLaunchedLPr(String packageName, int userId) {
4393         final PackageSetting pkgSetting = mPackages.get(packageName);
4394         if (pkgSetting == null) {
4395             throw new IllegalArgumentException("Unknown package: " + packageName);
4396         }
4397         return !pkgSetting.getNotLaunched(userId);
4398     }
4399 
setPackageStoppedStateLPw(PackageManagerService pm, String packageName, boolean stopped, boolean allowedByPermission, int uid, int userId)4400     boolean setPackageStoppedStateLPw(PackageManagerService pm, String packageName,
4401             boolean stopped, boolean allowedByPermission, int uid, int userId) {
4402         int appId = UserHandle.getAppId(uid);
4403         final PackageSetting pkgSetting = mPackages.get(packageName);
4404         if (pkgSetting == null) {
4405             throw new IllegalArgumentException("Unknown package: " + packageName);
4406         }
4407         if (!allowedByPermission && (appId != pkgSetting.appId)) {
4408             throw new SecurityException(
4409                     "Permission Denial: attempt to change stopped state from pid="
4410                     + Binder.getCallingPid()
4411                     + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
4412         }
4413         if (DEBUG_STOPPED) {
4414             if (stopped) {
4415                 RuntimeException e = new RuntimeException("here");
4416                 e.fillInStackTrace();
4417                 Slog.i(TAG, "Stopping package " + packageName, e);
4418             }
4419         }
4420         if (pkgSetting.getStopped(userId) != stopped) {
4421             pkgSetting.setStopped(stopped, userId);
4422             // pkgSetting.pkg.mSetStopped = stopped;
4423             if (pkgSetting.getNotLaunched(userId)) {
4424                 if (pkgSetting.installSource.installerPackageName != null) {
4425                     pm.notifyFirstLaunch(pkgSetting.name,
4426                             pkgSetting.installSource.installerPackageName, userId);
4427                 }
4428                 pkgSetting.setNotLaunched(false, userId);
4429             }
4430             return true;
4431         }
4432         return false;
4433     }
4434 
setHarmfulAppWarningLPw(String packageName, CharSequence warning, int userId)4435     void setHarmfulAppWarningLPw(String packageName, CharSequence warning, int userId) {
4436         final PackageSetting pkgSetting = mPackages.get(packageName);
4437         if (pkgSetting == null) {
4438             throw new IllegalArgumentException("Unknown package: " + packageName);
4439         }
4440         pkgSetting.setHarmfulAppWarning(userId, warning == null ? null : warning.toString());
4441     }
4442 
getHarmfulAppWarningLPr(String packageName, int userId)4443     String getHarmfulAppWarningLPr(String packageName, int userId) {
4444         final PackageSetting pkgSetting = mPackages.get(packageName);
4445         if (pkgSetting == null) {
4446             throw new IllegalArgumentException("Unknown package: " + packageName);
4447         }
4448         return pkgSetting.getHarmfulAppWarning(userId);
4449     }
4450 
4451     /**
4452      * Return all users on the device, including partial or dying users.
4453      * @param userManager UserManagerService instance
4454      * @return the list of users
4455      */
getAllUsers(UserManagerService userManager)4456     private static List<UserInfo> getAllUsers(UserManagerService userManager) {
4457         return getUsers(userManager, false);
4458     }
4459 
4460     /**
4461      * Return the list of users on the device. Clear the calling identity before calling into
4462      * UserManagerService.
4463      * @param userManager UserManagerService instance
4464      * @param excludeDying Indicates whether to exclude any users marked for deletion.
4465      * @return the list of users
4466      */
getUsers(UserManagerService userManager, boolean excludeDying)4467     private static List<UserInfo> getUsers(UserManagerService userManager, boolean excludeDying) {
4468         long id = Binder.clearCallingIdentity();
4469         try {
4470             return userManager.getUsers(excludeDying);
4471         } catch (NullPointerException npe) {
4472             // packagemanager not yet initialized
4473         } finally {
4474             Binder.restoreCallingIdentity(id);
4475         }
4476         return null;
4477     }
4478 
4479     /**
4480      * Return all {@link PackageSetting} that are actively installed on the
4481      * given {@link VolumeInfo#fsUuid}.
4482      */
getVolumePackagesLPr(String volumeUuid)4483     List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
4484         ArrayList<PackageSetting> res = new ArrayList<>();
4485         for (int i = 0; i < mPackages.size(); i++) {
4486             final PackageSetting setting = mPackages.valueAt(i);
4487             if (Objects.equals(volumeUuid, setting.volumeUuid)) {
4488                 res.add(setting);
4489             }
4490         }
4491         return res;
4492     }
4493 
printFlags(PrintWriter pw, int val, Object[] spec)4494     static void printFlags(PrintWriter pw, int val, Object[] spec) {
4495         pw.print("[ ");
4496         for (int i=0; i<spec.length; i+=2) {
4497             int mask = (Integer)spec[i];
4498             if ((val & mask) != 0) {
4499                 pw.print(spec[i+1]);
4500                 pw.print(" ");
4501             }
4502         }
4503         pw.print("]");
4504     }
4505 
4506     static final Object[] FLAG_DUMP_SPEC = new Object[] {
4507         ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4508         ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4509         ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4510         ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4511         ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4512         ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4513         ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4514         ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4515         ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4516         ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4517         ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4518         ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4519         ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4520         ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4521         ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4522     };
4523 
4524     private static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4525             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE",
4526             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION",
4527             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE",
4528             ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, "ALLOW_AUDIO_PLAYBACK_CAPTURE",
4529             ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE, "PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE",
4530             ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
4531             ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4532             ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
4533             ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
4534             ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
4535             ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN",
4536             ApplicationInfo.PRIVATE_FLAG_INSTANT, "EPHEMERAL",
4537             ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, "ISOLATED_SPLIT_LOADING",
4538             ApplicationInfo.PRIVATE_FLAG_OEM, "OEM",
4539             ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
4540             ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4541             ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
4542             ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
4543             ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
4544             ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
4545             ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT, "SYSTEM_EXT",
4546             ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
4547             ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
4548             ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING, "PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING",
4549     };
4550 
dumpVersionLPr(IndentingPrintWriter pw)4551     void dumpVersionLPr(IndentingPrintWriter pw) {
4552         pw.increaseIndent();
4553         for (int i= 0; i < mVersion.size(); i++) {
4554             final String volumeUuid = mVersion.keyAt(i);
4555             final VersionInfo ver = mVersion.valueAt(i);
4556             if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4557                 pw.println("Internal:");
4558             } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4559                 pw.println("External:");
4560             } else {
4561                 pw.println("UUID " + volumeUuid + ":");
4562             }
4563             pw.increaseIndent();
4564             pw.printPair("sdkVersion", ver.sdkVersion);
4565             pw.printPair("databaseVersion", ver.databaseVersion);
4566             pw.println();
4567             pw.printPair("fingerprint", ver.fingerprint);
4568             pw.println();
4569             pw.decreaseIndent();
4570         }
4571         pw.decreaseIndent();
4572     }
4573 
dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents)4574     void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4575             ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4576             Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) {
4577         AndroidPackage pkg = ps.pkg;
4578         if (checkinTag != null) {
4579             pw.print(checkinTag);
4580             pw.print(",");
4581             pw.print(ps.realName != null ? ps.realName : ps.name);
4582             pw.print(",");
4583             pw.print(ps.appId);
4584             pw.print(",");
4585             pw.print(ps.versionCode);
4586             pw.print(",");
4587             pw.print(ps.firstInstallTime);
4588             pw.print(",");
4589             pw.print(ps.lastUpdateTime);
4590             pw.print(",");
4591             pw.print(ps.installSource.installerPackageName != null
4592                     ? ps.installSource.installerPackageName : "?");
4593             pw.println();
4594             if (pkg != null) {
4595                 pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4596                 pw.print("base,");
4597                 pw.println(pkg.getBaseRevisionCode());
4598                 if (pkg.getSplitNames() != null) {
4599                     int[] splitRevisionCodes = pkg.getSplitRevisionCodes();
4600                     for (int i = 0; i < pkg.getSplitNames().length; i++) {
4601                         pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4602                         pw.print(pkg.getSplitNames()[i]); pw.print(",");
4603                         pw.println(splitRevisionCodes[i]);
4604                     }
4605                 }
4606             }
4607             for (UserInfo user : users) {
4608                 pw.print(checkinTag);
4609                 pw.print("-");
4610                 pw.print("usr");
4611                 pw.print(",");
4612                 pw.print(user.id);
4613                 pw.print(",");
4614                 pw.print(ps.getInstalled(user.id) ? "I" : "i");
4615                 pw.print(ps.getHidden(user.id) ? "B" : "b");
4616                 pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4617                 pw.print(ps.getStopped(user.id) ? "S" : "s");
4618                 pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4619                 pw.print(ps.getInstantApp(user.id) ? "IA" : "ia");
4620                 pw.print(ps.getVirtulalPreload(user.id) ? "VPI" : "vpi");
4621                 String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4622                 pw.print(harmfulAppWarning != null ? "HA" : "ha");
4623                 pw.print(",");
4624                 pw.print(ps.getEnabled(user.id));
4625                 String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4626                 pw.print(",");
4627                 pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4628                 pw.print(",");
4629                 pw.println();
4630             }
4631             return;
4632         }
4633 
4634         pw.print(prefix); pw.print("Package [");
4635             pw.print(ps.realName != null ? ps.realName : ps.name);
4636             pw.print("] (");
4637             pw.print(Integer.toHexString(System.identityHashCode(ps)));
4638             pw.println("):");
4639 
4640         if (ps.realName != null) {
4641             pw.print(prefix); pw.print("  compat name=");
4642             pw.println(ps.name);
4643         }
4644 
4645         pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4646 
4647         if (ps.sharedUser != null) {
4648             pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4649         }
4650         pw.print(prefix); pw.print("  pkg="); pw.println(pkg);
4651         pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4652         if (permissionNames == null) {
4653             pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4654             pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4655             pw.println(ps.legacyNativeLibraryPathString);
4656             pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4657             pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4658         }
4659         pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4660         if (pkg != null) {
4661             pw.print(" minSdk="); pw.print(pkg.getMinSdkVersion());
4662             pw.print(" targetSdk="); pw.print(pkg.getTargetSdkVersion());
4663         }
4664         pw.println();
4665         if (pkg != null) {
4666             pw.print(prefix); pw.print("  versionName="); pw.println(pkg.getVersionName());
4667             pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, pkg); pw.println();
4668             final int apkSigningVersion = pkg.getSigningDetails().signatureSchemeVersion;
4669             pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
4670             // TODO(b/135203078): Is there anything to print here with AppInfo removed?
4671             pw.print(prefix); pw.print("  applicationInfo=");
4672             pw.println(pkg.toAppInfoToString());
4673             pw.print(prefix); pw.print("  flags=");
4674             printFlags(pw, PackageInfoUtils.appInfoFlags(pkg, ps), FLAG_DUMP_SPEC); pw.println();
4675             int privateFlags = PackageInfoUtils.appInfoPrivateFlags(pkg, ps);
4676             if (privateFlags != 0) {
4677                 pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4678                         privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4679             }
4680             if (pkg.hasPreserveLegacyExternalStorage()) {
4681                 pw.print(prefix); pw.print("  hasPreserveLegacyExternalStorage=true");
4682                 pw.println();
4683             }
4684             pw.print(prefix); pw.print("  forceQueryable="); pw.print(ps.pkg.isForceQueryable());
4685             if (ps.forceQueryableOverride) {
4686                 pw.print(" (override=true)");
4687             }
4688             pw.println();
4689             if (ps.pkg.getQueriesPackages().isEmpty()) {
4690                 pw.append(prefix).append("  queriesPackages=").println(ps.pkg.getQueriesPackages());
4691             }
4692             if (!ps.pkg.getQueriesIntents().isEmpty()) {
4693                 pw.append(prefix).append("  queriesIntents=").println(ps.pkg.getQueriesIntents());
4694             }
4695             File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
4696             pw.print(prefix); pw.print("  dataDir="); pw.println(dataDir.getAbsolutePath());
4697             pw.print(prefix); pw.print("  supportsScreens=[");
4698             boolean first = true;
4699             if (pkg.isSupportsSmallScreens()) {
4700                 if (!first)
4701                     pw.print(", ");
4702                 first = false;
4703                 pw.print("small");
4704             }
4705             if (pkg.isSupportsNormalScreens()) {
4706                 if (!first)
4707                     pw.print(", ");
4708                 first = false;
4709                 pw.print("medium");
4710             }
4711             if (pkg.isSupportsLargeScreens()) {
4712                 if (!first)
4713                     pw.print(", ");
4714                 first = false;
4715                 pw.print("large");
4716             }
4717             if (pkg.isSupportsExtraLargeScreens()) {
4718                 if (!first)
4719                     pw.print(", ");
4720                 first = false;
4721                 pw.print("xlarge");
4722             }
4723             if (pkg.isResizeable()) {
4724                 if (!first)
4725                     pw.print(", ");
4726                 first = false;
4727                 pw.print("resizeable");
4728             }
4729             if (pkg.isAnyDensity()) {
4730                 if (!first)
4731                     pw.print(", ");
4732                 first = false;
4733                 pw.print("anyDensity");
4734             }
4735             pw.println("]");
4736             final List<String> libraryNames = pkg.getLibraryNames();
4737             if (libraryNames != null && libraryNames.size() > 0) {
4738                 pw.print(prefix); pw.println("  dynamic libraries:");
4739                 for (int i = 0; i< libraryNames.size(); i++) {
4740                     pw.print(prefix); pw.print("    ");
4741                             pw.println(libraryNames.get(i));
4742                 }
4743             }
4744             if (pkg.getStaticSharedLibName() != null) {
4745                 pw.print(prefix); pw.println("  static library:");
4746                 pw.print(prefix); pw.print("    ");
4747                 pw.print("name:"); pw.print(pkg.getStaticSharedLibName());
4748                 pw.print(" version:"); pw.println(pkg.getStaticSharedLibVersion());
4749             }
4750 
4751             List<String> usesLibraries = pkg.getUsesLibraries();
4752             if (usesLibraries.size() > 0) {
4753                 pw.print(prefix); pw.println("  usesLibraries:");
4754                 for (int i=0; i< usesLibraries.size(); i++) {
4755                     pw.print(prefix); pw.print("    "); pw.println(usesLibraries.get(i));
4756                 }
4757             }
4758 
4759             List<String> usesStaticLibraries = pkg.getUsesStaticLibraries();
4760             long[] usesStaticLibrariesVersions = pkg.getUsesStaticLibrariesVersions();
4761             if (usesStaticLibraries.size() > 0) {
4762                 pw.print(prefix); pw.println("  usesStaticLibraries:");
4763                 for (int i=0; i< usesStaticLibraries.size(); i++) {
4764                     pw.print(prefix); pw.print("    ");
4765                     pw.print(usesStaticLibraries.get(i)); pw.print(" version:");
4766                             pw.println(usesStaticLibrariesVersions[i]);
4767                 }
4768             }
4769 
4770             List<String> usesOptionalLibraries = pkg.getUsesOptionalLibraries();
4771             if (usesOptionalLibraries.size() > 0) {
4772                 pw.print(prefix); pw.println("  usesOptionalLibraries:");
4773                 for (int i=0; i< usesOptionalLibraries.size(); i++) {
4774                     pw.print(prefix); pw.print("    ");
4775                     pw.println(usesOptionalLibraries.get(i));
4776                 }
4777             }
4778 
4779             List<String> usesLibraryFiles = ps.getPkgState().getUsesLibraryFiles();
4780             if (usesLibraryFiles.size() > 0) {
4781                 pw.print(prefix); pw.println("  usesLibraryFiles:");
4782                 for (int i=0; i< usesLibraryFiles.size(); i++) {
4783                     pw.print(prefix); pw.print("    "); pw.println(usesLibraryFiles.get(i));
4784                 }
4785             }
4786             final Map<String, ParsedProcess> procs = pkg.getProcesses();
4787             if (!procs.isEmpty()) {
4788                 pw.print(prefix); pw.println("  processes:");
4789                 for (ParsedProcess proc : procs.values()) {
4790                     pw.print(prefix); pw.print("    "); pw.println(proc.getName());
4791                     if (proc.getDeniedPermissions() != null) {
4792                         for (String deniedPermission : proc.getDeniedPermissions()) {
4793                             pw.print(prefix); pw.print("      deny: ");
4794                             pw.println(deniedPermission);
4795                         }
4796                     }
4797                 }
4798             }
4799         }
4800         pw.print(prefix); pw.print("  timeStamp=");
4801             date.setTime(ps.timeStamp);
4802             pw.println(sdf.format(date));
4803         pw.print(prefix); pw.print("  firstInstallTime=");
4804             date.setTime(ps.firstInstallTime);
4805             pw.println(sdf.format(date));
4806         pw.print(prefix); pw.print("  lastUpdateTime=");
4807             date.setTime(ps.lastUpdateTime);
4808             pw.println(sdf.format(date));
4809         if (ps.installSource.installerPackageName != null) {
4810             pw.print(prefix); pw.print("  installerPackageName=");
4811             pw.println(ps.installSource.installerPackageName);
4812         }
4813         if (ps.volumeUuid != null) {
4814             pw.print(prefix); pw.print("  volumeUuid=");
4815                     pw.println(ps.volumeUuid);
4816         }
4817         pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4818         pw.print(prefix); pw.print("  installPermissionsFixed=");
4819                 pw.print(ps.installPermissionsFixed);
4820                 pw.println();
4821         pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4822                 pw.println();
4823 
4824         if (pkg != null && pkg.getOverlayTarget() != null) {
4825             pw.print(prefix); pw.print("  overlayTarget="); pw.println(pkg.getOverlayTarget());
4826             pw.print(prefix); pw.print("  overlayCategory="); pw.println(pkg.getOverlayCategory());
4827         }
4828 
4829         if (pkg != null && !pkg.getPermissions().isEmpty()) {
4830             final List<ParsedPermission> perms = pkg.getPermissions();
4831             pw.print(prefix); pw.println("  declared permissions:");
4832             for (int i=0; i<perms.size(); i++) {
4833                 ParsedPermission perm = perms.get(i);
4834                 if (permissionNames != null
4835                         && !permissionNames.contains(perm.getName())) {
4836                     continue;
4837                 }
4838                 pw.print(prefix); pw.print("    "); pw.print(perm.getName());
4839                 pw.print(": prot=");
4840                 pw.print(PermissionInfo.protectionToString(perm.getProtectionLevel()));
4841                 if ((perm.getFlags() &PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4842                     pw.print(", COSTS_MONEY");
4843                 }
4844                 if ((perm.getFlags() &PermissionInfo.FLAG_REMOVED) != 0) {
4845                     pw.print(", HIDDEN");
4846                 }
4847                 if ((perm.getFlags() &PermissionInfo.FLAG_INSTALLED) != 0) {
4848                     pw.print(", INSTALLED");
4849                 }
4850                 pw.println();
4851             }
4852         }
4853 
4854         if ((permissionNames != null || dumpAll) && pkg != null
4855                 && pkg.getRequestedPermissions() != null
4856                 && pkg.getRequestedPermissions().size() > 0) {
4857             final List<String> perms = pkg.getRequestedPermissions();
4858             pw.print(prefix); pw.println("  requested permissions:");
4859             for (int i=0; i<perms.size(); i++) {
4860                 String perm = perms.get(i);
4861                 if (permissionNames != null
4862                         && !permissionNames.contains(perm)) {
4863                     continue;
4864                 }
4865                 pw.print(prefix); pw.print("    "); pw.print(perm);
4866                 final BasePermission bp = mPermissions.getPermission(perm);
4867                 if (bp != null && bp.isHardOrSoftRestricted()) {
4868                     pw.println(": restricted=true");
4869                 } else {
4870                     pw.println();
4871                 }
4872             }
4873         }
4874 
4875         if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4876             PermissionsState permissionsState = ps.getPermissionsState();
4877             dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4878         }
4879 
4880         if (dumpAllComponents) {
4881             dumpComponents(pw, prefix + "  ", ps);
4882         }
4883 
4884         for (UserInfo user : users) {
4885             pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4886             pw.print("ceDataInode=");
4887             pw.print(ps.getCeDataInode(user.id));
4888             pw.print(" installed=");
4889             pw.print(ps.getInstalled(user.id));
4890             pw.print(" hidden=");
4891             pw.print(ps.getHidden(user.id));
4892             pw.print(" suspended=");
4893             pw.print(ps.getSuspended(user.id));
4894             pw.print(" distractionFlags=");
4895             pw.print(ps.getDistractionFlags(user.id));
4896             pw.print(" stopped=");
4897             pw.print(ps.getStopped(user.id));
4898             pw.print(" notLaunched=");
4899             pw.print(ps.getNotLaunched(user.id));
4900             pw.print(" enabled=");
4901             pw.print(ps.getEnabled(user.id));
4902             pw.print(" instant=");
4903             pw.print(ps.getInstantApp(user.id));
4904             pw.print(" virtual=");
4905             pw.println(ps.getVirtulalPreload(user.id));
4906 
4907             if (ps.getSuspended(user.id)) {
4908                 pw.print(prefix);
4909                 pw.println("  Suspend params:");
4910                 final PackageUserState pus = ps.readUserState(user.id);
4911                 for (int i = 0; i < pus.suspendParams.size(); i++) {
4912                     pw.print(prefix);
4913                     pw.print("    suspendingPackage=");
4914                     pw.print(pus.suspendParams.keyAt(i));
4915                     final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
4916                     if (params != null) {
4917                         pw.print(" dialogInfo=");
4918                         pw.print(params.dialogInfo);
4919                     }
4920                     pw.println();
4921                 }
4922             }
4923 
4924             String[] overlayPaths = ps.getOverlayPaths(user.id);
4925             if (overlayPaths != null && overlayPaths.length > 0) {
4926                 pw.print(prefix); pw.println("  overlay paths:");
4927                 for (String path : overlayPaths) {
4928                     pw.print(prefix); pw.print("    "); pw.println(path);
4929                 }
4930             }
4931 
4932             Map<String, String[]> sharedLibraryOverlayPaths =
4933                     ps.getOverlayPathsForLibrary(user.id);
4934             if (sharedLibraryOverlayPaths != null) {
4935                 for (Map.Entry<String, String[]> libOverlayPaths :
4936                         sharedLibraryOverlayPaths.entrySet()) {
4937                     if (libOverlayPaths.getValue() == null) {
4938                         continue;
4939                     }
4940                     pw.print(prefix); pw.print("  ");
4941                     pw.print(libOverlayPaths.getKey()); pw.println(" overlay paths:");
4942                     for (String path : libOverlayPaths.getValue()) {
4943                         pw.print(prefix); pw.print("    "); pw.println(path);
4944                     }
4945                 }
4946             }
4947 
4948             String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4949             if (lastDisabledAppCaller != null) {
4950                 pw.print(prefix); pw.print("    lastDisabledCaller: ");
4951                         pw.println(lastDisabledAppCaller);
4952             }
4953 
4954             if (ps.sharedUser == null) {
4955                 PermissionsState permissionsState = ps.getPermissionsState();
4956                 dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4957                 dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4958                         .getRuntimePermissionStates(user.id), dumpAll);
4959             }
4960 
4961             String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4962             if (harmfulAppWarning != null) {
4963                 pw.print(prefix); pw.print("      harmfulAppWarning: ");
4964                 pw.println(harmfulAppWarning);
4965             }
4966 
4967             if (permissionNames == null) {
4968                 ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4969                 if (cmp != null && cmp.size() > 0) {
4970                     pw.print(prefix); pw.println("    disabledComponents:");
4971                     for (String s : cmp) {
4972                         pw.print(prefix); pw.print("      "); pw.println(s);
4973                     }
4974                 }
4975                 cmp = ps.getEnabledComponents(user.id);
4976                 if (cmp != null && cmp.size() > 0) {
4977                     pw.print(prefix); pw.println("    enabledComponents:");
4978                     for (String s : cmp) {
4979                         pw.print(prefix); pw.print("      "); pw.println(s);
4980                     }
4981                 }
4982             }
4983         }
4984     }
4985 
dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, DumpState dumpState, boolean checkin)4986     void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4987             DumpState dumpState, boolean checkin) {
4988         final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4989         final Date date = new Date();
4990         boolean printedSomething = false;
4991         final boolean dumpAllComponents =
4992                 dumpState.isOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
4993         List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4994         for (final PackageSetting ps : mPackages.values()) {
4995             if (packageName != null && !packageName.equals(ps.realName)
4996                     && !packageName.equals(ps.name)) {
4997                 continue;
4998             }
4999             if (permissionNames != null
5000                     && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
5001                 continue;
5002             }
5003 
5004             if (!checkin && packageName != null) {
5005                 dumpState.setSharedUser(ps.sharedUser);
5006             }
5007 
5008             if (!checkin && !printedSomething) {
5009                 if (dumpState.onTitlePrinted())
5010                     pw.println();
5011                 pw.println("Packages:");
5012                 printedSomething = true;
5013             }
5014             dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
5015                     packageName != null, dumpAllComponents);
5016         }
5017 
5018         printedSomething = false;
5019         if (mRenamedPackages.size() > 0 && permissionNames == null) {
5020             for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
5021                 if (packageName != null && !packageName.equals(e.getKey())
5022                         && !packageName.equals(e.getValue())) {
5023                     continue;
5024                 }
5025                 if (!checkin) {
5026                     if (!printedSomething) {
5027                         if (dumpState.onTitlePrinted())
5028                             pw.println();
5029                         pw.println("Renamed packages:");
5030                         printedSomething = true;
5031                     }
5032                     pw.print("  ");
5033                 } else {
5034                     pw.print("ren,");
5035                 }
5036                 pw.print(e.getKey());
5037                 pw.print(checkin ? " -> " : ",");
5038                 pw.println(e.getValue());
5039             }
5040         }
5041 
5042         printedSomething = false;
5043         if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
5044             for (final PackageSetting ps : mDisabledSysPackages.values()) {
5045                 if (packageName != null && !packageName.equals(ps.realName)
5046                         && !packageName.equals(ps.name)) {
5047                     continue;
5048                 }
5049                 if (!checkin && !printedSomething) {
5050                     if (dumpState.onTitlePrinted())
5051                         pw.println();
5052                     pw.println("Hidden system packages:");
5053                     printedSomething = true;
5054                 }
5055                 dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
5056                         users, packageName != null, dumpAllComponents);
5057             }
5058         }
5059     }
5060 
dumpPackagesProto(ProtoOutputStream proto)5061     void dumpPackagesProto(ProtoOutputStream proto) {
5062         List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
5063 
5064         final int count = mPackages.size();
5065         for (int i = 0; i < count; i++) {
5066             final PackageSetting ps = mPackages.valueAt(i);
5067             ps.dumpDebug(proto, PackageServiceDumpProto.PACKAGES, users);
5068         }
5069     }
5070 
dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, DumpState dumpState)5071     void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
5072             DumpState dumpState) {
5073         mPermissions.dumpPermissions(pw, packageName, permissionNames,
5074                 (mReadExternalStorageEnforced == Boolean.TRUE), dumpState);
5075     }
5076 
dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, DumpState dumpState, boolean checkin)5077     void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
5078             DumpState dumpState, boolean checkin) {
5079         boolean printedSomething = false;
5080         for (SharedUserSetting su : mSharedUsers.values()) {
5081             if (packageName != null && su != dumpState.getSharedUser()) {
5082                 continue;
5083             }
5084             if (permissionNames != null
5085                     && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
5086                 continue;
5087             }
5088             if (!checkin) {
5089                 if (!printedSomething) {
5090                     if (dumpState.onTitlePrinted())
5091                         pw.println();
5092                     pw.println("Shared users:");
5093                     printedSomething = true;
5094                 }
5095 
5096                 pw.print("  SharedUser [");
5097                 pw.print(su.name);
5098                 pw.print("] (");
5099                 pw.print(Integer.toHexString(System.identityHashCode(su)));
5100                 pw.println("):");
5101 
5102                 String prefix = "    ";
5103                 pw.print(prefix); pw.print("userId="); pw.println(su.userId);
5104 
5105                 pw.print(prefix); pw.println("Packages");
5106                 final int numPackages = su.packages.size();
5107                 for (int i = 0; i < numPackages; i++) {
5108                     final PackageSetting ps = su.packages.valueAt(i);
5109                     if (ps != null) {
5110                         pw.print(prefix + "  "); pw.println(ps.toString());
5111                     } else {
5112                         pw.print(prefix + "  "); pw.println("NULL?!");
5113                     }
5114                 }
5115 
5116                 if (dumpState.isOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS)) {
5117                     continue;
5118                 }
5119 
5120                 final PermissionsState permissionsState = su.getPermissionsState();
5121                 dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
5122 
5123                 for (int userId : UserManagerService.getInstance().getUserIds()) {
5124                     final int[] gids = permissionsState.computeGids(userId);
5125                     final List<PermissionState> permissions =
5126                             permissionsState.getRuntimePermissionStates(userId);
5127                     if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
5128                         pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
5129                         dumpGidsLPr(pw, prefix + "  ", gids);
5130                         dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames,
5131                                 permissions, packageName != null);
5132                     }
5133                 }
5134             } else {
5135                 pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
5136             }
5137         }
5138     }
5139 
dumpSharedUsersProto(ProtoOutputStream proto)5140     void dumpSharedUsersProto(ProtoOutputStream proto) {
5141         final int count = mSharedUsers.size();
5142         for (int i = 0; i < count; i++) {
5143             mSharedUsers.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.SHARED_USERS);
5144         }
5145     }
5146 
dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState)5147     void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
5148         pw.println("Settings parse messages:");
5149         pw.print(mReadMessages.toString());
5150     }
5151 
dumpSplitNames(PrintWriter pw, AndroidPackage pkg)5152     private static void dumpSplitNames(PrintWriter pw, AndroidPackage pkg) {
5153         if (pkg == null) {
5154             pw.print("unknown");
5155         } else {
5156             // [base:10, config.mdpi, config.xhdpi:12]
5157             pw.print("[");
5158             pw.print("base");
5159             if (pkg.getBaseRevisionCode() != 0) {
5160                 pw.print(":"); pw.print(pkg.getBaseRevisionCode());
5161             }
5162             String[] splitNames = pkg.getSplitNames();
5163             int[] splitRevisionCodes = pkg.getSplitRevisionCodes();
5164             if (splitNames != null) {
5165                 for (int i = 0; i < splitNames.length; i++) {
5166                     pw.print(", ");
5167                     pw.print(splitNames[i]);
5168                     if (splitRevisionCodes[i] != 0) {
5169                         pw.print(":"); pw.print(splitRevisionCodes[i]);
5170                     }
5171                 }
5172             }
5173             pw.print("]");
5174         }
5175     }
5176 
dumpGidsLPr(PrintWriter pw, String prefix, int[] gids)5177     void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
5178         if (!ArrayUtils.isEmpty(gids)) {
5179             pw.print(prefix);
5180             pw.print("gids="); pw.println(
5181                     PackageManagerService.arrayToString(gids));
5182         }
5183     }
5184 
dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, List<PermissionState> permissionStates, boolean dumpAll)5185     void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
5186             List<PermissionState> permissionStates, boolean dumpAll) {
5187         if (!permissionStates.isEmpty() || dumpAll) {
5188             pw.print(prefix); pw.println("runtime permissions:");
5189             for (PermissionState permissionState : permissionStates) {
5190                 if (permissionNames != null
5191                         && !permissionNames.contains(permissionState.getName())) {
5192                     continue;
5193                 }
5194                 pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5195                 pw.print(": granted="); pw.print(permissionState.isGranted());
5196                     pw.println(permissionFlagsToString(", flags=",
5197                             permissionState.getFlags()));
5198             }
5199         }
5200     }
5201 
permissionFlagsToString(String prefix, int flags)5202     private static String permissionFlagsToString(String prefix, int flags) {
5203         StringBuilder flagsString = null;
5204         while (flags != 0) {
5205             if (flagsString == null) {
5206                 flagsString = new StringBuilder();
5207                 flagsString.append(prefix);
5208                 flagsString.append("[ ");
5209             }
5210             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5211             flags &= ~flag;
5212             flagsString.append(PackageManager.permissionFlagToString(flag));
5213             if (flags != 0) {
5214                 flagsString.append('|');
5215             }
5216 
5217         }
5218         if (flagsString != null) {
5219             flagsString.append(']');
5220             return flagsString.toString();
5221         } else {
5222             return "";
5223         }
5224     }
5225 
dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, PermissionsState permissionsState)5226     void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
5227             PermissionsState permissionsState) {
5228         List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
5229         if (!permissionStates.isEmpty()) {
5230             pw.print(prefix); pw.println("install permissions:");
5231             for (PermissionState permissionState : permissionStates) {
5232                 if (permissionNames != null
5233                         && !permissionNames.contains(permissionState.getName())) {
5234                     continue;
5235                 }
5236                 pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5237                     pw.print(": granted="); pw.print(permissionState.isGranted());
5238                     pw.println(permissionFlagsToString(", flags=",
5239                         permissionState.getFlags()));
5240             }
5241         }
5242     }
5243 
dumpComponents(PrintWriter pw, String prefix, PackageSetting ps)5244     void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps) {
5245         // TODO(b/135203078): ParsedComponent toString methods for dumping
5246         dumpComponents(pw, prefix, "activities:", ps.pkg.getActivities());
5247         dumpComponents(pw, prefix, "services:", ps.pkg.getServices());
5248         dumpComponents(pw, prefix, "receivers:", ps.pkg.getReceivers());
5249         dumpComponents(pw, prefix, "providers:", ps.pkg.getProviders());
5250         dumpComponents(pw, prefix, "instrumentations:", ps.pkg.getInstrumentations());
5251     }
5252 
dumpComponents(PrintWriter pw, String prefix, String label, List<? extends ParsedComponent> list)5253     void dumpComponents(PrintWriter pw, String prefix, String label,
5254             List<? extends ParsedComponent> list) {
5255         final int size = CollectionUtils.size(list);
5256         if (size == 0) {
5257             return;
5258         }
5259         pw.print(prefix);pw.println(label);
5260         for (int i = 0; i < size; i++) {
5261             final ParsedComponent component = list.get(i);
5262             pw.print(prefix);pw.print("  ");
5263             pw.println(component.getComponentName().flattenToShortString());
5264         }
5265     }
5266 
writeRuntimePermissionsForUserLPr(int userId, boolean sync)5267     public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
5268         if (sync) {
5269             mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
5270         } else {
5271             mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
5272         }
5273     }
5274 
5275     private static class KeySetToValueMap<K, V> implements Map<K, V> {
5276         @NonNull
5277         private final Set<K> mKeySet;
5278         private final V mValue;
5279 
KeySetToValueMap(@onNull Set<K> keySet, V value)5280         KeySetToValueMap(@NonNull Set<K> keySet, V value) {
5281             mKeySet = keySet;
5282             mValue = value;
5283         }
5284 
5285         @Override
size()5286         public int size() {
5287             return mKeySet.size();
5288         }
5289 
5290         @Override
isEmpty()5291         public boolean isEmpty() {
5292             return mKeySet.isEmpty();
5293         }
5294 
5295         @Override
containsKey(Object key)5296         public boolean containsKey(Object key) {
5297             return mKeySet.contains(key);
5298         }
5299 
5300         @Override
containsValue(Object value)5301         public boolean containsValue(Object value) {
5302             return mValue == value;
5303         }
5304 
5305         @Override
get(Object key)5306         public V get(Object key) {
5307             return mValue;
5308         }
5309 
5310         @Override
put(K key, V value)5311         public V put(K key, V value) {
5312             throw new UnsupportedOperationException();
5313         }
5314 
5315         @Override
remove(Object key)5316         public V remove(Object key) {
5317             throw new UnsupportedOperationException();
5318         }
5319 
5320         @Override
putAll(Map<? extends K, ? extends V> m)5321         public void putAll(Map<? extends K, ? extends V> m) {
5322             throw new UnsupportedOperationException();
5323         }
5324 
5325         @Override
clear()5326         public void clear() {
5327             throw new UnsupportedOperationException();
5328         }
5329 
5330         @Override
keySet()5331         public Set<K> keySet() {
5332             return mKeySet;
5333         }
5334 
5335         @Override
values()5336         public Collection<V> values() {
5337             throw new UnsupportedOperationException();
5338         }
5339 
5340         @Override
entrySet()5341         public Set<Entry<K, V>> entrySet() {
5342             throw new UnsupportedOperationException();
5343         }
5344     }
5345 
5346     private final class RuntimePermissionPersistence {
5347         private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
5348         private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
5349 
5350         private static final int UPGRADE_VERSION = -1;
5351         private static final int INITIAL_VERSION = 0;
5352 
5353         private String mExtendedFingerprint;
5354 
5355         private final RuntimePermissionsPersistence mPersistence =
5356                 RuntimePermissionsPersistence.createInstance();
5357 
5358         private final Handler mHandler = new MyHandler();
5359 
5360         private final Object mPersistenceLock;
5361 
5362         @GuardedBy("mLock")
5363         private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
5364 
5365         @GuardedBy("mLock")
5366         // The mapping keys are user ids.
5367         private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
5368 
5369         @GuardedBy("mLock")
5370         // The mapping keys are user ids.
5371         private final SparseIntArray mVersions = new SparseIntArray();
5372 
5373         @GuardedBy("mLock")
5374         // The mapping keys are user ids.
5375         private final SparseArray<String> mFingerprints = new SparseArray<>();
5376 
5377         @GuardedBy("mLock")
5378         // The mapping keys are user ids.
5379         private final SparseBooleanArray mPermissionUpgradeNeeded = new SparseBooleanArray();
5380 
RuntimePermissionPersistence(Object persistenceLock)5381         public RuntimePermissionPersistence(Object persistenceLock) {
5382             mPersistenceLock = persistenceLock;
5383         }
5384 
5385         @GuardedBy("Settings.this.mLock")
getVersionLPr(int userId)5386         int getVersionLPr(int userId) {
5387             return mVersions.get(userId, INITIAL_VERSION);
5388         }
5389 
5390         @GuardedBy("Settings.this.mLock")
setVersionLPr(int version, int userId)5391         void setVersionLPr(int version, int userId) {
5392             mVersions.put(userId, version);
5393             writePermissionsForUserAsyncLPr(userId);
5394         }
5395 
5396         @GuardedBy("Settings.this.mLock")
isPermissionUpgradeNeeded(int userId)5397         public boolean isPermissionUpgradeNeeded(int userId) {
5398             return mPermissionUpgradeNeeded.get(userId, true);
5399         }
5400 
5401         @GuardedBy("Settings.this.mLock")
updateRuntimePermissionsFingerprintLPr(@serIdInt int userId)5402         public void updateRuntimePermissionsFingerprintLPr(@UserIdInt int userId) {
5403             if (mExtendedFingerprint == null) {
5404                 throw new RuntimeException("The version of the permission controller hasn't been "
5405                         + "set before trying to update the fingerprint.");
5406             }
5407             mFingerprints.put(userId, mExtendedFingerprint);
5408             writePermissionsForUserAsyncLPr(userId);
5409         }
5410 
setPermissionControllerVersion(long version)5411         public void setPermissionControllerVersion(long version) {
5412             int numUser = mFingerprints.size();
5413             mExtendedFingerprint = getExtendedFingerprint(version);
5414 
5415             for (int i = 0;  i < numUser; i++) {
5416                 int userId = mFingerprints.keyAt(i);
5417                 String fingerprint = mFingerprints.valueAt(i);
5418                 mPermissionUpgradeNeeded.put(userId,
5419                         !TextUtils.equals(mExtendedFingerprint, fingerprint));
5420             }
5421         }
5422 
getExtendedFingerprint(long version)5423         private String getExtendedFingerprint(long version) {
5424             return Build.FINGERPRINT + "?pc_version=" + version;
5425         }
5426 
writePermissionsForUserSyncLPr(int userId)5427         public void writePermissionsForUserSyncLPr(int userId) {
5428             mHandler.removeMessages(userId);
5429             writePermissionsSync(userId);
5430         }
5431 
5432         @GuardedBy("Settings.this.mLock")
writePermissionsForUserAsyncLPr(int userId)5433         public void writePermissionsForUserAsyncLPr(int userId) {
5434             final long currentTimeMillis = SystemClock.uptimeMillis();
5435 
5436             if (mWriteScheduled.get(userId)) {
5437                 mHandler.removeMessages(userId);
5438 
5439                 // If enough time passed, write without holding off anymore.
5440                 final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
5441                         .get(userId);
5442                 final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
5443                         - lastNotWrittenMutationTimeMillis;
5444                 if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
5445                     mHandler.obtainMessage(userId).sendToTarget();
5446                     return;
5447                 }
5448 
5449                 // Hold off a bit more as settings are frequently changing.
5450                 final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
5451                         + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
5452                 final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
5453                         maxDelayMillis);
5454 
5455                 Message message = mHandler.obtainMessage(userId);
5456                 mHandler.sendMessageDelayed(message, writeDelayMillis);
5457             } else {
5458                 mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
5459                 Message message = mHandler.obtainMessage(userId);
5460                 mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
5461                 mWriteScheduled.put(userId, true);
5462             }
5463         }
5464 
writePermissionsSync(int userId)5465         private void writePermissionsSync(int userId) {
5466             RuntimePermissionsState runtimePermissions;
5467             synchronized (mPersistenceLock) {
5468                 mWriteScheduled.delete(userId);
5469 
5470                 int version = mVersions.get(userId, INITIAL_VERSION);
5471 
5472                 String fingerprint = mFingerprints.get(userId);
5473 
5474                 Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
5475                         new ArrayMap<>();
5476                 int packagesSize = mPackages.size();
5477                 for (int i = 0; i < packagesSize; i++) {
5478                     String packageName = mPackages.keyAt(i);
5479                     PackageSetting packageSetting = mPackages.valueAt(i);
5480                     if (packageSetting.sharedUser == null) {
5481                         List<RuntimePermissionsState.PermissionState> permissions =
5482                                 getPermissionsFromPermissionsState(
5483                                         packageSetting.getPermissionsState(), userId);
5484                         packagePermissions.put(packageName, permissions);
5485                     }
5486                 }
5487 
5488                 Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
5489                         new ArrayMap<>();
5490                 final int sharedUsersSize = mSharedUsers.size();
5491                 for (int i = 0; i < sharedUsersSize; i++) {
5492                     String sharedUserName = mSharedUsers.keyAt(i);
5493                     SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i);
5494                     List<RuntimePermissionsState.PermissionState> permissions =
5495                             getPermissionsFromPermissionsState(
5496                                     sharedUserSetting.getPermissionsState(), userId);
5497                     sharedUserPermissions.put(sharedUserName, permissions);
5498                 }
5499 
5500                 runtimePermissions = new RuntimePermissionsState(version, fingerprint,
5501                         packagePermissions, sharedUserPermissions);
5502             }
5503 
5504             mPersistence.writeForUser(runtimePermissions, UserHandle.of(userId));
5505         }
5506 
5507         @NonNull
getPermissionsFromPermissionsState( @onNull PermissionsState permissionsState, @UserIdInt int userId)5508         private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState(
5509                 @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
5510             List<PermissionState> permissionStates = permissionsState.getRuntimePermissionStates(
5511                     userId);
5512             List<RuntimePermissionsState.PermissionState> permissions =
5513                     new ArrayList<>();
5514             int permissionStatesSize = permissionStates.size();
5515             for (int i = 0; i < permissionStatesSize; i++) {
5516                 PermissionState permissionState = permissionStates.get(i);
5517 
5518                 RuntimePermissionsState.PermissionState permission =
5519                         new RuntimePermissionsState.PermissionState(permissionState.getName(),
5520                                 permissionState.isGranted(), permissionState.getFlags());
5521                 permissions.add(permission);
5522             }
5523             return permissions;
5524         }
5525 
5526         @GuardedBy("Settings.this.mLock")
onUserRemovedLPw(int userId)5527         private void onUserRemovedLPw(int userId) {
5528             // Make sure we do not
5529             mHandler.removeMessages(userId);
5530 
5531             for (SettingBase sb : mPackages.values()) {
5532                 revokeRuntimePermissionsAndClearFlags(sb, userId);
5533             }
5534 
5535             for (SettingBase sb : mSharedUsers.values()) {
5536                 revokeRuntimePermissionsAndClearFlags(sb, userId);
5537             }
5538 
5539             mPermissionUpgradeNeeded.delete(userId);
5540             mVersions.delete(userId);
5541             mFingerprints.remove(userId);
5542         }
5543 
revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId)5544         private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5545             PermissionsState permissionsState = sb.getPermissionsState();
5546             for (PermissionState permissionState
5547                     : permissionsState.getRuntimePermissionStates(userId)) {
5548                 BasePermission bp = mPermissions.getPermission(permissionState.getName());
5549                 if (bp != null) {
5550                     permissionsState.revokeRuntimePermission(bp, userId);
5551                     permissionsState.updatePermissionFlags(bp, userId,
5552                             PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
5553                 }
5554             }
5555         }
5556 
deleteUserRuntimePermissionsFile(int userId)5557         public void deleteUserRuntimePermissionsFile(int userId) {
5558             mPersistence.deleteForUser(UserHandle.of(userId));
5559         }
5560 
5561         @GuardedBy("Settings.this.mLock")
readStateForUserSyncLPr(int userId)5562         public void readStateForUserSyncLPr(int userId) {
5563             RuntimePermissionsState runtimePermissions = mPersistence.readForUser(UserHandle.of(
5564                     userId));
5565             if (runtimePermissions == null) {
5566                 readLegacyStateForUserSyncLPr(userId);
5567                 writePermissionsForUserAsyncLPr(userId);
5568                 return;
5569             }
5570 
5571             // If the runtime permissions file exists but the version is not set this is
5572             // an upgrade from P->Q. Hence mark it with the special UPGRADE_VERSION.
5573             int version = runtimePermissions.getVersion();
5574             if (version == RuntimePermissionsState.NO_VERSION) {
5575                 version = UPGRADE_VERSION;
5576             }
5577             mVersions.put(userId, version);
5578 
5579             String fingerprint = runtimePermissions.getFingerprint();
5580             mFingerprints.put(userId, fingerprint);
5581 
5582             boolean isUpgradeToR = getInternalVersion().sdkVersion < Build.VERSION_CODES.R;
5583 
5584             Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
5585                     runtimePermissions.getPackagePermissions();
5586             int packagesSize = mPackages.size();
5587             for (int i = 0; i < packagesSize; i++) {
5588                 String packageName = mPackages.keyAt(i);
5589                 PackageSetting packageSetting = mPackages.valueAt(i);
5590 
5591                 List<RuntimePermissionsState.PermissionState> permissions =
5592                         packagePermissions.get(packageName);
5593                 if (permissions != null) {
5594                     readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(),
5595                             userId);
5596                 } else if (packageSetting.sharedUser == null && !isUpgradeToR) {
5597                     Slog.w(TAG, "Missing permission state for package: " + packageName);
5598                     packageSetting.getPermissionsState().setMissing(true, userId);
5599                 }
5600             }
5601 
5602             Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
5603                     runtimePermissions.getSharedUserPermissions();
5604             int sharedUsersSize = mSharedUsers.size();
5605             for (int i = 0; i < sharedUsersSize; i++) {
5606                 String sharedUserName = mSharedUsers.keyAt(i);
5607                 SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i);
5608 
5609                 List<RuntimePermissionsState.PermissionState> permissions =
5610                         sharedUserPermissions.get(sharedUserName);
5611                 if (permissions != null) {
5612                     readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(),
5613                             userId);
5614                 } else if (!isUpgradeToR) {
5615                     Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName);
5616                     sharedUserSetting.getPermissionsState().setMissing(true, userId);
5617                 }
5618             }
5619         }
5620 
5621         private void readPermissionsStateLpr(
5622                 @NonNull List<RuntimePermissionsState.PermissionState> permissions,
5623                 @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
5624             int permissionsSize = permissions.size();
5625             for (int i = 0; i < permissionsSize; i++) {
5626                 RuntimePermissionsState.PermissionState permission = permissions.get(i);
5627 
5628                 String name = permission.getName();
5629                 BasePermission basePermission = mPermissions.getPermission(name);
5630                 if (basePermission == null) {
5631                     Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5632                     continue;
5633                 }
5634                 boolean granted = permission.isGranted();
5635                 int flags = permission.getFlags();
5636 
5637                 if (granted) {
5638                     permissionsState.grantRuntimePermission(basePermission, userId);
5639                     permissionsState.updatePermissionFlags(basePermission, userId,
5640                             PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
5641                 } else {
5642                     permissionsState.updatePermissionFlags(basePermission, userId,
5643                             PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
5644                 }
5645             }
5646         }
5647 
5648         @GuardedBy("Settings.this.mLock")
5649         private void readLegacyStateForUserSyncLPr(int userId) {
5650             File permissionsFile = getUserRuntimePermissionsFile(userId);
5651             if (!permissionsFile.exists()) {
5652                 return;
5653             }
5654 
5655             FileInputStream in;
5656             try {
5657                 in = new AtomicFile(permissionsFile).openRead();
5658             } catch (FileNotFoundException fnfe) {
5659                 Slog.i(PackageManagerService.TAG, "No permissions state");
5660                 return;
5661             }
5662 
5663             try {
5664                 XmlPullParser parser = Xml.newPullParser();
5665                 parser.setInput(in, null);
5666                 parseRuntimePermissionsLPr(parser, userId);
5667 
5668             } catch (XmlPullParserException | IOException e) {
5669                 throw new IllegalStateException("Failed parsing permissions file: "
5670                         + permissionsFile, e);
5671             } finally {
5672                 IoUtils.closeQuietly(in);
5673             }
5674         }
5675 
5676         // Private internals
5677 
5678         @GuardedBy("Settings.this.mLock")
5679         private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5680                 throws IOException, XmlPullParserException {
5681             final int outerDepth = parser.getDepth();
5682             int type;
5683             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5684                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5685                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5686                     continue;
5687                 }
5688 
5689                 switch (parser.getName()) {
5690                     case TAG_RUNTIME_PERMISSIONS: {
5691                         // If the permisions settings file exists but the version is not set this is
5692                         // an upgrade from P->Q. Hence mark it with the special UPGRADE_VERSION
5693                         int version = XmlUtils.readIntAttribute(parser, ATTR_VERSION,
5694                                 UPGRADE_VERSION);
5695                         mVersions.put(userId, version);
5696                         String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5697                         mFingerprints.put(userId, fingerprint);
5698                     } break;
5699 
5700                     case TAG_PACKAGE: {
5701                         String name = parser.getAttributeValue(null, ATTR_NAME);
5702                         PackageSetting ps = mPackages.get(name);
5703                         if (ps == null) {
5704                             Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5705                             XmlUtils.skipCurrentTag(parser);
5706                             continue;
5707                         }
5708                         parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5709                     } break;
5710 
5711                     case TAG_SHARED_USER: {
5712                         String name = parser.getAttributeValue(null, ATTR_NAME);
5713                         SharedUserSetting sus = mSharedUsers.get(name);
5714                         if (sus == null) {
5715                             Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5716                             XmlUtils.skipCurrentTag(parser);
5717                             continue;
5718                         }
5719                         parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5720                     } break;
5721                 }
5722             }
5723         }
5724 
5725         private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5726                 int userId) throws IOException, XmlPullParserException {
5727             final int outerDepth = parser.getDepth();
5728             int type;
5729             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5730                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5731                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5732                     continue;
5733                 }
5734 
5735                 switch (parser.getName()) {
5736                     case TAG_ITEM: {
5737                         String name = parser.getAttributeValue(null, ATTR_NAME);
5738                         BasePermission bp = mPermissions.getPermission(name);
5739                         if (bp == null) {
5740                             Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5741                             XmlUtils.skipCurrentTag(parser);
5742                             continue;
5743                         }
5744 
5745                         String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5746                         final boolean granted = grantedStr == null
5747                                 || Boolean.parseBoolean(grantedStr);
5748 
5749                         String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5750                         final int flags = (flagsStr != null)
5751                                 ? Integer.parseInt(flagsStr, 16) : 0;
5752 
5753                         if (granted) {
5754                             permissionsState.grantRuntimePermission(bp, userId);
5755                             permissionsState.updatePermissionFlags(bp, userId,
5756                                     PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
5757                         } else {
5758                             permissionsState.updatePermissionFlags(bp, userId,
5759                                     PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
5760                         }
5761 
5762                     }
5763                     break;
5764                 }
5765             }
5766         }
5767 
5768         private final class MyHandler extends Handler {
5769             public MyHandler() {
5770                 super(BackgroundThread.getHandler().getLooper());
5771             }
5772 
5773             @Override
5774             public void handleMessage(Message message) {
5775                 final int userId = message.what;
5776                 Runnable callback = (Runnable) message.obj;
5777                 writePermissionsSync(userId);
5778                 if (callback != null) {
5779                     callback.run();
5780                 }
5781             }
5782         }
5783     }
5784 }
5785