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