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