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