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