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