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