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_SYSTEM_EXT
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_SYSTEM_EXT;
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)1246     boolean removeIntentFilterVerificationLPw(String packageName, int userId) {
1247         PackageSetting ps = mPackages.get(packageName);
1248         if (ps == null) {
1249             if (DEBUG_DOMAIN_VERIFICATION) {
1250                 Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
1251             }
1252             return false;
1253         }
1254         ps.clearDomainVerificationStatusForUser(userId);
1255         return true;
1256     }
1257 
removeIntentFilterVerificationLPw(String packageName, int[] userIds)1258     boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) {
1259         boolean result = false;
1260         for (int userId : userIds) {
1261             result |= removeIntentFilterVerificationLPw(packageName, userId);
1262         }
1263         return result;
1264     }
1265 
removeDefaultBrowserPackageNameLPw(int userId)1266     String removeDefaultBrowserPackageNameLPw(int userId) {
1267         return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId);
1268     }
1269 
getUserPackagesStateFile(int userId)1270     private File getUserPackagesStateFile(int userId) {
1271         // TODO: Implement a cleaner solution when adding tests.
1272         // This instead of Environment.getUserSystemDirectory(userId) to support testing.
1273         File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
1274         return new File(userDir, "package-restrictions.xml");
1275     }
1276 
getUserRuntimePermissionsFile(int userId)1277     private File getUserRuntimePermissionsFile(int userId) {
1278         // TODO: Implement a cleaner solution when adding tests.
1279         // This instead of Environment.getUserSystemDirectory(userId) to support testing.
1280         File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
1281         return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
1282     }
1283 
getUserPackagesStateBackupFile(int userId)1284     private File getUserPackagesStateBackupFile(int userId) {
1285         return new File(Environment.getUserSystemDirectory(userId),
1286                 "package-restrictions-backup.xml");
1287     }
1288 
writeAllUsersPackageRestrictionsLPr()1289     void writeAllUsersPackageRestrictionsLPr() {
1290         List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
1291         if (users == null) return;
1292 
1293         for (UserInfo user : users) {
1294             writePackageRestrictionsLPr(user.id);
1295         }
1296     }
1297 
writeAllRuntimePermissionsLPr()1298     void writeAllRuntimePermissionsLPr() {
1299         for (int userId : UserManagerService.getInstance().getUserIds()) {
1300             mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
1301         }
1302     }
1303 
areDefaultRuntimePermissionsGrantedLPr(int userId)1304     boolean areDefaultRuntimePermissionsGrantedLPr(int userId) {
1305         return mRuntimePermissionsPersistence
1306                 .areDefaultRuntimePermissionsGrantedLPr(userId);
1307     }
1308 
setRuntimePermissionsFingerPrintLPr(@onNull String fingerPrint, @UserIdInt int userId)1309     void setRuntimePermissionsFingerPrintLPr(@NonNull String fingerPrint, @UserIdInt int userId) {
1310         mRuntimePermissionsPersistence.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
1311     }
1312 
getDefaultRuntimePermissionsVersionLPr(int userId)1313     int getDefaultRuntimePermissionsVersionLPr(int userId) {
1314         return mRuntimePermissionsPersistence.getVersionLPr(userId);
1315     }
1316 
setDefaultRuntimePermissionsVersionLPr(int version, int userId)1317     void setDefaultRuntimePermissionsVersionLPr(int version, int userId) {
1318         mRuntimePermissionsPersistence.setVersionLPr(version, userId);
1319     }
1320 
findOrCreateVersion(String volumeUuid)1321     public VersionInfo findOrCreateVersion(String volumeUuid) {
1322         VersionInfo ver = mVersion.get(volumeUuid);
1323         if (ver == null) {
1324             ver = new VersionInfo();
1325             mVersion.put(volumeUuid, ver);
1326         }
1327         return ver;
1328     }
1329 
getInternalVersion()1330     public VersionInfo getInternalVersion() {
1331         return mVersion.get(StorageManager.UUID_PRIVATE_INTERNAL);
1332     }
1333 
getExternalVersion()1334     public VersionInfo getExternalVersion() {
1335         return mVersion.get(StorageManager.UUID_PRIMARY_PHYSICAL);
1336     }
1337 
onVolumeForgotten(String fsUuid)1338     public void onVolumeForgotten(String fsUuid) {
1339         mVersion.remove(fsUuid);
1340     }
1341 
1342     /**
1343      * Applies the preferred activity state described by the given XML.  This code
1344      * also supports the restore-from-backup code path.
1345      *
1346      * @see PreferredActivityBackupHelper
1347      */
readPreferredActivitiesLPw(XmlPullParser parser, int userId)1348     void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
1349             throws XmlPullParserException, IOException {
1350         int outerDepth = parser.getDepth();
1351         int type;
1352         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1353                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1354             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1355                 continue;
1356             }
1357 
1358             String tagName = parser.getName();
1359             if (tagName.equals(TAG_ITEM)) {
1360                 PreferredActivity pa = new PreferredActivity(parser);
1361                 if (pa.mPref.getParseError() == null) {
1362                     editPreferredActivitiesLPw(userId).addFilter(pa);
1363                 } else {
1364                     PackageManagerService.reportSettingsProblem(Log.WARN,
1365                             "Error in package manager settings: <preferred-activity> "
1366                                     + pa.mPref.getParseError() + " at "
1367                                     + parser.getPositionDescription());
1368                 }
1369             } else {
1370                 PackageManagerService.reportSettingsProblem(Log.WARN,
1371                         "Unknown element under <preferred-activities>: " + parser.getName());
1372                 XmlUtils.skipCurrentTag(parser);
1373             }
1374         }
1375     }
1376 
readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)1377     private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)
1378             throws XmlPullParserException, IOException {
1379         int outerDepth = parser.getDepth();
1380         int type;
1381         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1382                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1383             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1384                 continue;
1385             }
1386             String tagName = parser.getName();
1387             if (tagName.equals(TAG_ITEM)) {
1388                 PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
1389                 editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
1390             } else {
1391                 PackageManagerService.reportSettingsProblem(Log.WARN,
1392                         "Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: "
1393                         + parser.getName());
1394                 XmlUtils.skipCurrentTag(parser);
1395             }
1396         }
1397     }
1398 
readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)1399     private void readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)
1400             throws XmlPullParserException, IOException {
1401         int outerDepth = parser.getDepth();
1402         int type;
1403         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1404                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1405             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1406                 continue;
1407             }
1408             final String tagName = parser.getName();
1409             if (tagName.equals(TAG_ITEM)) {
1410                 CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
1411                 editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
1412             } else {
1413                 String msg = "Unknown element under " +  TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
1414                         tagName;
1415                 PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1416                 XmlUtils.skipCurrentTag(parser);
1417             }
1418         }
1419     }
1420 
readDomainVerificationLPw(XmlPullParser parser, PackageSettingBase packageSetting)1421     private void readDomainVerificationLPw(XmlPullParser parser, PackageSettingBase packageSetting)
1422             throws XmlPullParserException, IOException {
1423         IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1424         packageSetting.setIntentFilterVerificationInfo(ivi);
1425         if (DEBUG_PARSER) {
1426             Log.d(TAG, "Read domain verification for package: " + ivi.getPackageName());
1427         }
1428     }
1429 
readRestoredIntentFilterVerifications(XmlPullParser parser)1430     private void readRestoredIntentFilterVerifications(XmlPullParser parser)
1431             throws XmlPullParserException, IOException {
1432         int outerDepth = parser.getDepth();
1433         int type;
1434         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1435                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1436             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1437                 continue;
1438             }
1439             final String tagName = parser.getName();
1440             if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
1441                 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1442                 if (DEBUG_DOMAIN_VERIFICATION) {
1443                     Slog.i(TAG, "Restored IVI for " + ivi.getPackageName()
1444                             + " status=" + ivi.getStatusString());
1445                 }
1446                 mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi);
1447             } else {
1448                 Slog.w(TAG, "Unknown element: " + tagName);
1449                 XmlUtils.skipCurrentTag(parser);
1450             }
1451         }
1452     }
1453 
readDefaultAppsLPw(XmlPullParser parser, int userId)1454     void readDefaultAppsLPw(XmlPullParser parser, int userId)
1455             throws XmlPullParserException, IOException {
1456         int outerDepth = parser.getDepth();
1457         int type;
1458         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1459                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1460             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1461                 continue;
1462             }
1463             String tagName = parser.getName();
1464             if (tagName.equals(TAG_DEFAULT_BROWSER)) {
1465                 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
1466                 mDefaultBrowserApp.put(userId, packageName);
1467             } else if (tagName.equals(TAG_DEFAULT_DIALER)) {
1468                 // Ignored.
1469             } else {
1470                 String msg = "Unknown element under " +  TAG_DEFAULT_APPS + ": " +
1471                         parser.getName();
1472                 PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1473                 XmlUtils.skipCurrentTag(parser);
1474             }
1475         }
1476     }
1477 
readBlockUninstallPackagesLPw(XmlPullParser parser, int userId)1478     void readBlockUninstallPackagesLPw(XmlPullParser parser, int userId)
1479             throws XmlPullParserException, IOException {
1480         int outerDepth = parser.getDepth();
1481         int type;
1482         ArraySet<String> packages = new ArraySet<>();
1483         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1484                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1485             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1486                 continue;
1487             }
1488             String tagName = parser.getName();
1489             if (tagName.equals(TAG_BLOCK_UNINSTALL)) {
1490                 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
1491                 packages.add(packageName);
1492             } else {
1493                 String msg = "Unknown element under " +  TAG_BLOCK_UNINSTALL_PACKAGES + ": " +
1494                         parser.getName();
1495                 PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1496                 XmlUtils.skipCurrentTag(parser);
1497             }
1498         }
1499         if (packages.isEmpty()) {
1500             mBlockUninstallPackages.remove(userId);
1501         } else {
1502             mBlockUninstallPackages.put(userId, packages);
1503         }
1504     }
1505 
readPackageRestrictionsLPr(int userId)1506     void readPackageRestrictionsLPr(int userId) {
1507         if (DEBUG_MU) {
1508             Log.i(TAG, "Reading package restrictions for user=" + userId);
1509         }
1510         FileInputStream str = null;
1511         File userPackagesStateFile = getUserPackagesStateFile(userId);
1512         File backupFile = getUserPackagesStateBackupFile(userId);
1513         if (backupFile.exists()) {
1514             try {
1515                 str = new FileInputStream(backupFile);
1516                 mReadMessages.append("Reading from backup stopped packages file\n");
1517                 PackageManagerService.reportSettingsProblem(Log.INFO,
1518                         "Need to read from backup stopped packages file");
1519                 if (userPackagesStateFile.exists()) {
1520                     // If both the backup and normal file exist, we
1521                     // ignore the normal one since it might have been
1522                     // corrupted.
1523                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1524                             + userPackagesStateFile);
1525                     userPackagesStateFile.delete();
1526                 }
1527             } catch (java.io.IOException e) {
1528                 // We'll try for the normal settings file.
1529             }
1530         }
1531 
1532         try {
1533             if (str == null) {
1534                 if (!userPackagesStateFile.exists()) {
1535                     mReadMessages.append("No stopped packages file found\n");
1536                     PackageManagerService.reportSettingsProblem(Log.INFO,
1537                             "No stopped packages file; "
1538                             + "assuming all started");
1539                     // At first boot, make sure no packages are stopped.
1540                     // We usually want to have third party apps initialize
1541                     // in the stopped state, but not at first boot.  Also
1542                     // consider all applications to be installed.
1543                     for (PackageSetting pkg : mPackages.values()) {
1544                         pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
1545                                 true  /*installed*/,
1546                                 false /*stopped*/,
1547                                 false /*notLaunched*/,
1548                                 false /*hidden*/,
1549                                 0 /*distractionFlags*/,
1550                                 false /*suspended*/,
1551                                 null /*suspendingPackage*/,
1552                                 null /*dialogInfo*/,
1553                                 null /*suspendedAppExtras*/,
1554                                 null /*suspendedLauncherExtras*/,
1555                                 false /*instantApp*/,
1556                                 false /*virtualPreload*/,
1557                                 null /*lastDisableAppCaller*/,
1558                                 null /*enabledComponents*/,
1559                                 null /*disabledComponents*/,
1560                                 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
1561                                 0, PackageManager.INSTALL_REASON_UNKNOWN,
1562                                 null /*harmfulAppWarning*/);
1563                     }
1564                     return;
1565                 }
1566                 str = new FileInputStream(userPackagesStateFile);
1567             }
1568             final XmlPullParser parser = Xml.newPullParser();
1569             parser.setInput(str, StandardCharsets.UTF_8.name());
1570 
1571             int type;
1572             while ((type=parser.next()) != XmlPullParser.START_TAG
1573                        && type != XmlPullParser.END_DOCUMENT) {
1574                 ;
1575             }
1576 
1577             if (type != XmlPullParser.START_TAG) {
1578                 mReadMessages.append("No start tag found in package restrictions file\n");
1579                 PackageManagerService.reportSettingsProblem(Log.WARN,
1580                         "No start tag found in package manager stopped packages");
1581                 return;
1582             }
1583 
1584             int maxAppLinkGeneration = 0;
1585 
1586             int outerDepth = parser.getDepth();
1587             PackageSetting ps = null;
1588             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1589                    && (type != XmlPullParser.END_TAG
1590                            || parser.getDepth() > outerDepth)) {
1591                 if (type == XmlPullParser.END_TAG
1592                         || type == XmlPullParser.TEXT) {
1593                     continue;
1594                 }
1595 
1596                 String tagName = parser.getName();
1597                 if (tagName.equals(TAG_PACKAGE)) {
1598                     String name = parser.getAttributeValue(null, ATTR_NAME);
1599                     ps = mPackages.get(name);
1600                     if (ps == null) {
1601                         Slog.w(PackageManagerService.TAG, "No package known for stopped package "
1602                                 + name);
1603                         XmlUtils.skipCurrentTag(parser);
1604                         continue;
1605                     }
1606 
1607                     final long ceDataInode = XmlUtils.readLongAttribute(parser, ATTR_CE_DATA_INODE,
1608                             0);
1609                     final boolean installed = XmlUtils.readBooleanAttribute(parser, ATTR_INSTALLED,
1610                             true);
1611                     final boolean stopped = XmlUtils.readBooleanAttribute(parser, ATTR_STOPPED,
1612                             false);
1613                     final boolean notLaunched = XmlUtils.readBooleanAttribute(parser,
1614                             ATTR_NOT_LAUNCHED, false);
1615 
1616                     // For backwards compatibility with the previous name of "blocked", which
1617                     // now means hidden, read the old attribute as well.
1618                     final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
1619                     boolean hidden = blockedStr == null
1620                             ? false : Boolean.parseBoolean(blockedStr);
1621                     final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN);
1622                     hidden = hiddenStr == null
1623                             ? hidden : Boolean.parseBoolean(hiddenStr);
1624 
1625                     final int distractionFlags = XmlUtils.readIntAttribute(parser,
1626                             ATTR_DISTRACTION_FLAGS, 0);
1627                     final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED,
1628                             false);
1629                     String suspendingPackage = parser.getAttributeValue(null,
1630                             ATTR_SUSPENDING_PACKAGE);
1631                     final String dialogMessage = parser.getAttributeValue(null,
1632                             ATTR_SUSPEND_DIALOG_MESSAGE);
1633                     if (suspended && suspendingPackage == null) {
1634                         suspendingPackage = PLATFORM_PACKAGE_NAME;
1635                     }
1636 
1637                     final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser,
1638                             ATTR_BLOCK_UNINSTALL, false);
1639                     final boolean instantApp = XmlUtils.readBooleanAttribute(parser,
1640                             ATTR_INSTANT_APP, false);
1641                     final boolean virtualPreload = XmlUtils.readBooleanAttribute(parser,
1642                             ATTR_VIRTUAL_PRELOAD, false);
1643                     final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED,
1644                             COMPONENT_ENABLED_STATE_DEFAULT);
1645                     final String enabledCaller = parser.getAttributeValue(null,
1646                             ATTR_ENABLED_CALLER);
1647                     final String harmfulAppWarning =
1648                             parser.getAttributeValue(null, ATTR_HARMFUL_APP_WARNING);
1649                     final int verifState = XmlUtils.readIntAttribute(parser,
1650                             ATTR_DOMAIN_VERIFICATON_STATE,
1651                             PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
1652                     final int linkGeneration = XmlUtils.readIntAttribute(parser,
1653                             ATTR_APP_LINK_GENERATION, 0);
1654                     if (linkGeneration > maxAppLinkGeneration) {
1655                         maxAppLinkGeneration = linkGeneration;
1656                     }
1657                     final int installReason = XmlUtils.readIntAttribute(parser,
1658                             ATTR_INSTALL_REASON, PackageManager.INSTALL_REASON_UNKNOWN);
1659 
1660                     ArraySet<String> enabledComponents = null;
1661                     ArraySet<String> disabledComponents = null;
1662                     PersistableBundle suspendedAppExtras = null;
1663                     PersistableBundle suspendedLauncherExtras = null;
1664                     SuspendDialogInfo suspendDialogInfo = null;
1665 
1666                     int packageDepth = parser.getDepth();
1667                     while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1668                             && (type != XmlPullParser.END_TAG
1669                             || parser.getDepth() > packageDepth)) {
1670                         if (type == XmlPullParser.END_TAG
1671                                 || type == XmlPullParser.TEXT) {
1672                             continue;
1673                         }
1674                         switch (parser.getName()) {
1675                             case TAG_ENABLED_COMPONENTS:
1676                                 enabledComponents = readComponentsLPr(parser);
1677                                 break;
1678                             case TAG_DISABLED_COMPONENTS:
1679                                 disabledComponents = readComponentsLPr(parser);
1680                                 break;
1681                             case TAG_SUSPENDED_APP_EXTRAS:
1682                                 suspendedAppExtras = PersistableBundle.restoreFromXml(parser);
1683                                 break;
1684                             case TAG_SUSPENDED_LAUNCHER_EXTRAS:
1685                                 suspendedLauncherExtras = PersistableBundle.restoreFromXml(parser);
1686                                 break;
1687                             case TAG_SUSPENDED_DIALOG_INFO:
1688                                 suspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
1689                                 break;
1690                             default:
1691                                 Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
1692                                         + TAG_PACKAGE);
1693                         }
1694                     }
1695                     if (suspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
1696                         suspendDialogInfo = new SuspendDialogInfo.Builder()
1697                                 .setMessage(dialogMessage)
1698                                 .build();
1699                     }
1700 
1701                     if (blockUninstall) {
1702                         setBlockUninstallLPw(userId, name, true);
1703                     }
1704                     ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
1705                             hidden, distractionFlags, suspended, suspendingPackage,
1706                             suspendDialogInfo,
1707                             suspendedAppExtras, suspendedLauncherExtras, instantApp, virtualPreload,
1708                             enabledCaller, enabledComponents, disabledComponents, verifState,
1709                             linkGeneration, installReason, harmfulAppWarning);
1710                 } else if (tagName.equals("preferred-activities")) {
1711                     readPreferredActivitiesLPw(parser, userId);
1712                 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1713                     readPersistentPreferredActivitiesLPw(parser, userId);
1714                 } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
1715                     readCrossProfileIntentFiltersLPw(parser, userId);
1716                 } else if (tagName.equals(TAG_DEFAULT_APPS)) {
1717                     readDefaultAppsLPw(parser, userId);
1718                 } else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) {
1719                     readBlockUninstallPackagesLPw(parser, userId);
1720                 } else {
1721                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1722                           + parser.getName());
1723                     XmlUtils.skipCurrentTag(parser);
1724                 }
1725             }
1726 
1727             str.close();
1728 
1729             mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1);
1730 
1731         } catch (XmlPullParserException e) {
1732             mReadMessages.append("Error reading: " + e.toString());
1733             PackageManagerService.reportSettingsProblem(Log.ERROR,
1734                     "Error reading stopped packages: " + e);
1735             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1736                     e);
1737 
1738         } catch (java.io.IOException e) {
1739             mReadMessages.append("Error reading: " + e.toString());
1740             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1741             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1742                     e);
1743         }
1744     }
1745 
setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall)1746     void setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall) {
1747         ArraySet<String> packages = mBlockUninstallPackages.get(userId);
1748         if (blockUninstall) {
1749             if (packages == null) {
1750                 packages = new ArraySet<String>();
1751                 mBlockUninstallPackages.put(userId, packages);
1752             }
1753             packages.add(packageName);
1754         } else if (packages != null) {
1755             packages.remove(packageName);
1756             if (packages.isEmpty()) {
1757                 mBlockUninstallPackages.remove(userId);
1758             }
1759         }
1760     }
1761 
getBlockUninstallLPr(int userId, String packageName)1762     boolean getBlockUninstallLPr(int userId, String packageName) {
1763         ArraySet<String> packages = mBlockUninstallPackages.get(userId);
1764         if (packages == null) {
1765             return false;
1766         }
1767         return packages.contains(packageName);
1768     }
1769 
readComponentsLPr(XmlPullParser parser)1770     private ArraySet<String> readComponentsLPr(XmlPullParser parser)
1771             throws IOException, XmlPullParserException {
1772         ArraySet<String> components = null;
1773         int type;
1774         int outerDepth = parser.getDepth();
1775         String tagName;
1776         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1777                 && (type != XmlPullParser.END_TAG
1778                 || parser.getDepth() > outerDepth)) {
1779             if (type == XmlPullParser.END_TAG
1780                     || type == XmlPullParser.TEXT) {
1781                 continue;
1782             }
1783             tagName = parser.getName();
1784             if (tagName.equals(TAG_ITEM)) {
1785                 String componentName = parser.getAttributeValue(null, ATTR_NAME);
1786                 if (componentName != null) {
1787                     if (components == null) {
1788                         components = new ArraySet<String>();
1789                     }
1790                     components.add(componentName);
1791                 }
1792             }
1793         }
1794         return components;
1795     }
1796 
1797     /**
1798      * Record the state of preferred activity configuration into XML.  This is used both
1799      * for recording packages.xml internally and for supporting backup/restore of the
1800      * preferred activity configuration.
1801      */
writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)1802     void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
1803             throws IllegalArgumentException, IllegalStateException, IOException {
1804         serializer.startTag(null, "preferred-activities");
1805         PreferredIntentResolver pir = mPreferredActivities.get(userId);
1806         if (pir != null) {
1807             for (final PreferredActivity pa : pir.filterSet()) {
1808                 serializer.startTag(null, TAG_ITEM);
1809                 pa.writeToXml(serializer, full);
1810                 serializer.endTag(null, TAG_ITEM);
1811             }
1812         }
1813         serializer.endTag(null, "preferred-activities");
1814     }
1815 
writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)1816     void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
1817             throws IllegalArgumentException, IllegalStateException, IOException {
1818         serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1819         PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1820         if (ppir != null) {
1821             for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
1822                 serializer.startTag(null, TAG_ITEM);
1823                 ppa.writeToXml(serializer);
1824                 serializer.endTag(null, TAG_ITEM);
1825             }
1826         }
1827         serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1828     }
1829 
writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)1830     void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)
1831             throws IllegalArgumentException, IllegalStateException, IOException {
1832         serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1833         CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1834         if (cpir != null) {
1835             for (final CrossProfileIntentFilter cpif : cpir.filterSet()) {
1836                 serializer.startTag(null, TAG_ITEM);
1837                 cpif.writeToXml(serializer);
1838                 serializer.endTag(null, TAG_ITEM);
1839             }
1840         }
1841         serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1842     }
1843 
writeDomainVerificationsLPr(XmlSerializer serializer, IntentFilterVerificationInfo verificationInfo)1844     void writeDomainVerificationsLPr(XmlSerializer serializer,
1845                                      IntentFilterVerificationInfo verificationInfo)
1846             throws IllegalArgumentException, IllegalStateException, IOException {
1847         if (verificationInfo != null && verificationInfo.getPackageName() != null) {
1848             serializer.startTag(null, TAG_DOMAIN_VERIFICATION);
1849             verificationInfo.writeToXml(serializer);
1850             if (DEBUG_DOMAIN_VERIFICATION) {
1851                 Slog.d(TAG, "Wrote domain verification for package: "
1852                         + verificationInfo.getPackageName());
1853             }
1854             serializer.endTag(null, TAG_DOMAIN_VERIFICATION);
1855         }
1856     }
1857 
1858     // Specifically for backup/restore
writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)1859     void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)
1860             throws IllegalArgumentException, IllegalStateException, IOException {
1861         serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
1862         final int N = mPackages.size();
1863         for (int i = 0; i < N; i++) {
1864             PackageSetting ps = mPackages.valueAt(i);
1865             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
1866             if (ivi != null) {
1867                 writeDomainVerificationsLPr(serializer, ivi);
1868             }
1869         }
1870         serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
1871     }
1872 
1873     // Specifically for backup/restore
readAllDomainVerificationsLPr(XmlPullParser parser, int userId)1874     void readAllDomainVerificationsLPr(XmlPullParser parser, int userId)
1875             throws XmlPullParserException, IOException {
1876         mRestoredIntentFilterVerifications.clear();
1877 
1878         int outerDepth = parser.getDepth();
1879         int type;
1880         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1881                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1882             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1883                 continue;
1884             }
1885 
1886             String tagName = parser.getName();
1887             if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
1888                 IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1889                 final String pkgName = ivi.getPackageName();
1890                 final PackageSetting ps = mPackages.get(pkgName);
1891                 if (ps != null) {
1892                     // known/existing package; update in place
1893                     ps.setIntentFilterVerificationInfo(ivi);
1894                     if (DEBUG_DOMAIN_VERIFICATION) {
1895                         Slog.d(TAG, "Restored IVI for existing app " + pkgName
1896                                 + " status=" + ivi.getStatusString());
1897                     }
1898                 } else {
1899                     mRestoredIntentFilterVerifications.put(pkgName, ivi);
1900                     if (DEBUG_DOMAIN_VERIFICATION) {
1901                         Slog.d(TAG, "Restored IVI for pending app " + pkgName
1902                                 + " status=" + ivi.getStatusString());
1903                     }
1904                 }
1905             } else {
1906                 PackageManagerService.reportSettingsProblem(Log.WARN,
1907                         "Unknown element under <all-intent-filter-verification>: "
1908                         + parser.getName());
1909                 XmlUtils.skipCurrentTag(parser);
1910             }
1911         }
1912     }
1913 
writeDefaultAppsLPr(XmlSerializer serializer, int userId)1914     void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
1915             throws IllegalArgumentException, IllegalStateException, IOException {
1916         serializer.startTag(null, TAG_DEFAULT_APPS);
1917         String defaultBrowser = mDefaultBrowserApp.get(userId);
1918         if (!TextUtils.isEmpty(defaultBrowser)) {
1919             serializer.startTag(null, TAG_DEFAULT_BROWSER);
1920             serializer.attribute(null, ATTR_PACKAGE_NAME, defaultBrowser);
1921             serializer.endTag(null, TAG_DEFAULT_BROWSER);
1922         }
1923         serializer.endTag(null, TAG_DEFAULT_APPS);
1924     }
1925 
writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId)1926     void writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId)
1927             throws IOException  {
1928         ArraySet<String> packages = mBlockUninstallPackages.get(userId);
1929         if (packages != null) {
1930             serializer.startTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
1931             for (int i = 0; i < packages.size(); i++) {
1932                  serializer.startTag(null, TAG_BLOCK_UNINSTALL);
1933                  serializer.attribute(null, ATTR_PACKAGE_NAME, packages.valueAt(i));
1934                  serializer.endTag(null, TAG_BLOCK_UNINSTALL);
1935             }
1936             serializer.endTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
1937         }
1938     }
1939 
writePackageRestrictionsLPr(int userId)1940     void writePackageRestrictionsLPr(int userId) {
1941         if (DEBUG_MU) {
1942             Log.i(TAG, "Writing package restrictions for user=" + userId);
1943         }
1944         final long startTime = SystemClock.uptimeMillis();
1945 
1946         // Keep the old stopped packages around until we know the new ones have
1947         // been successfully written.
1948         File userPackagesStateFile = getUserPackagesStateFile(userId);
1949         File backupFile = getUserPackagesStateBackupFile(userId);
1950         new File(userPackagesStateFile.getParent()).mkdirs();
1951         if (userPackagesStateFile.exists()) {
1952             // Presence of backup settings file indicates that we failed
1953             // to persist packages earlier. So preserve the older
1954             // backup for future reference since the current packages
1955             // might have been corrupted.
1956             if (!backupFile.exists()) {
1957                 if (!userPackagesStateFile.renameTo(backupFile)) {
1958                     Slog.wtf(PackageManagerService.TAG,
1959                             "Unable to backup user packages state file, "
1960                             + "current changes will be lost at reboot");
1961                     return;
1962                 }
1963             } else {
1964                 userPackagesStateFile.delete();
1965                 Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
1966             }
1967         }
1968 
1969         try {
1970             final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
1971             final BufferedOutputStream str = new BufferedOutputStream(fstr);
1972 
1973             final XmlSerializer serializer = new FastXmlSerializer();
1974             serializer.setOutput(str, StandardCharsets.UTF_8.name());
1975             serializer.startDocument(null, true);
1976             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1977 
1978             serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
1979 
1980             for (final PackageSetting pkg : mPackages.values()) {
1981                 final PackageUserState ustate = pkg.readUserState(userId);
1982                 if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
1983 
1984                 serializer.startTag(null, TAG_PACKAGE);
1985                 serializer.attribute(null, ATTR_NAME, pkg.name);
1986                 if (ustate.ceDataInode != 0) {
1987                     XmlUtils.writeLongAttribute(serializer, ATTR_CE_DATA_INODE, ustate.ceDataInode);
1988                 }
1989                 if (!ustate.installed) {
1990                     serializer.attribute(null, ATTR_INSTALLED, "false");
1991                 }
1992                 if (ustate.stopped) {
1993                     serializer.attribute(null, ATTR_STOPPED, "true");
1994                 }
1995                 if (ustate.notLaunched) {
1996                     serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
1997                 }
1998                 if (ustate.hidden) {
1999                     serializer.attribute(null, ATTR_HIDDEN, "true");
2000                 }
2001                 if (ustate.distractionFlags != 0) {
2002                     serializer.attribute(null, ATTR_DISTRACTION_FLAGS,
2003                             Integer.toString(ustate.distractionFlags));
2004                 }
2005                 if (ustate.suspended) {
2006                     serializer.attribute(null, ATTR_SUSPENDED, "true");
2007                     if (ustate.suspendingPackage != null) {
2008                         serializer.attribute(null, ATTR_SUSPENDING_PACKAGE,
2009                                 ustate.suspendingPackage);
2010                     }
2011                     if (ustate.dialogInfo != null) {
2012                         serializer.startTag(null, TAG_SUSPENDED_DIALOG_INFO);
2013                         ustate.dialogInfo.saveToXml(serializer);
2014                         serializer.endTag(null, TAG_SUSPENDED_DIALOG_INFO);
2015                     }
2016                     if (ustate.suspendedAppExtras != null) {
2017                         serializer.startTag(null, TAG_SUSPENDED_APP_EXTRAS);
2018                         try {
2019                             ustate.suspendedAppExtras.saveToXml(serializer);
2020                         } catch (XmlPullParserException xmle) {
2021                             Slog.wtf(TAG, "Exception while trying to write suspendedAppExtras for "
2022                                     + pkg + ". Will be lost on reboot", xmle);
2023                         }
2024                         serializer.endTag(null, TAG_SUSPENDED_APP_EXTRAS);
2025                     }
2026                     if (ustate.suspendedLauncherExtras != null) {
2027                         serializer.startTag(null, TAG_SUSPENDED_LAUNCHER_EXTRAS);
2028                         try {
2029                             ustate.suspendedLauncherExtras.saveToXml(serializer);
2030                         } catch (XmlPullParserException xmle) {
2031                             Slog.wtf(TAG, "Exception while trying to write suspendedLauncherExtras"
2032                                     + " for " + pkg + ". Will be lost on reboot", xmle);
2033                         }
2034                         serializer.endTag(null, TAG_SUSPENDED_LAUNCHER_EXTRAS);
2035                     }
2036                 }
2037                 if (ustate.instantApp) {
2038                     serializer.attribute(null, ATTR_INSTANT_APP, "true");
2039                 }
2040                 if (ustate.virtualPreload) {
2041                     serializer.attribute(null, ATTR_VIRTUAL_PRELOAD, "true");
2042                 }
2043                 if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
2044                     serializer.attribute(null, ATTR_ENABLED,
2045                             Integer.toString(ustate.enabled));
2046                     if (ustate.lastDisableAppCaller != null) {
2047                         serializer.attribute(null, ATTR_ENABLED_CALLER,
2048                                 ustate.lastDisableAppCaller);
2049                     }
2050                 }
2051                 if (ustate.domainVerificationStatus !=
2052                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
2053                     XmlUtils.writeIntAttribute(serializer, ATTR_DOMAIN_VERIFICATON_STATE,
2054                             ustate.domainVerificationStatus);
2055                 }
2056                 if (ustate.appLinkGeneration != 0) {
2057                     XmlUtils.writeIntAttribute(serializer, ATTR_APP_LINK_GENERATION,
2058                             ustate.appLinkGeneration);
2059                 }
2060                 if (ustate.installReason != PackageManager.INSTALL_REASON_UNKNOWN) {
2061                     serializer.attribute(null, ATTR_INSTALL_REASON,
2062                             Integer.toString(ustate.installReason));
2063                 }
2064                 if (ustate.harmfulAppWarning != null) {
2065                     serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
2066                             ustate.harmfulAppWarning);
2067                 }
2068                 if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
2069                     serializer.startTag(null, TAG_ENABLED_COMPONENTS);
2070                     for (final String name : ustate.enabledComponents) {
2071                         serializer.startTag(null, TAG_ITEM);
2072                         serializer.attribute(null, ATTR_NAME, name);
2073                         serializer.endTag(null, TAG_ITEM);
2074                     }
2075                     serializer.endTag(null, TAG_ENABLED_COMPONENTS);
2076                 }
2077                 if (!ArrayUtils.isEmpty(ustate.disabledComponents)) {
2078                     serializer.startTag(null, TAG_DISABLED_COMPONENTS);
2079                     for (final String name : ustate.disabledComponents) {
2080                         serializer.startTag(null, TAG_ITEM);
2081                         serializer.attribute(null, ATTR_NAME, name);
2082                         serializer.endTag(null, TAG_ITEM);
2083                     }
2084                     serializer.endTag(null, TAG_DISABLED_COMPONENTS);
2085                 }
2086 
2087                 serializer.endTag(null, TAG_PACKAGE);
2088             }
2089 
2090             writePreferredActivitiesLPr(serializer, userId, true);
2091             writePersistentPreferredActivitiesLPr(serializer, userId);
2092             writeCrossProfileIntentFiltersLPr(serializer, userId);
2093             writeDefaultAppsLPr(serializer, userId);
2094             writeBlockUninstallPackagesLPr(serializer, userId);
2095 
2096             serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
2097 
2098             serializer.endDocument();
2099 
2100             str.flush();
2101             FileUtils.sync(fstr);
2102             str.close();
2103 
2104             // New settings successfully written, old ones are no longer
2105             // needed.
2106             backupFile.delete();
2107             FileUtils.setPermissions(userPackagesStateFile.toString(),
2108                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
2109                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2110                     -1, -1);
2111 
2112             com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
2113                     "package-user-" + userId, SystemClock.uptimeMillis() - startTime);
2114 
2115             // Done, all is good!
2116             return;
2117         } catch(java.io.IOException e) {
2118             Slog.wtf(PackageManagerService.TAG,
2119                     "Unable to write package manager user packages state, "
2120                     + " current changes will be lost at reboot", e);
2121         }
2122 
2123         // Clean up partially written files
2124         if (userPackagesStateFile.exists()) {
2125             if (!userPackagesStateFile.delete()) {
2126                 Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
2127                         + mStoppedPackagesFilename);
2128             }
2129         }
2130     }
2131 
readInstallPermissionsLPr(XmlPullParser parser, PermissionsState permissionsState)2132     void readInstallPermissionsLPr(XmlPullParser parser,
2133             PermissionsState permissionsState) throws IOException, XmlPullParserException {
2134         int outerDepth = parser.getDepth();
2135         int type;
2136         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2137                 && (type != XmlPullParser.END_TAG
2138                 || parser.getDepth() > outerDepth)) {
2139             if (type == XmlPullParser.END_TAG
2140                     || type == XmlPullParser.TEXT) {
2141                 continue;
2142             }
2143             String tagName = parser.getName();
2144             if (tagName.equals(TAG_ITEM)) {
2145                 String name = parser.getAttributeValue(null, ATTR_NAME);
2146 
2147                 BasePermission bp = mPermissions.getPermission(name);
2148                 if (bp == null) {
2149                     Slog.w(PackageManagerService.TAG, "Unknown permission: " + name);
2150                     XmlUtils.skipCurrentTag(parser);
2151                     continue;
2152                 }
2153 
2154                 String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
2155                 final boolean granted = grantedStr == null
2156                         || Boolean.parseBoolean(grantedStr);
2157 
2158                 String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
2159                 final int flags = (flagsStr != null)
2160                         ? Integer.parseInt(flagsStr, 16) : 0;
2161 
2162                 if (granted) {
2163                     if (permissionsState.grantInstallPermission(bp) ==
2164                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
2165                         Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2166                         XmlUtils.skipCurrentTag(parser);
2167                     } else {
2168                         permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2169                                 PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
2170                     }
2171                 } else {
2172                     if (permissionsState.revokeInstallPermission(bp) ==
2173                             PermissionsState.PERMISSION_OPERATION_FAILURE) {
2174                         Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2175                         XmlUtils.skipCurrentTag(parser);
2176                     } else {
2177                         permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2178                                 PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
2179                     }
2180                 }
2181             } else {
2182                 Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: "
2183                         + parser.getName());
2184                 XmlUtils.skipCurrentTag(parser);
2185             }
2186         }
2187     }
2188 
writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates)2189     void writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates)
2190             throws IOException {
2191         if (permissionStates.isEmpty()) {
2192             return;
2193         }
2194 
2195         serializer.startTag(null, TAG_PERMISSIONS);
2196 
2197         for (PermissionState permissionState : permissionStates) {
2198             serializer.startTag(null, TAG_ITEM);
2199             serializer.attribute(null, ATTR_NAME, permissionState.getName());
2200             serializer.attribute(null, ATTR_GRANTED, String.valueOf(permissionState.isGranted()));
2201             serializer.attribute(null, ATTR_FLAGS, Integer.toHexString(permissionState.getFlags()));
2202             serializer.endTag(null, TAG_ITEM);
2203         }
2204 
2205         serializer.endTag(null, TAG_PERMISSIONS);
2206     }
2207 
writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames)2208     void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames)
2209             throws IOException {
2210         if (childPackageNames == null) {
2211             return;
2212         }
2213         final int childCount = childPackageNames.size();
2214         for (int i = 0; i < childCount; i++) {
2215             String childPackageName = childPackageNames.get(i);
2216             serializer.startTag(null, TAG_CHILD_PACKAGE);
2217             serializer.attribute(null, ATTR_NAME, childPackageName);
2218             serializer.endTag(null, TAG_CHILD_PACKAGE);
2219         }
2220     }
2221 
readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)2222     void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)
2223             throws IOException, XmlPullParserException {
2224         int outerDepth = parser.getDepth();
2225         int type;
2226         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2227                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2228             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2229                 continue;
2230             }
2231             String libName = parser.getAttributeValue(null, ATTR_NAME);
2232             String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
2233 
2234             long libVersion = -1;
2235             try {
2236                 libVersion = Long.parseLong(libVersionStr);
2237             } catch (NumberFormatException e) {
2238                 // ignore
2239             }
2240 
2241             if (libName != null && libVersion >= 0) {
2242                 outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
2243                         outPs.usesStaticLibraries, libName);
2244                 outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong(
2245                         outPs.usesStaticLibrariesVersions, libVersion);
2246             }
2247 
2248             XmlUtils.skipCurrentTag(parser);
2249         }
2250     }
2251 
writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries, long[] usesStaticLibraryVersions)2252     void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries,
2253             long[] usesStaticLibraryVersions) throws IOException {
2254         if (ArrayUtils.isEmpty(usesStaticLibraries) || ArrayUtils.isEmpty(usesStaticLibraryVersions)
2255                 || usesStaticLibraries.length != usesStaticLibraryVersions.length) {
2256             return;
2257         }
2258         final int libCount = usesStaticLibraries.length;
2259         for (int i = 0; i < libCount; i++) {
2260             final String libName = usesStaticLibraries[i];
2261             final long libVersion = usesStaticLibraryVersions[i];
2262             serializer.startTag(null, TAG_USES_STATIC_LIB);
2263             serializer.attribute(null, ATTR_NAME, libName);
2264             serializer.attribute(null, ATTR_VERSION, Long.toString(libVersion));
2265             serializer.endTag(null, TAG_USES_STATIC_LIB);
2266         }
2267     }
2268 
2269     // Note: assumed "stopped" field is already cleared in all packages.
2270     // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
readStoppedLPw()2271     void readStoppedLPw() {
2272         FileInputStream str = null;
2273         if (mBackupStoppedPackagesFilename.exists()) {
2274             try {
2275                 str = new FileInputStream(mBackupStoppedPackagesFilename);
2276                 mReadMessages.append("Reading from backup stopped packages file\n");
2277                 PackageManagerService.reportSettingsProblem(Log.INFO,
2278                         "Need to read from backup stopped packages file");
2279                 if (mSettingsFilename.exists()) {
2280                     // If both the backup and normal file exist, we
2281                     // ignore the normal one since it might have been
2282                     // corrupted.
2283                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
2284                             + mStoppedPackagesFilename);
2285                     mStoppedPackagesFilename.delete();
2286                 }
2287             } catch (java.io.IOException e) {
2288                 // We'll try for the normal settings file.
2289             }
2290         }
2291 
2292         try {
2293             if (str == null) {
2294                 if (!mStoppedPackagesFilename.exists()) {
2295                     mReadMessages.append("No stopped packages file found\n");
2296                     PackageManagerService.reportSettingsProblem(Log.INFO,
2297                             "No stopped packages file file; assuming all started");
2298                     // At first boot, make sure no packages are stopped.
2299                     // We usually want to have third party apps initialize
2300                     // in the stopped state, but not at first boot.
2301                     for (PackageSetting pkg : mPackages.values()) {
2302                         pkg.setStopped(false, 0);
2303                         pkg.setNotLaunched(false, 0);
2304                     }
2305                     return;
2306                 }
2307                 str = new FileInputStream(mStoppedPackagesFilename);
2308             }
2309             final XmlPullParser parser = Xml.newPullParser();
2310             parser.setInput(str, null);
2311 
2312             int type;
2313             while ((type=parser.next()) != XmlPullParser.START_TAG
2314                        && type != XmlPullParser.END_DOCUMENT) {
2315                 ;
2316             }
2317 
2318             if (type != XmlPullParser.START_TAG) {
2319                 mReadMessages.append("No start tag found in stopped packages file\n");
2320                 PackageManagerService.reportSettingsProblem(Log.WARN,
2321                         "No start tag found in package manager stopped packages");
2322                 return;
2323             }
2324 
2325             int outerDepth = parser.getDepth();
2326             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2327                    && (type != XmlPullParser.END_TAG
2328                            || parser.getDepth() > outerDepth)) {
2329                 if (type == XmlPullParser.END_TAG
2330                         || type == XmlPullParser.TEXT) {
2331                     continue;
2332                 }
2333 
2334                 String tagName = parser.getName();
2335                 if (tagName.equals(TAG_PACKAGE)) {
2336                     String name = parser.getAttributeValue(null, ATTR_NAME);
2337                     PackageSetting ps = mPackages.get(name);
2338                     if (ps != null) {
2339                         ps.setStopped(true, 0);
2340                         if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
2341                             ps.setNotLaunched(true, 0);
2342                         }
2343                     } else {
2344                         Slog.w(PackageManagerService.TAG,
2345                                 "No package known for stopped package " + name);
2346                     }
2347                     XmlUtils.skipCurrentTag(parser);
2348                 } else {
2349                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
2350                           + parser.getName());
2351                     XmlUtils.skipCurrentTag(parser);
2352                 }
2353             }
2354 
2355             str.close();
2356 
2357         } catch (XmlPullParserException e) {
2358             mReadMessages.append("Error reading: " + e.toString());
2359             PackageManagerService.reportSettingsProblem(Log.ERROR,
2360                     "Error reading stopped packages: " + e);
2361             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2362                     e);
2363 
2364         } catch (java.io.IOException e) {
2365             mReadMessages.append("Error reading: " + e.toString());
2366             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2367             Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2368                     e);
2369 
2370         }
2371     }
2372 
writeLPr()2373     void writeLPr() {
2374         //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
2375 
2376         final long startTime = SystemClock.uptimeMillis();
2377 
2378         // Keep the old settings around until we know the new ones have
2379         // been successfully written.
2380         if (mSettingsFilename.exists()) {
2381             // Presence of backup settings file indicates that we failed
2382             // to persist settings earlier. So preserve the older
2383             // backup for future reference since the current settings
2384             // might have been corrupted.
2385             if (!mBackupSettingsFilename.exists()) {
2386                 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
2387                     Slog.wtf(PackageManagerService.TAG,
2388                             "Unable to backup package manager settings, "
2389                             + " current changes will be lost at reboot");
2390                     return;
2391                 }
2392             } else {
2393                 mSettingsFilename.delete();
2394                 Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
2395             }
2396         }
2397 
2398         mPastSignatures.clear();
2399 
2400         try {
2401             FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
2402             BufferedOutputStream str = new BufferedOutputStream(fstr);
2403 
2404             //XmlSerializer serializer = XmlUtils.serializerInstance();
2405             XmlSerializer serializer = new FastXmlSerializer();
2406             serializer.setOutput(str, StandardCharsets.UTF_8.name());
2407             serializer.startDocument(null, true);
2408             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2409 
2410             serializer.startTag(null, "packages");
2411 
2412             for (int i = 0; i < mVersion.size(); i++) {
2413                 final String volumeUuid = mVersion.keyAt(i);
2414                 final VersionInfo ver = mVersion.valueAt(i);
2415 
2416                 serializer.startTag(null, TAG_VERSION);
2417                 XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid);
2418                 XmlUtils.writeIntAttribute(serializer, ATTR_SDK_VERSION, ver.sdkVersion);
2419                 XmlUtils.writeIntAttribute(serializer, ATTR_DATABASE_VERSION, ver.databaseVersion);
2420                 XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint);
2421                 serializer.endTag(null, TAG_VERSION);
2422             }
2423 
2424             if (mVerifierDeviceIdentity != null) {
2425                 serializer.startTag(null, "verifier");
2426                 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
2427                 serializer.endTag(null, "verifier");
2428             }
2429 
2430             if (mReadExternalStorageEnforced != null) {
2431                 serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
2432                 serializer.attribute(
2433                         null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
2434                 serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
2435             }
2436 
2437             serializer.startTag(null, "permission-trees");
2438             mPermissions.writePermissionTrees(serializer);
2439             serializer.endTag(null, "permission-trees");
2440 
2441             serializer.startTag(null, "permissions");
2442             mPermissions.writePermissions(serializer);
2443             serializer.endTag(null, "permissions");
2444 
2445             for (final PackageSetting pkg : mPackages.values()) {
2446                 writePackageLPr(serializer, pkg);
2447             }
2448 
2449             for (final PackageSetting pkg : mDisabledSysPackages.values()) {
2450                 writeDisabledSysPackageLPr(serializer, pkg);
2451             }
2452 
2453             for (final SharedUserSetting usr : mSharedUsers.values()) {
2454                 serializer.startTag(null, "shared-user");
2455                 serializer.attribute(null, ATTR_NAME, usr.name);
2456                 serializer.attribute(null, "userId",
2457                         Integer.toString(usr.userId));
2458                 usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
2459                 writePermissionsLPr(serializer, usr.getPermissionsState()
2460                         .getInstallPermissionStates());
2461                 serializer.endTag(null, "shared-user");
2462             }
2463 
2464             if (mRenamedPackages.size() > 0) {
2465                 for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
2466                     serializer.startTag(null, "renamed-package");
2467                     serializer.attribute(null, "new", e.getKey());
2468                     serializer.attribute(null, "old", e.getValue());
2469                     serializer.endTag(null, "renamed-package");
2470                 }
2471             }
2472 
2473             final int numIVIs = mRestoredIntentFilterVerifications.size();
2474             if (numIVIs > 0) {
2475                 if (DEBUG_DOMAIN_VERIFICATION) {
2476                     Slog.i(TAG, "Writing restored-ivi entries to packages.xml");
2477                 }
2478                 serializer.startTag(null, "restored-ivi");
2479                 for (int i = 0; i < numIVIs; i++) {
2480                     IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i);
2481                     writeDomainVerificationsLPr(serializer, ivi);
2482                 }
2483                 serializer.endTag(null, "restored-ivi");
2484             } else {
2485                 if (DEBUG_DOMAIN_VERIFICATION) {
2486                     Slog.i(TAG, "  no restored IVI entries to write");
2487                 }
2488             }
2489 
2490             mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
2491 
2492             serializer.endTag(null, "packages");
2493 
2494             serializer.endDocument();
2495 
2496             str.flush();
2497             FileUtils.sync(fstr);
2498             str.close();
2499 
2500             // New settings successfully written, old ones are no longer
2501             // needed.
2502             mBackupSettingsFilename.delete();
2503             FileUtils.setPermissions(mSettingsFilename.toString(),
2504                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
2505                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2506                     -1, -1);
2507 
2508             writeKernelMappingLPr();
2509             writePackageListLPr();
2510             writeAllUsersPackageRestrictionsLPr();
2511             writeAllRuntimePermissionsLPr();
2512             com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
2513                     "package", SystemClock.uptimeMillis() - startTime);
2514             return;
2515 
2516         } catch(java.io.IOException e) {
2517             Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
2518                     + "current changes will be lost at reboot", e);
2519         }
2520         // Clean up partially written files
2521         if (mSettingsFilename.exists()) {
2522             if (!mSettingsFilename.delete()) {
2523                 Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
2524                         + mSettingsFilename);
2525             }
2526         }
2527         //Debug.stopMethodTracing();
2528     }
2529 
writeKernelRemoveUserLPr(int userId)2530     private void writeKernelRemoveUserLPr(int userId) {
2531         if (mKernelMappingFilename == null) return;
2532 
2533         File removeUserIdFile = new File(mKernelMappingFilename, "remove_userid");
2534         if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + userId + " to " + removeUserIdFile
2535                 .getAbsolutePath());
2536         writeIntToFile(removeUserIdFile, userId);
2537     }
2538 
writeKernelMappingLPr()2539     void writeKernelMappingLPr() {
2540         if (mKernelMappingFilename == null) return;
2541 
2542         final String[] known = mKernelMappingFilename.list();
2543         final ArraySet<String> knownSet = new ArraySet<>(known.length);
2544         for (String name : known) {
2545             knownSet.add(name);
2546         }
2547 
2548         for (final PackageSetting ps : mPackages.values()) {
2549             // Package is actively claimed
2550             knownSet.remove(ps.name);
2551             writeKernelMappingLPr(ps);
2552         }
2553 
2554         // Remove any unclaimed mappings
2555         for (int i = 0; i < knownSet.size(); i++) {
2556             final String name = knownSet.valueAt(i);
2557             if (DEBUG_KERNEL) Slog.d(TAG, "Dropping mapping " + name);
2558 
2559             mKernelMapping.remove(name);
2560             new File(mKernelMappingFilename, name).delete();
2561         }
2562     }
2563 
writeKernelMappingLPr(PackageSetting ps)2564     void writeKernelMappingLPr(PackageSetting ps) {
2565         if (mKernelMappingFilename == null || ps == null || ps.name == null) return;
2566 
2567         writeKernelMappingLPr(ps.name, ps.appId, ps.getNotInstalledUserIds());
2568     }
2569 
writeKernelMappingLPr(String name, int appId, int[] excludedUserIds)2570     void writeKernelMappingLPr(String name, int appId, int[] excludedUserIds) {
2571         KernelPackageState cur = mKernelMapping.get(name);
2572         final boolean firstTime = cur == null;
2573         final boolean userIdsChanged = firstTime
2574                 || !Arrays.equals(excludedUserIds, cur.excludedUserIds);
2575 
2576         // Package directory
2577         final File dir = new File(mKernelMappingFilename, name);
2578 
2579         if (firstTime) {
2580             dir.mkdir();
2581             // Create a new mapping state
2582             cur = new KernelPackageState();
2583             mKernelMapping.put(name, cur);
2584         }
2585 
2586         // If mapping is incorrect or non-existent, write the appid file
2587         if (cur.appId != appId) {
2588             final File appIdFile = new File(dir, "appid");
2589             writeIntToFile(appIdFile, appId);
2590             if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + name + " to " + appId);
2591         }
2592 
2593         if (userIdsChanged) {
2594             // Build the exclusion list -- the ids to add to the exclusion list
2595             for (int i = 0; i < excludedUserIds.length; i++) {
2596                 if (cur.excludedUserIds == null || !ArrayUtils.contains(cur.excludedUserIds,
2597                         excludedUserIds[i])) {
2598                     writeIntToFile(new File(dir, "excluded_userids"), excludedUserIds[i]);
2599                     if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + excludedUserIds[i] + " to "
2600                             + name + "/excluded_userids");
2601                 }
2602             }
2603             // Build the inclusion list -- the ids to remove from the exclusion list
2604             if (cur.excludedUserIds != null) {
2605                 for (int i = 0; i < cur.excludedUserIds.length; i++) {
2606                     if (!ArrayUtils.contains(excludedUserIds, cur.excludedUserIds[i])) {
2607                         writeIntToFile(new File(dir, "clear_userid"),
2608                                 cur.excludedUserIds[i]);
2609                         if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + cur.excludedUserIds[i] + " to "
2610                                 + name + "/clear_userid");
2611 
2612                     }
2613                 }
2614             }
2615             cur.excludedUserIds = excludedUserIds;
2616         }
2617     }
2618 
writeIntToFile(File file, int value)2619     private void writeIntToFile(File file, int value) {
2620         try {
2621             FileUtils.bytesToFile(file.getAbsolutePath(),
2622                     Integer.toString(value).getBytes(StandardCharsets.US_ASCII));
2623         } catch (IOException ignored) {
2624             Slog.w(TAG, "Couldn't write " + value + " to " + file.getAbsolutePath());
2625         }
2626     }
2627 
writePackageListLPr()2628     void writePackageListLPr() {
2629         writePackageListLPr(-1);
2630     }
2631 
writePackageListLPr(int creatingUserId)2632     void writePackageListLPr(int creatingUserId) {
2633         String filename = mPackageListFilename.getAbsolutePath();
2634         String ctx = SELinux.fileSelabelLookup(filename);
2635         if (ctx == null) {
2636             Slog.wtf(TAG, "Failed to get SELinux context for " +
2637                 mPackageListFilename.getAbsolutePath());
2638         }
2639 
2640         if (!SELinux.setFSCreateContext(ctx)) {
2641             Slog.wtf(TAG, "Failed to set packages.list SELinux context");
2642         }
2643         try {
2644             writePackageListLPrInternal(creatingUserId);
2645         } finally {
2646             SELinux.setFSCreateContext(null);
2647         }
2648     }
2649 
writePackageListLPrInternal(int creatingUserId)2650     private void writePackageListLPrInternal(int creatingUserId) {
2651         // Only derive GIDs for active users (not dying)
2652         final List<UserInfo> users = getUsers(UserManagerService.getInstance(), true);
2653         int[] userIds = new int[users.size()];
2654         for (int i = 0; i < userIds.length; i++) {
2655             userIds[i] = users.get(i).id;
2656         }
2657         if (creatingUserId != -1) {
2658             userIds = ArrayUtils.appendInt(userIds, creatingUserId);
2659         }
2660 
2661         // Write package list file now, use a JournaledFile.
2662         File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
2663         JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
2664 
2665         final File writeTarget = journal.chooseForWrite();
2666         FileOutputStream fstr;
2667         BufferedWriter writer = null;
2668         try {
2669             fstr = new FileOutputStream(writeTarget);
2670             writer = new BufferedWriter(new OutputStreamWriter(fstr, Charset.defaultCharset()));
2671             FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
2672 
2673             StringBuilder sb = new StringBuilder();
2674             for (final PackageSetting pkg : mPackages.values()) {
2675                 if (pkg.pkg == null || pkg.pkg.applicationInfo == null
2676                         || pkg.pkg.applicationInfo.dataDir == null) {
2677                     if (!"android".equals(pkg.name)) {
2678                         Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
2679                     }
2680                     continue;
2681                 }
2682 
2683                 final ApplicationInfo ai = pkg.pkg.applicationInfo;
2684                 final String dataPath = ai.dataDir;
2685                 final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
2686                 final int[] gids = pkg.getPermissionsState().computeGids(userIds);
2687 
2688                 // Avoid any application that has a space in its path.
2689                 if (dataPath.indexOf(' ') >= 0)
2690                     continue;
2691 
2692                 // we store on each line the following information for now:
2693                 //
2694                 // pkgName    - package name
2695                 // userId     - application-specific user id
2696                 // debugFlag  - 0 or 1 if the package is debuggable.
2697                 // dataPath   - path to package's data path
2698                 // seinfo     - seinfo label for the app (assigned at install time)
2699                 // gids       - supplementary gids this app launches with
2700                 // profileableFromShellFlag  - 0 or 1 if the package is profileable from shell.
2701                 // longVersionCode - integer version of the package.
2702                 //
2703                 // NOTE: We prefer not to expose all ApplicationInfo flags for now.
2704                 //
2705                 // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
2706                 // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
2707                 //   system/core/libpackagelistparser
2708                 //
2709                 sb.setLength(0);
2710                 sb.append(ai.packageName);
2711                 sb.append(" ");
2712                 sb.append(ai.uid);
2713                 sb.append(isDebug ? " 1 " : " 0 ");
2714                 sb.append(dataPath);
2715                 sb.append(" ");
2716                 sb.append(ai.seInfo);
2717                 sb.append(" ");
2718                 if (gids != null && gids.length > 0) {
2719                     sb.append(gids[0]);
2720                     for (int i = 1; i < gids.length; i++) {
2721                         sb.append(",");
2722                         sb.append(gids[i]);
2723                     }
2724                 } else {
2725                     sb.append("none");
2726                 }
2727                 sb.append(" ");
2728                 sb.append(ai.isProfileableByShell() ? "1" : "0");
2729                 sb.append(" ");
2730                 sb.append(String.valueOf(ai.longVersionCode));
2731                 sb.append("\n");
2732                 writer.append(sb);
2733             }
2734             writer.flush();
2735             FileUtils.sync(fstr);
2736             writer.close();
2737             journal.commit();
2738         } catch (Exception e) {
2739             Slog.wtf(TAG, "Failed to write packages.list", e);
2740             IoUtils.closeQuietly(writer);
2741             journal.rollback();
2742         }
2743     }
2744 
writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)2745     void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2746             throws java.io.IOException {
2747         serializer.startTag(null, "updated-package");
2748         serializer.attribute(null, ATTR_NAME, pkg.name);
2749         if (pkg.realName != null) {
2750             serializer.attribute(null, "realName", pkg.realName);
2751         }
2752         serializer.attribute(null, "codePath", pkg.codePathString);
2753         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2754         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2755         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2756         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2757         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2758             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2759         }
2760         if (pkg.legacyNativeLibraryPathString != null) {
2761             serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2762         }
2763         if (pkg.primaryCpuAbiString != null) {
2764            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2765         }
2766         if (pkg.secondaryCpuAbiString != null) {
2767             serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2768         }
2769         if (pkg.cpuAbiOverrideString != null) {
2770             serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2771         }
2772 
2773         if (pkg.sharedUser == null) {
2774             serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2775         } else {
2776             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2777         }
2778 
2779         if (pkg.parentPackageName != null) {
2780             serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2781         }
2782 
2783         writeChildPackagesLPw(serializer, pkg.childPackageNames);
2784 
2785         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
2786 
2787         // If this is a shared user, the permissions will be written there.
2788         if (pkg.sharedUser == null) {
2789             writePermissionsLPr(serializer, pkg.getPermissionsState()
2790                     .getInstallPermissionStates());
2791         }
2792 
2793         serializer.endTag(null, "updated-package");
2794     }
2795 
writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)2796     void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2797             throws java.io.IOException {
2798         serializer.startTag(null, "package");
2799         serializer.attribute(null, ATTR_NAME, pkg.name);
2800         if (pkg.realName != null) {
2801             serializer.attribute(null, "realName", pkg.realName);
2802         }
2803         serializer.attribute(null, "codePath", pkg.codePathString);
2804         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2805             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2806         }
2807 
2808         if (pkg.legacyNativeLibraryPathString != null) {
2809             serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2810         }
2811         if (pkg.primaryCpuAbiString != null) {
2812             serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2813         }
2814         if (pkg.secondaryCpuAbiString != null) {
2815             serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2816         }
2817         if (pkg.cpuAbiOverrideString != null) {
2818             serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2819         }
2820 
2821         serializer.attribute(null, "publicFlags", Integer.toString(pkg.pkgFlags));
2822         serializer.attribute(null, "privateFlags", Integer.toString(pkg.pkgPrivateFlags));
2823         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2824         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2825         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2826         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2827         if (pkg.sharedUser == null) {
2828             serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2829         } else {
2830             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2831         }
2832         if (pkg.uidError) {
2833             serializer.attribute(null, "uidError", "true");
2834         }
2835         if (pkg.installerPackageName != null) {
2836             serializer.attribute(null, "installer", pkg.installerPackageName);
2837         }
2838         if (pkg.isOrphaned) {
2839             serializer.attribute(null, "isOrphaned", "true");
2840         }
2841         if (pkg.volumeUuid != null) {
2842             serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
2843         }
2844         if (pkg.categoryHint != ApplicationInfo.CATEGORY_UNDEFINED) {
2845             serializer.attribute(null, "categoryHint",
2846                     Integer.toString(pkg.categoryHint));
2847         }
2848         if (pkg.parentPackageName != null) {
2849             serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2850         }
2851         if (pkg.updateAvailable) {
2852             serializer.attribute(null, "updateAvailable", "true");
2853         }
2854 
2855         writeChildPackagesLPw(serializer, pkg.childPackageNames);
2856 
2857         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
2858 
2859         pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
2860 
2861         writePermissionsLPr(serializer, pkg.getPermissionsState()
2862                     .getInstallPermissionStates());
2863 
2864         writeSigningKeySetLPr(serializer, pkg.keySetData);
2865         writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
2866         writeKeySetAliasesLPr(serializer, pkg.keySetData);
2867         writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
2868 
2869         serializer.endTag(null, "package");
2870     }
2871 
writeSigningKeySetLPr(XmlSerializer serializer, PackageKeySetData data)2872     void writeSigningKeySetLPr(XmlSerializer serializer,
2873             PackageKeySetData data) throws IOException {
2874         serializer.startTag(null, "proper-signing-keyset");
2875         serializer.attribute(null, "identifier",
2876                 Long.toString(data.getProperSigningKeySet()));
2877         serializer.endTag(null, "proper-signing-keyset");
2878     }
2879 
writeUpgradeKeySetsLPr(XmlSerializer serializer, PackageKeySetData data)2880     void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2881             PackageKeySetData data) throws IOException {
2882         if (data.isUsingUpgradeKeySets()) {
2883             for (long id : data.getUpgradeKeySets()) {
2884                 serializer.startTag(null, "upgrade-keyset");
2885                 serializer.attribute(null, "identifier", Long.toString(id));
2886                 serializer.endTag(null, "upgrade-keyset");
2887             }
2888         }
2889     }
2890 
writeKeySetAliasesLPr(XmlSerializer serializer, PackageKeySetData data)2891     void writeKeySetAliasesLPr(XmlSerializer serializer,
2892             PackageKeySetData data) throws IOException {
2893         for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2894             serializer.startTag(null, "defined-keyset");
2895             serializer.attribute(null, "alias", e.getKey());
2896             serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2897             serializer.endTag(null, "defined-keyset");
2898         }
2899     }
2900 
writePermissionLPr(XmlSerializer serializer, BasePermission bp)2901     void writePermissionLPr(XmlSerializer serializer, BasePermission bp) throws IOException {
2902         bp.writeLPr(serializer);
2903     }
2904 
readLPw(@onNull List<UserInfo> users)2905     boolean readLPw(@NonNull List<UserInfo> users) {
2906         FileInputStream str = null;
2907         if (mBackupSettingsFilename.exists()) {
2908             try {
2909                 str = new FileInputStream(mBackupSettingsFilename);
2910                 mReadMessages.append("Reading from backup settings file\n");
2911                 PackageManagerService.reportSettingsProblem(Log.INFO,
2912                         "Need to read from backup settings file");
2913                 if (mSettingsFilename.exists()) {
2914                     // If both the backup and settings file exist, we
2915                     // ignore the settings since it might have been
2916                     // corrupted.
2917                     Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2918                             + mSettingsFilename);
2919                     mSettingsFilename.delete();
2920                 }
2921             } catch (java.io.IOException e) {
2922                 // We'll try for the normal settings file.
2923             }
2924         }
2925 
2926         mPendingPackages.clear();
2927         mPastSignatures.clear();
2928         mKeySetRefs.clear();
2929         mInstallerPackages.clear();
2930 
2931         try {
2932             if (str == null) {
2933                 if (!mSettingsFilename.exists()) {
2934                     mReadMessages.append("No settings file found\n");
2935                     PackageManagerService.reportSettingsProblem(Log.INFO,
2936                             "No settings file; creating initial state");
2937                     // It's enough to just touch version details to create them
2938                     // with default values
2939                     findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
2940                     findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
2941                     return false;
2942                 }
2943                 str = new FileInputStream(mSettingsFilename);
2944             }
2945             XmlPullParser parser = Xml.newPullParser();
2946             parser.setInput(str, StandardCharsets.UTF_8.name());
2947 
2948             int type;
2949             while ((type = parser.next()) != XmlPullParser.START_TAG
2950                     && type != XmlPullParser.END_DOCUMENT) {
2951                 ;
2952             }
2953 
2954             if (type != XmlPullParser.START_TAG) {
2955                 mReadMessages.append("No start tag found in settings file\n");
2956                 PackageManagerService.reportSettingsProblem(Log.WARN,
2957                         "No start tag found in package manager settings");
2958                 Slog.wtf(PackageManagerService.TAG,
2959                         "No start tag found in package manager settings");
2960                 return false;
2961             }
2962 
2963             int outerDepth = parser.getDepth();
2964             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2965                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2966                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2967                     continue;
2968                 }
2969 
2970                 String tagName = parser.getName();
2971                 if (tagName.equals("package")) {
2972                     readPackageLPw(parser);
2973                 } else if (tagName.equals("permissions")) {
2974                     mPermissions.readPermissions(parser);
2975                 } else if (tagName.equals("permission-trees")) {
2976                     mPermissions.readPermissionTrees(parser);
2977                 } else if (tagName.equals("shared-user")) {
2978                     readSharedUserLPw(parser);
2979                 } else if (tagName.equals("preferred-packages")) {
2980                     // no longer used.
2981                 } else if (tagName.equals("preferred-activities")) {
2982                     // Upgrading from old single-user implementation;
2983                     // these are the preferred activities for user 0.
2984                     readPreferredActivitiesLPw(parser, 0);
2985                 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2986                     // TODO: check whether this is okay! as it is very
2987                     // similar to how preferred-activities are treated
2988                     readPersistentPreferredActivitiesLPw(parser, 0);
2989                 } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2990                     // TODO: check whether this is okay! as it is very
2991                     // similar to how preferred-activities are treated
2992                     readCrossProfileIntentFiltersLPw(parser, 0);
2993                 } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
2994                     readDefaultAppsLPw(parser, 0);
2995                 } else if (tagName.equals("updated-package")) {
2996                     readDisabledSysPackageLPw(parser);
2997                 } else if (tagName.equals("renamed-package")) {
2998                     String nname = parser.getAttributeValue(null, "new");
2999                     String oname = parser.getAttributeValue(null, "old");
3000                     if (nname != null && oname != null) {
3001                         mRenamedPackages.put(nname, oname);
3002                     }
3003                 } else if (tagName.equals("restored-ivi")) {
3004                     readRestoredIntentFilterVerifications(parser);
3005                 } else if (tagName.equals("last-platform-version")) {
3006                     // Upgrade from older XML schema
3007                     final VersionInfo internal = findOrCreateVersion(
3008                             StorageManager.UUID_PRIVATE_INTERNAL);
3009                     final VersionInfo external = findOrCreateVersion(
3010                             StorageManager.UUID_PRIMARY_PHYSICAL);
3011 
3012                     internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
3013                     external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
3014                     internal.fingerprint = external.fingerprint =
3015                             XmlUtils.readStringAttribute(parser, "fingerprint");
3016 
3017                 } else if (tagName.equals("database-version")) {
3018                     // Upgrade from older XML schema
3019                     final VersionInfo internal = findOrCreateVersion(
3020                             StorageManager.UUID_PRIVATE_INTERNAL);
3021                     final VersionInfo external = findOrCreateVersion(
3022                             StorageManager.UUID_PRIMARY_PHYSICAL);
3023 
3024                     internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
3025                     external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);
3026 
3027                 } else if (tagName.equals("verifier")) {
3028                     final String deviceIdentity = parser.getAttributeValue(null, "device");
3029                     try {
3030                         mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
3031                     } catch (IllegalArgumentException e) {
3032                         Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
3033                                 + e.getMessage());
3034                     }
3035                 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
3036                     final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
3037                     mReadExternalStorageEnforced =
3038                             "1".equals(enforcement) ? Boolean.TRUE : Boolean.FALSE;
3039                 } else if (tagName.equals("keyset-settings")) {
3040                     mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
3041                 } else if (TAG_VERSION.equals(tagName)) {
3042                     final String volumeUuid = XmlUtils.readStringAttribute(parser,
3043                             ATTR_VOLUME_UUID);
3044                     final VersionInfo ver = findOrCreateVersion(volumeUuid);
3045                     ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
3046                     ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_DATABASE_VERSION);
3047                     ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
3048                 } else {
3049                     Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
3050                             + parser.getName());
3051                     XmlUtils.skipCurrentTag(parser);
3052                 }
3053             }
3054 
3055             str.close();
3056 
3057         } catch (XmlPullParserException e) {
3058             mReadMessages.append("Error reading: " + e.toString());
3059             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
3060             Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
3061 
3062         } catch (java.io.IOException e) {
3063             mReadMessages.append("Error reading: " + e.toString());
3064             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
3065             Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
3066         }
3067 
3068         // If the build is setup to drop runtime permissions
3069         // on update drop the files before loading them.
3070         if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
3071             final VersionInfo internal = getInternalVersion();
3072             if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
3073                 for (UserInfo user : users) {
3074                     mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
3075                 }
3076             }
3077         }
3078 
3079         final int N = mPendingPackages.size();
3080 
3081         for (int i = 0; i < N; i++) {
3082             final PackageSetting p = mPendingPackages.get(i);
3083             final int sharedUserId = p.getSharedUserId();
3084             final Object idObj = getSettingLPr(sharedUserId);
3085             if (idObj instanceof SharedUserSetting) {
3086                 final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
3087                 p.sharedUser = sharedUser;
3088                 p.appId = sharedUser.userId;
3089                 addPackageSettingLPw(p, sharedUser);
3090             } else if (idObj != null) {
3091                 String msg = "Bad package setting: package " + p.name + " has shared uid "
3092                         + sharedUserId + " that is not a shared uid\n";
3093                 mReadMessages.append(msg);
3094                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
3095             } else {
3096                 String msg = "Bad package setting: package " + p.name + " has shared uid "
3097                         + sharedUserId + " that is not defined\n";
3098                 mReadMessages.append(msg);
3099                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
3100             }
3101         }
3102         mPendingPackages.clear();
3103 
3104         if (mBackupStoppedPackagesFilename.exists()
3105                 || mStoppedPackagesFilename.exists()) {
3106             // Read old file
3107             readStoppedLPw();
3108             mBackupStoppedPackagesFilename.delete();
3109             mStoppedPackagesFilename.delete();
3110             // Migrate to new file format
3111             writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
3112         } else {
3113             for (UserInfo user : users) {
3114                 readPackageRestrictionsLPr(user.id);
3115             }
3116         }
3117 
3118         for (UserInfo user : users) {
3119             mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
3120         }
3121 
3122         /*
3123          * Make sure all the updated system packages have their shared users
3124          * associated with them.
3125          */
3126         final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
3127         while (disabledIt.hasNext()) {
3128             final PackageSetting disabledPs = disabledIt.next();
3129             final Object id = getSettingLPr(disabledPs.appId);
3130             if (id != null && id instanceof SharedUserSetting) {
3131                 disabledPs.sharedUser = (SharedUserSetting) id;
3132             }
3133         }
3134 
3135         mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
3136                 + mSharedUsers.size() + " shared uids\n");
3137 
3138         writeKernelMappingLPr();
3139 
3140         return true;
3141     }
3142 
readPermissionStateForUserSyncLPr(@serIdInt int userId)3143     void readPermissionStateForUserSyncLPr(@UserIdInt int userId) {
3144         mRuntimePermissionsPersistence.readStateForUserSyncLPr(userId);
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(
3345                         intent, intent.getType(), flags, Binder.getCallingUid(), 0);
3346         if (PackageManagerService.DEBUG_PREFERRED) {
3347             Log.d(TAG, "Queried " + intent + " results: " + ri);
3348         }
3349         int systemMatch = 0;
3350         int thirdPartyMatch = 0;
3351         final int numMatches = (ri == null ? 0 : ri.size());
3352         if (numMatches <= 1) {
3353             Slog.w(TAG, "No potential matches found for " + intent
3354                     + " while setting preferred " + cn.flattenToShortString());
3355             return;
3356         }
3357         boolean haveAct = false;
3358         ComponentName haveNonSys = null;
3359         ComponentName[] set = new ComponentName[ri.size()];
3360         for (int i = 0; i < numMatches; i++) {
3361             final ActivityInfo ai = ri.get(i).activityInfo;
3362             set[i] = new ComponentName(ai.packageName, ai.name);
3363             if ((ai.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
3364                 if (ri.get(i).match >= thirdPartyMatch) {
3365                     // Keep track of the best match we find of all third
3366                     // party apps, for use later to determine if we actually
3367                     // want to set a preferred app for this intent.
3368                     if (PackageManagerService.DEBUG_PREFERRED) {
3369                         Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": non-system!");
3370                     }
3371                     haveNonSys = set[i];
3372                     break;
3373                 }
3374             } else if (cn.getPackageName().equals(ai.packageName)
3375                     && cn.getClassName().equals(ai.name)) {
3376                 if (PackageManagerService.DEBUG_PREFERRED) {
3377                     Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": default!");
3378                 }
3379                 haveAct = true;
3380                 systemMatch = ri.get(i).match;
3381             } else {
3382                 if (PackageManagerService.DEBUG_PREFERRED) {
3383                     Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": skipped");
3384                 }
3385             }
3386         }
3387         if (haveNonSys != null && thirdPartyMatch < systemMatch) {
3388             // If we have a matching third party app, but its match is not as
3389             // good as the built-in system app, then we don't want to actually
3390             // consider it a match because presumably the built-in app is still
3391             // the thing we want users to see by default.
3392             haveNonSys = null;
3393         }
3394         if (haveAct && haveNonSys == null) {
3395             IntentFilter filter = new IntentFilter();
3396             if (intent.getAction() != null) {
3397                 filter.addAction(intent.getAction());
3398             }
3399             if (intent.getCategories() != null) {
3400                 for (String cat : intent.getCategories()) {
3401                     filter.addCategory(cat);
3402                 }
3403             }
3404             if ((flags & MATCH_DEFAULT_ONLY) != 0) {
3405                 filter.addCategory(Intent.CATEGORY_DEFAULT);
3406             }
3407             if (scheme != null) {
3408                 filter.addDataScheme(scheme);
3409             }
3410             if (ssp != null) {
3411                 filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
3412             }
3413             if (auth != null) {
3414                 filter.addDataAuthority(auth);
3415             }
3416             if (path != null) {
3417                 filter.addDataPath(path);
3418             }
3419             if (intent.getType() != null) {
3420                 try {
3421                     filter.addDataType(intent.getType());
3422                 } catch (IntentFilter.MalformedMimeTypeException ex) {
3423                     Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
3424                 }
3425             }
3426             PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
3427             editPreferredActivitiesLPw(userId).addFilter(pa);
3428         } else if (haveNonSys == null) {
3429             StringBuilder sb = new StringBuilder();
3430             sb.append("No component ");
3431             sb.append(cn.flattenToShortString());
3432             sb.append(" found setting preferred ");
3433             sb.append(intent);
3434             sb.append("; possible matches are ");
3435             for (int i = 0; i < set.length; i++) {
3436                 if (i > 0) sb.append(", ");
3437                 sb.append(set[i].flattenToShortString());
3438             }
3439             Slog.w(TAG, sb.toString());
3440         } else {
3441             Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
3442                     + haveNonSys.flattenToShortString());
3443         }
3444     }
3445 
readDefaultPreferredActivitiesLPw(XmlPullParser parser, int userId)3446     private void readDefaultPreferredActivitiesLPw(XmlPullParser parser, int userId)
3447             throws XmlPullParserException, IOException {
3448         final PackageManagerInternal pmInternal =
3449                 LocalServices.getService(PackageManagerInternal.class);
3450         int outerDepth = parser.getDepth();
3451         int type;
3452         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3453                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3454             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3455                 continue;
3456             }
3457 
3458             String tagName = parser.getName();
3459             if (tagName.equals(TAG_ITEM)) {
3460                 PreferredActivity tmpPa = new PreferredActivity(parser);
3461                 if (tmpPa.mPref.getParseError() == null) {
3462                     applyDefaultPreferredActivityLPw(
3463                             pmInternal, tmpPa, tmpPa.mPref.mComponent, userId);
3464                 } else {
3465                     PackageManagerService.reportSettingsProblem(Log.WARN,
3466                             "Error in package manager settings: <preferred-activity> "
3467                                     + tmpPa.mPref.getParseError() + " at "
3468                                     + parser.getPositionDescription());
3469                 }
3470             } else {
3471                 PackageManagerService.reportSettingsProblem(Log.WARN,
3472                         "Unknown element under <preferred-activities>: " + parser.getName());
3473                 XmlUtils.skipCurrentTag(parser);
3474             }
3475         }
3476     }
3477 
readDisabledSysPackageLPw(XmlPullParser parser)3478     private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
3479             IOException {
3480         String name = parser.getAttributeValue(null, ATTR_NAME);
3481         String realName = parser.getAttributeValue(null, "realName");
3482         String codePathStr = parser.getAttributeValue(null, "codePath");
3483         String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3484 
3485         String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
3486         String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3487 
3488         String parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3489 
3490         String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
3491         String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
3492         String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
3493 
3494         if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
3495             primaryCpuAbiStr = legacyCpuAbiStr;
3496         }
3497 
3498         if (resourcePathStr == null) {
3499             resourcePathStr = codePathStr;
3500         }
3501         String version = parser.getAttributeValue(null, "version");
3502         long versionCode = 0;
3503         if (version != null) {
3504             try {
3505                 versionCode = Long.parseLong(version);
3506             } catch (NumberFormatException e) {
3507             }
3508         }
3509 
3510         int pkgFlags = 0;
3511         int pkgPrivateFlags = 0;
3512         pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3513         if (codePathStr.contains("/priv-app/")) {
3514             pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3515         }
3516         PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
3517                 new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
3518                 secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
3519                 parentPackageName, null /*childPackageNames*/, 0 /*sharedUserId*/, null, null);
3520         String timeStampStr = parser.getAttributeValue(null, "ft");
3521         if (timeStampStr != null) {
3522             try {
3523                 long timeStamp = Long.parseLong(timeStampStr, 16);
3524                 ps.setTimeStamp(timeStamp);
3525             } catch (NumberFormatException e) {
3526             }
3527         } else {
3528             timeStampStr = parser.getAttributeValue(null, "ts");
3529             if (timeStampStr != null) {
3530                 try {
3531                     long timeStamp = Long.parseLong(timeStampStr);
3532                     ps.setTimeStamp(timeStamp);
3533                 } catch (NumberFormatException e) {
3534                 }
3535             }
3536         }
3537         timeStampStr = parser.getAttributeValue(null, "it");
3538         if (timeStampStr != null) {
3539             try {
3540                 ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
3541             } catch (NumberFormatException e) {
3542             }
3543         }
3544         timeStampStr = parser.getAttributeValue(null, "ut");
3545         if (timeStampStr != null) {
3546             try {
3547                 ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
3548             } catch (NumberFormatException e) {
3549             }
3550         }
3551         String idStr = parser.getAttributeValue(null, "userId");
3552         ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
3553         if (ps.appId <= 0) {
3554             String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3555             ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3556         }
3557 
3558         int outerDepth = parser.getDepth();
3559         int type;
3560         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3561                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3562             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3563                 continue;
3564             }
3565 
3566             if (parser.getName().equals(TAG_PERMISSIONS)) {
3567                 readInstallPermissionsLPr(parser, ps.getPermissionsState());
3568             } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) {
3569                 String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3570                 if (ps.childPackageNames == null) {
3571                     ps.childPackageNames = new ArrayList<>();
3572                 }
3573                 ps.childPackageNames.add(childPackageName);
3574             } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) {
3575                 readUsesStaticLibLPw(parser, ps);
3576             } else {
3577                 PackageManagerService.reportSettingsProblem(Log.WARN,
3578                         "Unknown element under <updated-package>: " + parser.getName());
3579                 XmlUtils.skipCurrentTag(parser);
3580             }
3581         }
3582 
3583         mDisabledSysPackages.put(name, ps);
3584     }
3585 
3586     private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27;
3587     private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
3588     private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
3589 
readPackageLPw(XmlPullParser parser)3590     private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
3591         String name = null;
3592         String realName = null;
3593         String idStr = null;
3594         String sharedIdStr = null;
3595         String codePathStr = null;
3596         String resourcePathStr = null;
3597         String legacyCpuAbiString = null;
3598         String legacyNativeLibraryPathStr = null;
3599         String primaryCpuAbiString = null;
3600         String secondaryCpuAbiString = null;
3601         String cpuAbiOverrideString = null;
3602         String systemStr = null;
3603         String installerPackageName = null;
3604         String isOrphaned = null;
3605         String volumeUuid = null;
3606         String categoryHintString = null;
3607         String updateAvailable = null;
3608         int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
3609         String uidError = null;
3610         int pkgFlags = 0;
3611         int pkgPrivateFlags = 0;
3612         long timeStamp = 0;
3613         long firstInstallTime = 0;
3614         long lastUpdateTime = 0;
3615         PackageSetting packageSetting = null;
3616         String version = null;
3617         long versionCode = 0;
3618         String parentPackageName;
3619         try {
3620             name = parser.getAttributeValue(null, ATTR_NAME);
3621             realName = parser.getAttributeValue(null, "realName");
3622             idStr = parser.getAttributeValue(null, "userId");
3623             uidError = parser.getAttributeValue(null, "uidError");
3624             sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3625             codePathStr = parser.getAttributeValue(null, "codePath");
3626             resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3627 
3628             legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
3629 
3630             parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3631 
3632             legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3633             primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
3634             secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
3635             cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
3636             updateAvailable = parser.getAttributeValue(null, "updateAvailable");
3637 
3638             if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
3639                 primaryCpuAbiString = legacyCpuAbiString;
3640             }
3641 
3642             version = parser.getAttributeValue(null, "version");
3643             if (version != null) {
3644                 try {
3645                     versionCode = Long.parseLong(version);
3646                 } catch (NumberFormatException e) {
3647                 }
3648             }
3649             installerPackageName = parser.getAttributeValue(null, "installer");
3650             isOrphaned = parser.getAttributeValue(null, "isOrphaned");
3651             volumeUuid = parser.getAttributeValue(null, "volumeUuid");
3652             categoryHintString = parser.getAttributeValue(null, "categoryHint");
3653             if (categoryHintString != null) {
3654                 try {
3655                     categoryHint = Integer.parseInt(categoryHintString);
3656                 } catch (NumberFormatException e) {
3657                 }
3658             }
3659 
3660             systemStr = parser.getAttributeValue(null, "publicFlags");
3661             if (systemStr != null) {
3662                 try {
3663                     pkgFlags = Integer.parseInt(systemStr);
3664                 } catch (NumberFormatException e) {
3665                 }
3666                 systemStr = parser.getAttributeValue(null, "privateFlags");
3667                 if (systemStr != null) {
3668                     try {
3669                         pkgPrivateFlags = Integer.parseInt(systemStr);
3670                     } catch (NumberFormatException e) {
3671                     }
3672                 }
3673             } else {
3674                 // Pre-M -- both public and private flags were stored in one "flags" field.
3675                 systemStr = parser.getAttributeValue(null, "flags");
3676                 if (systemStr != null) {
3677                     try {
3678                         pkgFlags = Integer.parseInt(systemStr);
3679                     } catch (NumberFormatException e) {
3680                     }
3681                     if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) {
3682                         pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
3683                     }
3684                     if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) {
3685                         pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
3686                     }
3687                     if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) {
3688                         pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3689                     }
3690                     pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN
3691                             | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE
3692                             | PRE_M_APP_INFO_FLAG_PRIVILEGED);
3693                 } else {
3694                     // For backward compatibility
3695                     systemStr = parser.getAttributeValue(null, "system");
3696                     if (systemStr != null) {
3697                         pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
3698                                 : 0;
3699                     } else {
3700                         // Old settings that don't specify system... just treat
3701                         // them as system, good enough.
3702                         pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3703                     }
3704                 }
3705             }
3706             String timeStampStr = parser.getAttributeValue(null, "ft");
3707             if (timeStampStr != null) {
3708                 try {
3709                     timeStamp = Long.parseLong(timeStampStr, 16);
3710                 } catch (NumberFormatException e) {
3711                 }
3712             } else {
3713                 timeStampStr = parser.getAttributeValue(null, "ts");
3714                 if (timeStampStr != null) {
3715                     try {
3716                         timeStamp = Long.parseLong(timeStampStr);
3717                     } catch (NumberFormatException e) {
3718                     }
3719                 }
3720             }
3721             timeStampStr = parser.getAttributeValue(null, "it");
3722             if (timeStampStr != null) {
3723                 try {
3724                     firstInstallTime = Long.parseLong(timeStampStr, 16);
3725                 } catch (NumberFormatException e) {
3726                 }
3727             }
3728             timeStampStr = parser.getAttributeValue(null, "ut");
3729             if (timeStampStr != null) {
3730                 try {
3731                     lastUpdateTime = Long.parseLong(timeStampStr, 16);
3732                 } catch (NumberFormatException e) {
3733                 }
3734             }
3735             if (PackageManagerService.DEBUG_SETTINGS)
3736                 Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
3737                         + " sharedUserId=" + sharedIdStr);
3738             final int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3739             final int sharedUserId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3740             if (resourcePathStr == null) {
3741                 resourcePathStr = codePathStr;
3742             }
3743             if (realName != null) {
3744                 realName = realName.intern();
3745             }
3746             if (name == null) {
3747                 PackageManagerService.reportSettingsProblem(Log.WARN,
3748                         "Error in package manager settings: <package> has no name at "
3749                                 + parser.getPositionDescription());
3750             } else if (codePathStr == null) {
3751                 PackageManagerService.reportSettingsProblem(Log.WARN,
3752                         "Error in package manager settings: <package> has no codePath at "
3753                                 + parser.getPositionDescription());
3754             } else if (userId > 0) {
3755                 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
3756                         new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
3757                         secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
3758                         pkgPrivateFlags, parentPackageName, null /*childPackageNames*/,
3759                         null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/);
3760                 if (PackageManagerService.DEBUG_SETTINGS)
3761                     Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
3762                             + userId + " pkg=" + packageSetting);
3763                 if (packageSetting == null) {
3764                     PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
3765                             + userId + " while parsing settings at "
3766                             + parser.getPositionDescription());
3767                 } else {
3768                     packageSetting.setTimeStamp(timeStamp);
3769                     packageSetting.firstInstallTime = firstInstallTime;
3770                     packageSetting.lastUpdateTime = lastUpdateTime;
3771                 }
3772             } else if (sharedIdStr != null) {
3773                 if (sharedUserId > 0) {
3774                     packageSetting = new PackageSetting(name.intern(), realName, new File(
3775                             codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
3776                             primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
3777                             versionCode, pkgFlags, pkgPrivateFlags, parentPackageName,
3778                             null /*childPackageNames*/, sharedUserId,
3779                             null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/);
3780                     packageSetting.setTimeStamp(timeStamp);
3781                     packageSetting.firstInstallTime = firstInstallTime;
3782                     packageSetting.lastUpdateTime = lastUpdateTime;
3783                     mPendingPackages.add(packageSetting);
3784                     if (PackageManagerService.DEBUG_SETTINGS)
3785                         Log.i(PackageManagerService.TAG, "Reading package " + name
3786                                 + ": sharedUserId=" + sharedUserId + " pkg=" + packageSetting);
3787                 } else {
3788                     PackageManagerService.reportSettingsProblem(Log.WARN,
3789                             "Error in package manager settings: package " + name
3790                                     + " has bad sharedId " + sharedIdStr + " at "
3791                                     + parser.getPositionDescription());
3792                 }
3793             } else {
3794                 PackageManagerService.reportSettingsProblem(Log.WARN,
3795                         "Error in package manager settings: package " + name + " has bad userId "
3796                                 + idStr + " at " + parser.getPositionDescription());
3797             }
3798         } catch (NumberFormatException e) {
3799             PackageManagerService.reportSettingsProblem(Log.WARN,
3800                     "Error in package manager settings: package " + name + " has bad userId "
3801                             + idStr + " at " + parser.getPositionDescription());
3802         }
3803         if (packageSetting != null) {
3804             packageSetting.uidError = "true".equals(uidError);
3805             packageSetting.installerPackageName = installerPackageName;
3806             packageSetting.isOrphaned = "true".equals(isOrphaned);
3807             packageSetting.volumeUuid = volumeUuid;
3808             packageSetting.categoryHint = categoryHint;
3809             packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
3810             packageSetting.primaryCpuAbiString = primaryCpuAbiString;
3811             packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
3812             packageSetting.updateAvailable = "true".equals(updateAvailable);
3813             // Handle legacy string here for single-user mode
3814             final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
3815             if (enabledStr != null) {
3816                 try {
3817                     packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
3818                 } catch (NumberFormatException e) {
3819                     if (enabledStr.equalsIgnoreCase("true")) {
3820                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
3821                     } else if (enabledStr.equalsIgnoreCase("false")) {
3822                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
3823                     } else if (enabledStr.equalsIgnoreCase("default")) {
3824                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3825                     } else {
3826                         PackageManagerService.reportSettingsProblem(Log.WARN,
3827                                 "Error in package manager settings: package " + name
3828                                         + " has bad enabled value: " + idStr + " at "
3829                                         + parser.getPositionDescription());
3830                     }
3831                 }
3832             } else {
3833                 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3834             }
3835 
3836             if (installerPackageName != null) {
3837                 mInstallerPackages.add(installerPackageName);
3838             }
3839 
3840             int outerDepth = parser.getDepth();
3841             int type;
3842             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3843                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3844                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3845                     continue;
3846                 }
3847 
3848                 String tagName = parser.getName();
3849                 // Legacy
3850                 if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
3851                     readDisabledComponentsLPw(packageSetting, parser, 0);
3852                 } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
3853                     readEnabledComponentsLPw(packageSetting, parser, 0);
3854                 } else if (tagName.equals("sigs")) {
3855                     packageSetting.signatures.readXml(parser, mPastSignatures);
3856                 } else if (tagName.equals(TAG_PERMISSIONS)) {
3857                     readInstallPermissionsLPr(parser,
3858                             packageSetting.getPermissionsState());
3859                     packageSetting.installPermissionsFixed = true;
3860                 } else if (tagName.equals("proper-signing-keyset")) {
3861                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3862                     Integer refCt = mKeySetRefs.get(id);
3863                     if (refCt != null) {
3864                         mKeySetRefs.put(id, refCt + 1);
3865                     } else {
3866                         mKeySetRefs.put(id, 1);
3867                     }
3868                     packageSetting.keySetData.setProperSigningKeySet(id);
3869                 } else if (tagName.equals("signing-keyset")) {
3870                     // from v1 of keysetmanagerservice - no longer used
3871                 } else if (tagName.equals("upgrade-keyset")) {
3872                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3873                     packageSetting.keySetData.addUpgradeKeySetById(id);
3874                 } else if (tagName.equals("defined-keyset")) {
3875                     long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3876                     String alias = parser.getAttributeValue(null, "alias");
3877                     Integer refCt = mKeySetRefs.get(id);
3878                     if (refCt != null) {
3879                         mKeySetRefs.put(id, refCt + 1);
3880                     } else {
3881                         mKeySetRefs.put(id, 1);
3882                     }
3883                     packageSetting.keySetData.addDefinedKeySet(id, alias);
3884                 } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
3885                     readDomainVerificationLPw(parser, packageSetting);
3886                 } else if (tagName.equals(TAG_CHILD_PACKAGE)) {
3887                     String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3888                     if (packageSetting.childPackageNames == null) {
3889                         packageSetting.childPackageNames = new ArrayList<>();
3890                     }
3891                     packageSetting.childPackageNames.add(childPackageName);
3892                 } else {
3893                     PackageManagerService.reportSettingsProblem(Log.WARN,
3894                             "Unknown element under <package>: " + parser.getName());
3895                     XmlUtils.skipCurrentTag(parser);
3896                 }
3897             }
3898         } else {
3899             XmlUtils.skipCurrentTag(parser);
3900         }
3901     }
3902 
readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, int userId)3903     private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3904             int userId) throws IOException, XmlPullParserException {
3905         int outerDepth = parser.getDepth();
3906         int type;
3907         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3908                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3909             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3910                 continue;
3911             }
3912 
3913             String tagName = parser.getName();
3914             if (tagName.equals(TAG_ITEM)) {
3915                 String name = parser.getAttributeValue(null, ATTR_NAME);
3916                 if (name != null) {
3917                     packageSetting.addDisabledComponent(name.intern(), userId);
3918                 } else {
3919                     PackageManagerService.reportSettingsProblem(Log.WARN,
3920                             "Error in package manager settings: <disabled-components> has"
3921                                     + " no name at " + parser.getPositionDescription());
3922                 }
3923             } else {
3924                 PackageManagerService.reportSettingsProblem(Log.WARN,
3925                         "Unknown element under <disabled-components>: " + parser.getName());
3926             }
3927             XmlUtils.skipCurrentTag(parser);
3928         }
3929     }
3930 
readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser, int userId)3931     private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3932             int userId) throws IOException, XmlPullParserException {
3933         int outerDepth = parser.getDepth();
3934         int type;
3935         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3936                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3937             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3938                 continue;
3939             }
3940 
3941             String tagName = parser.getName();
3942             if (tagName.equals(TAG_ITEM)) {
3943                 String name = parser.getAttributeValue(null, ATTR_NAME);
3944                 if (name != null) {
3945                     packageSetting.addEnabledComponent(name.intern(), userId);
3946                 } else {
3947                     PackageManagerService.reportSettingsProblem(Log.WARN,
3948                             "Error in package manager settings: <enabled-components> has"
3949                                     + " no name at " + parser.getPositionDescription());
3950                 }
3951             } else {
3952                 PackageManagerService.reportSettingsProblem(Log.WARN,
3953                         "Unknown element under <enabled-components>: " + parser.getName());
3954             }
3955             XmlUtils.skipCurrentTag(parser);
3956         }
3957     }
3958 
readSharedUserLPw(XmlPullParser parser)3959     private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
3960         String name = null;
3961         String idStr = null;
3962         int pkgFlags = 0;
3963         int pkgPrivateFlags = 0;
3964         SharedUserSetting su = null;
3965         try {
3966             name = parser.getAttributeValue(null, ATTR_NAME);
3967             idStr = parser.getAttributeValue(null, "userId");
3968             int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3969             if ("true".equals(parser.getAttributeValue(null, "system"))) {
3970                 pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3971             }
3972             if (name == null) {
3973                 PackageManagerService.reportSettingsProblem(Log.WARN,
3974                         "Error in package manager settings: <shared-user> has no name at "
3975                                 + parser.getPositionDescription());
3976             } else if (userId == 0) {
3977                 PackageManagerService.reportSettingsProblem(Log.WARN,
3978                         "Error in package manager settings: shared-user " + name
3979                                 + " has bad userId " + idStr + " at "
3980                                 + parser.getPositionDescription());
3981             } else {
3982                 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
3983                         == null) {
3984                     PackageManagerService
3985                             .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
3986                                     + parser.getPositionDescription());
3987                 }
3988             }
3989         } catch (NumberFormatException e) {
3990             PackageManagerService.reportSettingsProblem(Log.WARN,
3991                     "Error in package manager settings: package " + name + " has bad userId "
3992                             + idStr + " at " + parser.getPositionDescription());
3993         }
3994 
3995         if (su != null) {
3996             int outerDepth = parser.getDepth();
3997             int type;
3998             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3999                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4000                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4001                     continue;
4002                 }
4003 
4004                 String tagName = parser.getName();
4005                 if (tagName.equals("sigs")) {
4006                     su.signatures.readXml(parser, mPastSignatures);
4007                 } else if (tagName.equals("perms")) {
4008                     readInstallPermissionsLPr(parser, su.getPermissionsState());
4009                 } else {
4010                     PackageManagerService.reportSettingsProblem(Log.WARN,
4011                             "Unknown element under <shared-user>: " + parser.getName());
4012                     XmlUtils.skipCurrentTag(parser);
4013                 }
4014             }
4015         } else {
4016             XmlUtils.skipCurrentTag(parser);
4017         }
4018     }
4019 
createNewUserLI(@onNull PackageManagerService service, @NonNull Installer installer, int userHandle, String[] disallowedPackages)4020     void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
4021             int userHandle, String[] disallowedPackages) {
4022         String[] volumeUuids;
4023         String[] names;
4024         int[] appIds;
4025         String[] seinfos;
4026         int[] targetSdkVersions;
4027         int packagesCount;
4028         synchronized (mPackages) {
4029             Collection<PackageSetting> packages = mPackages.values();
4030             packagesCount = packages.size();
4031             volumeUuids = new String[packagesCount];
4032             names = new String[packagesCount];
4033             appIds = new int[packagesCount];
4034             seinfos = new String[packagesCount];
4035             targetSdkVersions = new int[packagesCount];
4036             Iterator<PackageSetting> packagesIterator = packages.iterator();
4037             for (int i = 0; i < packagesCount; i++) {
4038                 PackageSetting ps = packagesIterator.next();
4039                 if (ps.pkg == null || ps.pkg.applicationInfo == null) {
4040                     continue;
4041                 }
4042                 final boolean shouldInstall = ps.isSystem() &&
4043                         !ArrayUtils.contains(disallowedPackages, ps.name) &&
4044                         !ps.pkg.applicationInfo.hiddenUntilInstalled;
4045                 // Only system apps are initially installed.
4046                 ps.setInstalled(shouldInstall, userHandle);
4047                 if (!shouldInstall) {
4048                     writeKernelMappingLPr(ps);
4049                 }
4050                 // Need to create a data directory for all apps under this user. Accumulate all
4051                 // required args and call the installer after mPackages lock has been released
4052                 volumeUuids[i] = ps.volumeUuid;
4053                 names[i] = ps.name;
4054                 appIds[i] = ps.appId;
4055                 seinfos[i] = ps.pkg.applicationInfo.seInfo;
4056                 targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
4057             }
4058         }
4059         for (int i = 0; i < packagesCount; i++) {
4060             if (names[i] == null) {
4061                 continue;
4062             }
4063             // TODO: triage flags!
4064             final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
4065             try {
4066                 installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
4067                         seinfos[i], targetSdkVersions[i]);
4068             } catch (InstallerException e) {
4069                 Slog.w(TAG, "Failed to prepare app data", e);
4070             }
4071         }
4072         synchronized (mPackages) {
4073             applyDefaultPreferredAppsLPw(userHandle);
4074         }
4075     }
4076 
removeUserLPw(int userId)4077     void removeUserLPw(int userId) {
4078         Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
4079         for (Entry<String, PackageSetting> entry : entries) {
4080             entry.getValue().removeUser(userId);
4081         }
4082         mPreferredActivities.remove(userId);
4083         File file = getUserPackagesStateFile(userId);
4084         file.delete();
4085         file = getUserPackagesStateBackupFile(userId);
4086         file.delete();
4087         removeCrossProfileIntentFiltersLPw(userId);
4088 
4089         mRuntimePermissionsPersistence.onUserRemovedLPw(userId);
4090 
4091         writePackageListLPr();
4092 
4093         // Inform kernel that the user was removed, so that packages are marked uninstalled
4094         // for sdcardfs
4095         writeKernelRemoveUserLPr(userId);
4096     }
4097 
removeCrossProfileIntentFiltersLPw(int userId)4098     void removeCrossProfileIntentFiltersLPw(int userId) {
4099         synchronized (mCrossProfileIntentResolvers) {
4100             // userId is the source user
4101             if (mCrossProfileIntentResolvers.get(userId) != null) {
4102                 mCrossProfileIntentResolvers.remove(userId);
4103                 writePackageRestrictionsLPr(userId);
4104             }
4105             // userId is the target user
4106             int count = mCrossProfileIntentResolvers.size();
4107             for (int i = 0; i < count; i++) {
4108                 int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
4109                 CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
4110                 boolean needsWriting = false;
4111                 ArraySet<CrossProfileIntentFilter> cpifs =
4112                         new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
4113                 for (CrossProfileIntentFilter cpif : cpifs) {
4114                     if (cpif.getTargetUserId() == userId) {
4115                         needsWriting = true;
4116                         cpir.removeFilter(cpif);
4117                     }
4118                 }
4119                 if (needsWriting) {
4120                     writePackageRestrictionsLPr(sourceUserId);
4121                 }
4122             }
4123         }
4124     }
4125 
4126     // This should be called (at least) whenever an application is removed
setFirstAvailableUid(int uid)4127     private void setFirstAvailableUid(int uid) {
4128         if (uid > mFirstAvailableUid) {
4129             mFirstAvailableUid = uid;
4130         }
4131     }
4132 
4133     /** Returns a new AppID or -1 if we could not find an available AppID to assign */
acquireAndRegisterNewAppIdLPw(SettingBase obj)4134     private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
4135         // Let's be stupidly inefficient for now...
4136         final int size = mAppIds.size();
4137         for (int i = mFirstAvailableUid; i < size; i++) {
4138             if (mAppIds.get(i) == null) {
4139                 mAppIds.set(i, obj);
4140                 return Process.FIRST_APPLICATION_UID + i;
4141             }
4142         }
4143 
4144         // None left?
4145         if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
4146             return -1;
4147         }
4148 
4149         mAppIds.add(obj);
4150         return Process.FIRST_APPLICATION_UID + size;
4151     }
4152 
getVerifierDeviceIdentityLPw()4153     public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
4154         if (mVerifierDeviceIdentity == null) {
4155             mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
4156 
4157             writeLPr();
4158         }
4159 
4160         return mVerifierDeviceIdentity;
4161     }
4162 
hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName, String childPackageName)4163     boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
4164             String childPackageName) {
4165         final int packageCount = mDisabledSysPackages.size();
4166         for (int i = 0; i < packageCount; i++) {
4167             PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
4168             if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
4169                 continue;
4170             }
4171             if (disabledPs.name.equals(parentPackageName)) {
4172                 continue;
4173             }
4174             final int childCount = disabledPs.childPackageNames.size();
4175             for (int j = 0; j < childCount; j++) {
4176                 String currChildPackageName = disabledPs.childPackageNames.get(j);
4177                 if (currChildPackageName.equals(childPackageName)) {
4178                     return true;
4179                 }
4180             }
4181         }
4182         return false;
4183     }
4184 
4185     /**
4186      * Returns the disabled {@link PackageSetting} for the provided package name if one exists,
4187      * {@code null} otherwise.
4188      */
4189     @Nullable
getDisabledSystemPkgLPr(String name)4190     public PackageSetting getDisabledSystemPkgLPr(String name) {
4191         PackageSetting ps = mDisabledSysPackages.get(name);
4192         return ps;
4193     }
4194 
4195     /**
4196      * Returns the disabled {@link PackageSetting} for the provided enabled {@link PackageSetting}
4197      * if one exists, {@code null} otherwise.
4198      */
4199     @Nullable
getDisabledSystemPkgLPr(PackageSetting enabledPackageSetting)4200     public PackageSetting getDisabledSystemPkgLPr(PackageSetting enabledPackageSetting) {
4201         if (enabledPackageSetting == null) {
4202             return null;
4203         }
4204         return getDisabledSystemPkgLPr(enabledPackageSetting.name);
4205     }
4206 
4207     /**
4208      * Fetches an array of the child {@link PackageSetting}s for all child package names referenced
4209      * by the provided parent {@link PackageSetting} or {@code null} if no children are referenced.
4210      *
4211      * Note: Any child packages not found will be null in the returned array.
4212      */
4213     @Nullable
getChildSettingsLPr(PackageSetting parentPackageSetting)4214     public PackageSetting[] getChildSettingsLPr(PackageSetting parentPackageSetting) {
4215         if (parentPackageSetting == null || !parentPackageSetting.hasChildPackages()) {
4216             return null;
4217         }
4218         final int childCount = parentPackageSetting.childPackageNames.size();
4219         PackageSetting[] children =
4220                 new PackageSetting[childCount];
4221         for (int i = 0; i < childCount; i++) {
4222             children[i] = mPackages.get(parentPackageSetting.childPackageNames.get(i));
4223         }
4224         return children;
4225     }
4226 
isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId)4227     boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
4228         final PackageSetting ps = mPackages.get(componentInfo.packageName);
4229         if (ps == null) return false;
4230 
4231         final PackageUserState userState = ps.readUserState(userId);
4232         return userState.isMatch(componentInfo, flags);
4233     }
4234 
getInstallerPackageNameLPr(String packageName)4235     String getInstallerPackageNameLPr(String packageName) {
4236         final PackageSetting pkg = mPackages.get(packageName);
4237         if (pkg == null) {
4238             throw new IllegalArgumentException("Unknown package: " + packageName);
4239         }
4240         return pkg.installerPackageName;
4241     }
4242 
isOrphaned(String packageName)4243     boolean isOrphaned(String packageName) {
4244         final PackageSetting pkg = mPackages.get(packageName);
4245         if (pkg == null) {
4246             throw new IllegalArgumentException("Unknown package: " + packageName);
4247         }
4248         return pkg.isOrphaned;
4249     }
4250 
getApplicationEnabledSettingLPr(String packageName, int userId)4251     int getApplicationEnabledSettingLPr(String packageName, int userId) {
4252         final PackageSetting pkg = mPackages.get(packageName);
4253         if (pkg == null) {
4254             throw new IllegalArgumentException("Unknown package: " + packageName);
4255         }
4256         return pkg.getEnabled(userId);
4257     }
4258 
getComponentEnabledSettingLPr(ComponentName componentName, int userId)4259     int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
4260         final String packageName = componentName.getPackageName();
4261         final PackageSetting pkg = mPackages.get(packageName);
4262         if (pkg == null) {
4263             throw new IllegalArgumentException("Unknown component: " + componentName);
4264         }
4265         final String classNameStr = componentName.getClassName();
4266         return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
4267     }
4268 
wasPackageEverLaunchedLPr(String packageName, int userId)4269     boolean wasPackageEverLaunchedLPr(String packageName, int userId) {
4270         final PackageSetting pkgSetting = mPackages.get(packageName);
4271         if (pkgSetting == null) {
4272             throw new IllegalArgumentException("Unknown package: " + packageName);
4273         }
4274         return !pkgSetting.getNotLaunched(userId);
4275     }
4276 
setPackageStoppedStateLPw(PackageManagerService pm, String packageName, boolean stopped, boolean allowedByPermission, int uid, int userId)4277     boolean setPackageStoppedStateLPw(PackageManagerService pm, String packageName,
4278             boolean stopped, boolean allowedByPermission, int uid, int userId) {
4279         int appId = UserHandle.getAppId(uid);
4280         final PackageSetting pkgSetting = mPackages.get(packageName);
4281         if (pkgSetting == null) {
4282             throw new IllegalArgumentException("Unknown package: " + packageName);
4283         }
4284         if (!allowedByPermission && (appId != pkgSetting.appId)) {
4285             throw new SecurityException(
4286                     "Permission Denial: attempt to change stopped state from pid="
4287                     + Binder.getCallingPid()
4288                     + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
4289         }
4290         if (DEBUG_STOPPED) {
4291             if (stopped) {
4292                 RuntimeException e = new RuntimeException("here");
4293                 e.fillInStackTrace();
4294                 Slog.i(TAG, "Stopping package " + packageName, e);
4295             }
4296         }
4297         if (pkgSetting.getStopped(userId) != stopped) {
4298             pkgSetting.setStopped(stopped, userId);
4299             // pkgSetting.pkg.mSetStopped = stopped;
4300             if (pkgSetting.getNotLaunched(userId)) {
4301                 if (pkgSetting.installerPackageName != null) {
4302                     pm.notifyFirstLaunch(pkgSetting.name, pkgSetting.installerPackageName, userId);
4303                 }
4304                 pkgSetting.setNotLaunched(false, userId);
4305             }
4306             return true;
4307         }
4308         return false;
4309     }
4310 
setHarmfulAppWarningLPw(String packageName, CharSequence warning, int userId)4311     void setHarmfulAppWarningLPw(String packageName, CharSequence warning, int userId) {
4312         final PackageSetting pkgSetting = mPackages.get(packageName);
4313         if (pkgSetting == null) {
4314             throw new IllegalArgumentException("Unknown package: " + packageName);
4315         }
4316         pkgSetting.setHarmfulAppWarning(userId, warning == null ? null : warning.toString());
4317     }
4318 
getHarmfulAppWarningLPr(String packageName, int userId)4319     String getHarmfulAppWarningLPr(String packageName, int userId) {
4320         final PackageSetting pkgSetting = mPackages.get(packageName);
4321         if (pkgSetting == null) {
4322             throw new IllegalArgumentException("Unknown package: " + packageName);
4323         }
4324         return pkgSetting.getHarmfulAppWarning(userId);
4325     }
4326 
4327     /**
4328      * Return all users on the device, including partial or dying users.
4329      * @param userManager UserManagerService instance
4330      * @return the list of users
4331      */
getAllUsers(UserManagerService userManager)4332     private static List<UserInfo> getAllUsers(UserManagerService userManager) {
4333         return getUsers(userManager, false);
4334     }
4335 
4336     /**
4337      * Return the list of users on the device. Clear the calling identity before calling into
4338      * UserManagerService.
4339      * @param userManager UserManagerService instance
4340      * @param excludeDying Indicates whether to exclude any users marked for deletion.
4341      * @return the list of users
4342      */
getUsers(UserManagerService userManager, boolean excludeDying)4343     private static List<UserInfo> getUsers(UserManagerService userManager, boolean excludeDying) {
4344         long id = Binder.clearCallingIdentity();
4345         try {
4346             return userManager.getUsers(excludeDying);
4347         } catch (NullPointerException npe) {
4348             // packagemanager not yet initialized
4349         } finally {
4350             Binder.restoreCallingIdentity(id);
4351         }
4352         return null;
4353     }
4354 
4355     /**
4356      * Return all {@link PackageSetting} that are actively installed on the
4357      * given {@link VolumeInfo#fsUuid}.
4358      */
getVolumePackagesLPr(String volumeUuid)4359     List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
4360         ArrayList<PackageSetting> res = new ArrayList<>();
4361         for (int i = 0; i < mPackages.size(); i++) {
4362             final PackageSetting setting = mPackages.valueAt(i);
4363             if (Objects.equals(volumeUuid, setting.volumeUuid)) {
4364                 res.add(setting);
4365             }
4366         }
4367         return res;
4368     }
4369 
printFlags(PrintWriter pw, int val, Object[] spec)4370     static void printFlags(PrintWriter pw, int val, Object[] spec) {
4371         pw.print("[ ");
4372         for (int i=0; i<spec.length; i+=2) {
4373             int mask = (Integer)spec[i];
4374             if ((val & mask) != 0) {
4375                 pw.print(spec[i+1]);
4376                 pw.print(" ");
4377             }
4378         }
4379         pw.print("]");
4380     }
4381 
4382     static final Object[] FLAG_DUMP_SPEC = new Object[] {
4383         ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4384         ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4385         ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4386         ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4387         ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4388         ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4389         ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4390         ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4391         ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4392         ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4393         ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4394         ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4395         ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4396         ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4397         ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4398     };
4399 
4400     private static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4401             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE",
4402             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION",
4403             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE",
4404             ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, "ALLOW_AUDIO_PLAYBACK_CAPTURE",
4405             ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE, "PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE",
4406             ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
4407             ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4408             ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
4409             ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
4410             ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
4411             ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN",
4412             ApplicationInfo.PRIVATE_FLAG_INSTANT, "EPHEMERAL",
4413             ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, "ISOLATED_SPLIT_LOADING",
4414             ApplicationInfo.PRIVATE_FLAG_OEM, "OEM",
4415             ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
4416             ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4417             ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
4418             ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
4419             ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
4420             ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
4421             ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT, "SYSTEM_EXT",
4422             ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
4423             ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
4424     };
4425 
dumpVersionLPr(IndentingPrintWriter pw)4426     void dumpVersionLPr(IndentingPrintWriter pw) {
4427         pw.increaseIndent();
4428         for (int i= 0; i < mVersion.size(); i++) {
4429             final String volumeUuid = mVersion.keyAt(i);
4430             final VersionInfo ver = mVersion.valueAt(i);
4431             if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4432                 pw.println("Internal:");
4433             } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4434                 pw.println("External:");
4435             } else {
4436                 pw.println("UUID " + volumeUuid + ":");
4437             }
4438             pw.increaseIndent();
4439             pw.printPair("sdkVersion", ver.sdkVersion);
4440             pw.printPair("databaseVersion", ver.databaseVersion);
4441             pw.println();
4442             pw.printPair("fingerprint", ver.fingerprint);
4443             pw.println();
4444             pw.decreaseIndent();
4445         }
4446         pw.decreaseIndent();
4447     }
4448 
dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents)4449     void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4450             ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4451             Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) {
4452         if (checkinTag != null) {
4453             pw.print(checkinTag);
4454             pw.print(",");
4455             pw.print(ps.realName != null ? ps.realName : ps.name);
4456             pw.print(",");
4457             pw.print(ps.appId);
4458             pw.print(",");
4459             pw.print(ps.versionCode);
4460             pw.print(",");
4461             pw.print(ps.firstInstallTime);
4462             pw.print(",");
4463             pw.print(ps.lastUpdateTime);
4464             pw.print(",");
4465             pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4466             pw.println();
4467             if (ps.pkg != null) {
4468                 pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4469                 pw.print("base,");
4470                 pw.println(ps.pkg.baseRevisionCode);
4471                 if (ps.pkg.splitNames != null) {
4472                     for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4473                         pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4474                         pw.print(ps.pkg.splitNames[i]); pw.print(",");
4475                         pw.println(ps.pkg.splitRevisionCodes[i]);
4476                     }
4477                 }
4478             }
4479             for (UserInfo user : users) {
4480                 pw.print(checkinTag);
4481                 pw.print("-");
4482                 pw.print("usr");
4483                 pw.print(",");
4484                 pw.print(user.id);
4485                 pw.print(",");
4486                 pw.print(ps.getInstalled(user.id) ? "I" : "i");
4487                 pw.print(ps.getHidden(user.id) ? "B" : "b");
4488                 pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4489                 pw.print(ps.getStopped(user.id) ? "S" : "s");
4490                 pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4491                 pw.print(ps.getInstantApp(user.id) ? "IA" : "ia");
4492                 pw.print(ps.getVirtulalPreload(user.id) ? "VPI" : "vpi");
4493                 String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4494                 pw.print(harmfulAppWarning != null ? "HA" : "ha");
4495                 pw.print(",");
4496                 pw.print(ps.getEnabled(user.id));
4497                 String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4498                 pw.print(",");
4499                 pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4500                 pw.print(",");
4501                 pw.println();
4502             }
4503             return;
4504         }
4505 
4506         pw.print(prefix); pw.print("Package [");
4507             pw.print(ps.realName != null ? ps.realName : ps.name);
4508             pw.print("] (");
4509             pw.print(Integer.toHexString(System.identityHashCode(ps)));
4510             pw.println("):");
4511 
4512         if (ps.realName != null) {
4513             pw.print(prefix); pw.print("  compat name=");
4514             pw.println(ps.name);
4515         }
4516 
4517         pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4518 
4519         if (ps.sharedUser != null) {
4520             pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4521         }
4522         pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4523         pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4524         if (permissionNames == null) {
4525             pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4526             pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4527             pw.println(ps.legacyNativeLibraryPathString);
4528             pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4529             pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4530         }
4531         pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4532         if (ps.pkg != null) {
4533             pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion);
4534             pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4535         }
4536         pw.println();
4537         if (ps.pkg != null) {
4538             if (ps.pkg.parentPackage != null) {
4539                 PackageParser.Package parentPkg = ps.pkg.parentPackage;
4540                 PackageSetting pps = mPackages.get(parentPkg.packageName);
4541                 if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
4542                     pps = mDisabledSysPackages.get(parentPkg.packageName);
4543                 }
4544                 if (pps != null) {
4545                     pw.print(prefix); pw.print("  parentPackage=");
4546                     pw.println(pps.realName != null ? pps.realName : pps.name);
4547                 }
4548             } else if (ps.pkg.childPackages != null) {
4549                 pw.print(prefix); pw.print("  childPackages=[");
4550                 final int childCount = ps.pkg.childPackages.size();
4551                 for (int i = 0; i < childCount; i++) {
4552                     PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
4553                     PackageSetting cps = mPackages.get(childPkg.packageName);
4554                     if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
4555                         cps = mDisabledSysPackages.get(childPkg.packageName);
4556                     }
4557                     if (cps != null) {
4558                         if (i > 0) {
4559                             pw.print(", ");
4560                         }
4561                         pw.print(cps.realName != null ? cps.realName : cps.name);
4562                     }
4563                 }
4564                 pw.println("]");
4565             }
4566             pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4567             pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4568             final int apkSigningVersion = ps.pkg.mSigningDetails.signatureSchemeVersion;
4569             pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
4570             pw.print(prefix); pw.print("  applicationInfo=");
4571                 pw.println(ps.pkg.applicationInfo.toString());
4572             pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4573                     FLAG_DUMP_SPEC); pw.println();
4574             if (ps.pkg.applicationInfo.privateFlags != 0) {
4575                 pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4576                         ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4577             }
4578             pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4579             pw.print(prefix); pw.print("  supportsScreens=[");
4580             boolean first = true;
4581             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4582                 if (!first)
4583                     pw.print(", ");
4584                 first = false;
4585                 pw.print("small");
4586             }
4587             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4588                 if (!first)
4589                     pw.print(", ");
4590                 first = false;
4591                 pw.print("medium");
4592             }
4593             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4594                 if (!first)
4595                     pw.print(", ");
4596                 first = false;
4597                 pw.print("large");
4598             }
4599             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4600                 if (!first)
4601                     pw.print(", ");
4602                 first = false;
4603                 pw.print("xlarge");
4604             }
4605             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4606                 if (!first)
4607                     pw.print(", ");
4608                 first = false;
4609                 pw.print("resizeable");
4610             }
4611             if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4612                 if (!first)
4613                     pw.print(", ");
4614                 first = false;
4615                 pw.print("anyDensity");
4616             }
4617             pw.println("]");
4618             if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4619                 pw.print(prefix); pw.println("  dynamic libraries:");
4620                 for (int i = 0; i<ps.pkg.libraryNames.size(); i++) {
4621                     pw.print(prefix); pw.print("    ");
4622                             pw.println(ps.pkg.libraryNames.get(i));
4623                 }
4624             }
4625             if (ps.pkg.staticSharedLibName != null) {
4626                 pw.print(prefix); pw.println("  static library:");
4627                 pw.print(prefix); pw.print("    ");
4628                 pw.print("name:"); pw.print(ps.pkg.staticSharedLibName);
4629                 pw.print(" version:"); pw.println(ps.pkg.staticSharedLibVersion);
4630             }
4631             if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4632                 pw.print(prefix); pw.println("  usesLibraries:");
4633                 for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4634                     pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4635                 }
4636             }
4637             if (ps.pkg.usesStaticLibraries != null
4638                     && ps.pkg.usesStaticLibraries.size() > 0) {
4639                 pw.print(prefix); pw.println("  usesStaticLibraries:");
4640                 for (int i=0; i<ps.pkg.usesStaticLibraries.size(); i++) {
4641                     pw.print(prefix); pw.print("    ");
4642                     pw.print(ps.pkg.usesStaticLibraries.get(i)); pw.print(" version:");
4643                             pw.println(ps.pkg.usesStaticLibrariesVersions[i]);
4644                 }
4645             }
4646             if (ps.pkg.usesOptionalLibraries != null
4647                     && ps.pkg.usesOptionalLibraries.size() > 0) {
4648                 pw.print(prefix); pw.println("  usesOptionalLibraries:");
4649                 for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4650                     pw.print(prefix); pw.print("    ");
4651                     pw.println(ps.pkg.usesOptionalLibraries.get(i));
4652                 }
4653             }
4654             if (ps.pkg.usesLibraryFiles != null
4655                     && ps.pkg.usesLibraryFiles.length > 0) {
4656                 pw.print(prefix); pw.println("  usesLibraryFiles:");
4657                 for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4658                     pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4659                 }
4660             }
4661         }
4662         pw.print(prefix); pw.print("  timeStamp=");
4663             date.setTime(ps.timeStamp);
4664             pw.println(sdf.format(date));
4665         pw.print(prefix); pw.print("  firstInstallTime=");
4666             date.setTime(ps.firstInstallTime);
4667             pw.println(sdf.format(date));
4668         pw.print(prefix); pw.print("  lastUpdateTime=");
4669             date.setTime(ps.lastUpdateTime);
4670             pw.println(sdf.format(date));
4671         if (ps.installerPackageName != null) {
4672             pw.print(prefix); pw.print("  installerPackageName=");
4673                     pw.println(ps.installerPackageName);
4674         }
4675         if (ps.volumeUuid != null) {
4676             pw.print(prefix); pw.print("  volumeUuid=");
4677                     pw.println(ps.volumeUuid);
4678         }
4679         pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4680         pw.print(prefix); pw.print("  installPermissionsFixed=");
4681                 pw.print(ps.installPermissionsFixed);
4682                 pw.println();
4683         pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4684                 pw.println();
4685 
4686         if (ps.pkg != null && ps.pkg.mOverlayTarget != null) {
4687             pw.print(prefix); pw.print("  overlayTarget="); pw.println(ps.pkg.mOverlayTarget);
4688             pw.print(prefix); pw.print("  overlayCategory="); pw.println(ps.pkg.mOverlayCategory);
4689         }
4690 
4691         if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4692             final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4693             pw.print(prefix); pw.println("  declared permissions:");
4694             for (int i=0; i<perms.size(); i++) {
4695                 PackageParser.Permission perm = perms.get(i);
4696                 if (permissionNames != null
4697                         && !permissionNames.contains(perm.info.name)) {
4698                     continue;
4699                 }
4700                 pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4701                 pw.print(": prot=");
4702                 pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4703                 if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4704                     pw.print(", COSTS_MONEY");
4705                 }
4706                 if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4707                     pw.print(", HIDDEN");
4708                 }
4709                 if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4710                     pw.print(", INSTALLED");
4711                 }
4712                 pw.println();
4713             }
4714         }
4715 
4716         if ((permissionNames != null || dumpAll) && ps.pkg != null
4717                 && ps.pkg.requestedPermissions != null
4718                 && ps.pkg.requestedPermissions.size() > 0) {
4719             final ArrayList<String> perms = ps.pkg.requestedPermissions;
4720             pw.print(prefix); pw.println("  requested permissions:");
4721             for (int i=0; i<perms.size(); i++) {
4722                 String perm = perms.get(i);
4723                 if (permissionNames != null
4724                         && !permissionNames.contains(perm)) {
4725                     continue;
4726                 }
4727                 pw.print(prefix); pw.print("    "); pw.print(perm);
4728                 final BasePermission bp = mPermissions.getPermission(perm);
4729                 if (bp != null && bp.isHardOrSoftRestricted()) {
4730                     pw.println(": restricted=true");
4731                 } else {
4732                     pw.println();
4733                 }
4734             }
4735         }
4736 
4737         if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4738             PermissionsState permissionsState = ps.getPermissionsState();
4739             dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4740         }
4741 
4742         if (dumpAllComponents) {
4743             dumpComponents(pw, prefix + "  ", ps);
4744         }
4745 
4746         for (UserInfo user : users) {
4747             pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4748             pw.print("ceDataInode=");
4749             pw.print(ps.getCeDataInode(user.id));
4750             pw.print(" installed=");
4751             pw.print(ps.getInstalled(user.id));
4752             pw.print(" hidden=");
4753             pw.print(ps.getHidden(user.id));
4754             pw.print(" suspended=");
4755             pw.print(ps.getSuspended(user.id));
4756             if (ps.getSuspended(user.id)) {
4757                 final PackageUserState pus = ps.readUserState(user.id);
4758                 pw.print(" suspendingPackage=");
4759                 pw.print(pus.suspendingPackage);
4760                 pw.print(" dialogInfo=");
4761                 pw.print(pus.dialogInfo);
4762             }
4763             pw.print(" stopped=");
4764             pw.print(ps.getStopped(user.id));
4765             pw.print(" notLaunched=");
4766             pw.print(ps.getNotLaunched(user.id));
4767             pw.print(" enabled=");
4768             pw.print(ps.getEnabled(user.id));
4769             pw.print(" instant=");
4770             pw.print(ps.getInstantApp(user.id));
4771             pw.print(" virtual=");
4772             pw.println(ps.getVirtulalPreload(user.id));
4773 
4774             String[] overlayPaths = ps.getOverlayPaths(user.id);
4775             if (overlayPaths != null && overlayPaths.length > 0) {
4776                 pw.print(prefix); pw.println("  overlay paths:");
4777                 for (String path : overlayPaths) {
4778                     pw.print(prefix); pw.print("    "); pw.println(path);
4779                 }
4780             }
4781 
4782             String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4783             if (lastDisabledAppCaller != null) {
4784                 pw.print(prefix); pw.print("    lastDisabledCaller: ");
4785                         pw.println(lastDisabledAppCaller);
4786             }
4787 
4788             if (ps.sharedUser == null) {
4789                 PermissionsState permissionsState = ps.getPermissionsState();
4790                 dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4791                 dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4792                         .getRuntimePermissionStates(user.id), dumpAll);
4793             }
4794 
4795             String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4796             if (harmfulAppWarning != null) {
4797                 pw.print(prefix); pw.print("      harmfulAppWarning: ");
4798                 pw.println(harmfulAppWarning);
4799             }
4800 
4801             if (permissionNames == null) {
4802                 ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4803                 if (cmp != null && cmp.size() > 0) {
4804                     pw.print(prefix); pw.println("    disabledComponents:");
4805                     for (String s : cmp) {
4806                         pw.print(prefix); pw.print("      "); pw.println(s);
4807                     }
4808                 }
4809                 cmp = ps.getEnabledComponents(user.id);
4810                 if (cmp != null && cmp.size() > 0) {
4811                     pw.print(prefix); pw.println("    enabledComponents:");
4812                     for (String s : cmp) {
4813                         pw.print(prefix); pw.print("      "); pw.println(s);
4814                     }
4815                 }
4816             }
4817         }
4818     }
4819 
dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, DumpState dumpState, boolean checkin)4820     void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4821             DumpState dumpState, boolean checkin) {
4822         final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4823         final Date date = new Date();
4824         boolean printedSomething = false;
4825         final boolean dumpAllComponents =
4826                 dumpState.isOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
4827         List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4828         for (final PackageSetting ps : mPackages.values()) {
4829             if (packageName != null && !packageName.equals(ps.realName)
4830                     && !packageName.equals(ps.name)) {
4831                 continue;
4832             }
4833             if (permissionNames != null
4834                     && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4835                 continue;
4836             }
4837 
4838             if (!checkin && packageName != null) {
4839                 dumpState.setSharedUser(ps.sharedUser);
4840             }
4841 
4842             if (!checkin && !printedSomething) {
4843                 if (dumpState.onTitlePrinted())
4844                     pw.println();
4845                 pw.println("Packages:");
4846                 printedSomething = true;
4847             }
4848             dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4849                     packageName != null, dumpAllComponents);
4850         }
4851 
4852         printedSomething = false;
4853         if (mRenamedPackages.size() > 0 && permissionNames == null) {
4854             for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4855                 if (packageName != null && !packageName.equals(e.getKey())
4856                         && !packageName.equals(e.getValue())) {
4857                     continue;
4858                 }
4859                 if (!checkin) {
4860                     if (!printedSomething) {
4861                         if (dumpState.onTitlePrinted())
4862                             pw.println();
4863                         pw.println("Renamed packages:");
4864                         printedSomething = true;
4865                     }
4866                     pw.print("  ");
4867                 } else {
4868                     pw.print("ren,");
4869                 }
4870                 pw.print(e.getKey());
4871                 pw.print(checkin ? " -> " : ",");
4872                 pw.println(e.getValue());
4873             }
4874         }
4875 
4876         printedSomething = false;
4877         if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4878             for (final PackageSetting ps : mDisabledSysPackages.values()) {
4879                 if (packageName != null && !packageName.equals(ps.realName)
4880                         && !packageName.equals(ps.name)) {
4881                     continue;
4882                 }
4883                 if (!checkin && !printedSomething) {
4884                     if (dumpState.onTitlePrinted())
4885                         pw.println();
4886                     pw.println("Hidden system packages:");
4887                     printedSomething = true;
4888                 }
4889                 dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4890                         users, packageName != null, dumpAllComponents);
4891             }
4892         }
4893     }
4894 
dumpPackagesProto(ProtoOutputStream proto)4895     void dumpPackagesProto(ProtoOutputStream proto) {
4896         List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4897 
4898         final int count = mPackages.size();
4899         for (int i = 0; i < count; i++) {
4900             final PackageSetting ps = mPackages.valueAt(i);
4901             ps.writeToProto(proto, PackageServiceDumpProto.PACKAGES, users);
4902         }
4903     }
4904 
dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, DumpState dumpState)4905     void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4906             DumpState dumpState) {
4907         mPermissions.dumpPermissions(pw, packageName, permissionNames,
4908                 (mReadExternalStorageEnforced == Boolean.TRUE), dumpState);
4909     }
4910 
dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames, DumpState dumpState, boolean checkin)4911     void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4912             DumpState dumpState, boolean checkin) {
4913         boolean printedSomething = false;
4914         for (SharedUserSetting su : mSharedUsers.values()) {
4915             if (packageName != null && su != dumpState.getSharedUser()) {
4916                 continue;
4917             }
4918             if (permissionNames != null
4919                     && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4920                 continue;
4921             }
4922             if (!checkin) {
4923                 if (!printedSomething) {
4924                     if (dumpState.onTitlePrinted())
4925                         pw.println();
4926                     pw.println("Shared users:");
4927                     printedSomething = true;
4928                 }
4929 
4930                 pw.print("  SharedUser [");
4931                 pw.print(su.name);
4932                 pw.print("] (");
4933                 pw.print(Integer.toHexString(System.identityHashCode(su)));
4934                 pw.println("):");
4935 
4936                 String prefix = "    ";
4937                 pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4938 
4939                 pw.print(prefix); pw.println("Packages");
4940                 final int numPackages = su.packages.size();
4941                 for (int i = 0; i < numPackages; i++) {
4942                     final PackageSetting ps = su.packages.valueAt(i);
4943                     if (ps != null) {
4944                         pw.print(prefix + "  "); pw.println(ps.toString());
4945                     } else {
4946                         pw.print(prefix + "  "); pw.println("NULL?!");
4947                     }
4948                 }
4949 
4950                 if (dumpState.isOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS)) {
4951                     continue;
4952                 }
4953 
4954                 final PermissionsState permissionsState = su.getPermissionsState();
4955                 dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4956 
4957                 for (int userId : UserManagerService.getInstance().getUserIds()) {
4958                     final int[] gids = permissionsState.computeGids(userId);
4959                     final List<PermissionState> permissions =
4960                             permissionsState.getRuntimePermissionStates(userId);
4961                     if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4962                         pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4963                         dumpGidsLPr(pw, prefix + "  ", gids);
4964                         dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames,
4965                                 permissions, packageName != null);
4966                     }
4967                 }
4968             } else {
4969                 pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4970             }
4971         }
4972     }
4973 
dumpSharedUsersProto(ProtoOutputStream proto)4974     void dumpSharedUsersProto(ProtoOutputStream proto) {
4975         final int count = mSharedUsers.size();
4976         for (int i = 0; i < count; i++) {
4977             mSharedUsers.valueAt(i).writeToProto(proto, PackageServiceDumpProto.SHARED_USERS);
4978         }
4979     }
4980 
dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState)4981     void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4982         pw.println("Settings parse messages:");
4983         pw.print(mReadMessages.toString());
4984     }
4985 
dumpSplitNames(PrintWriter pw, PackageParser.Package pkg)4986     private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4987         if (pkg == null) {
4988             pw.print("unknown");
4989         } else {
4990             // [base:10, config.mdpi, config.xhdpi:12]
4991             pw.print("[");
4992             pw.print("base");
4993             if (pkg.baseRevisionCode != 0) {
4994                 pw.print(":"); pw.print(pkg.baseRevisionCode);
4995             }
4996             if (pkg.splitNames != null) {
4997                 for (int i = 0; i < pkg.splitNames.length; i++) {
4998                     pw.print(", ");
4999                     pw.print(pkg.splitNames[i]);
5000                     if (pkg.splitRevisionCodes[i] != 0) {
5001                         pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
5002                     }
5003                 }
5004             }
5005             pw.print("]");
5006         }
5007     }
5008 
dumpGidsLPr(PrintWriter pw, String prefix, int[] gids)5009     void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
5010         if (!ArrayUtils.isEmpty(gids)) {
5011             pw.print(prefix);
5012             pw.print("gids="); pw.println(
5013                     PackageManagerService.arrayToString(gids));
5014         }
5015     }
5016 
dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, List<PermissionState> permissionStates, boolean dumpAll)5017     void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
5018             List<PermissionState> permissionStates, boolean dumpAll) {
5019         if (!permissionStates.isEmpty() || dumpAll) {
5020             pw.print(prefix); pw.println("runtime permissions:");
5021             for (PermissionState permissionState : permissionStates) {
5022                 if (permissionNames != null
5023                         && !permissionNames.contains(permissionState.getName())) {
5024                     continue;
5025                 }
5026                 pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5027                 pw.print(": granted="); pw.print(permissionState.isGranted());
5028                     pw.println(permissionFlagsToString(", flags=",
5029                             permissionState.getFlags()));
5030             }
5031         }
5032     }
5033 
permissionFlagsToString(String prefix, int flags)5034     private static String permissionFlagsToString(String prefix, int flags) {
5035         StringBuilder flagsString = null;
5036         while (flags != 0) {
5037             if (flagsString == null) {
5038                 flagsString = new StringBuilder();
5039                 flagsString.append(prefix);
5040                 flagsString.append("[ ");
5041             }
5042             final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5043             flags &= ~flag;
5044             flagsString.append(PackageManager.permissionFlagToString(flag));
5045             if (flags != 0) {
5046                 flagsString.append('|');
5047             }
5048 
5049         }
5050         if (flagsString != null) {
5051             flagsString.append(']');
5052             return flagsString.toString();
5053         } else {
5054             return "";
5055         }
5056     }
5057 
dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, PermissionsState permissionsState)5058     void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
5059             PermissionsState permissionsState) {
5060         List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
5061         if (!permissionStates.isEmpty()) {
5062             pw.print(prefix); pw.println("install permissions:");
5063             for (PermissionState permissionState : permissionStates) {
5064                 if (permissionNames != null
5065                         && !permissionNames.contains(permissionState.getName())) {
5066                     continue;
5067                 }
5068                 pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5069                     pw.print(": granted="); pw.print(permissionState.isGranted());
5070                     pw.println(permissionFlagsToString(", flags=",
5071                         permissionState.getFlags()));
5072             }
5073         }
5074     }
5075 
dumpComponents(PrintWriter pw, String prefix, PackageSetting ps)5076     void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps) {
5077         dumpComponents(pw, prefix, ps, "activities:", ps.pkg.activities);
5078         dumpComponents(pw, prefix, ps, "services:", ps.pkg.services);
5079         dumpComponents(pw, prefix, ps, "receivers:", ps.pkg.receivers);
5080         dumpComponents(pw, prefix, ps, "providers:", ps.pkg.providers);
5081         dumpComponents(pw, prefix, ps, "instrumentations:", ps.pkg.instrumentation);
5082     }
5083 
dumpComponents(PrintWriter pw, String prefix, PackageSetting ps, String label, List<? extends PackageParser.Component<?>> list)5084     void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps,
5085             String label, List<? extends PackageParser.Component<?>> list) {
5086         final int size = CollectionUtils.size(list);
5087         if (size == 0) {
5088             return;
5089         }
5090         pw.print(prefix);pw.println(label);
5091         for (int i = 0; i < size; i++) {
5092             final PackageParser.Component<?> component = list.get(i);
5093             pw.print(prefix);pw.print("  ");
5094             pw.println(component.getComponentName().flattenToShortString());
5095         }
5096     }
5097 
writeRuntimePermissionsForUserLPr(int userId, boolean sync)5098     public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
5099         if (sync) {
5100             mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
5101         } else {
5102             mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
5103         }
5104     }
5105 
5106     private final class RuntimePermissionPersistence {
5107         private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
5108         private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
5109 
5110         private static final int UPGRADE_VERSION = -1;
5111         private static final int INITIAL_VERSION = 0;
5112 
5113         private final Handler mHandler = new MyHandler();
5114 
5115         private final Object mPersistenceLock;
5116 
5117         @GuardedBy("mLock")
5118         private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
5119 
5120         @GuardedBy("mLock")
5121         // The mapping keys are user ids.
5122         private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
5123 
5124         @GuardedBy("mLock")
5125         // The mapping keys are user ids.
5126         private final SparseIntArray mVersions = new SparseIntArray();
5127 
5128         @GuardedBy("mLock")
5129         // The mapping keys are user ids.
5130         private final SparseArray<String> mFingerprints = new SparseArray<>();
5131 
5132         @GuardedBy("mLock")
5133         // The mapping keys are user ids.
5134         private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
5135 
RuntimePermissionPersistence(Object persistenceLock)5136         public RuntimePermissionPersistence(Object persistenceLock) {
5137             mPersistenceLock = persistenceLock;
5138         }
5139 
5140         @GuardedBy("Settings.this.mLock")
getVersionLPr(int userId)5141         int getVersionLPr(int userId) {
5142             return mVersions.get(userId, INITIAL_VERSION);
5143         }
5144 
5145         @GuardedBy("Settings.this.mLock")
setVersionLPr(int version, int userId)5146         void setVersionLPr(int version, int userId) {
5147             mVersions.put(userId, version);
5148             writePermissionsForUserAsyncLPr(userId);
5149         }
5150 
5151         @GuardedBy("Settings.this.mLock")
areDefaultRuntimePermissionsGrantedLPr(int userId)5152         public boolean areDefaultRuntimePermissionsGrantedLPr(int userId) {
5153             return mDefaultPermissionsGranted.get(userId);
5154         }
5155 
5156         @GuardedBy("Settings.this.mLock")
setRuntimePermissionsFingerPrintLPr(@onNull String fingerPrint, @UserIdInt int userId)5157         public void setRuntimePermissionsFingerPrintLPr(@NonNull String fingerPrint,
5158                 @UserIdInt int userId) {
5159             mFingerprints.put(userId, fingerPrint);
5160             writePermissionsForUserAsyncLPr(userId);
5161         }
5162 
writePermissionsForUserSyncLPr(int userId)5163         public void writePermissionsForUserSyncLPr(int userId) {
5164             mHandler.removeMessages(userId);
5165             writePermissionsSync(userId);
5166         }
5167 
5168         @GuardedBy("Settings.this.mLock")
writePermissionsForUserAsyncLPr(int userId)5169         public void writePermissionsForUserAsyncLPr(int userId) {
5170             final long currentTimeMillis = SystemClock.uptimeMillis();
5171 
5172             if (mWriteScheduled.get(userId)) {
5173                 mHandler.removeMessages(userId);
5174 
5175                 // If enough time passed, write without holding off anymore.
5176                 final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
5177                         .get(userId);
5178                 final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
5179                         - lastNotWrittenMutationTimeMillis;
5180                 if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
5181                     mHandler.obtainMessage(userId).sendToTarget();
5182                     return;
5183                 }
5184 
5185                 // Hold off a bit more as settings are frequently changing.
5186                 final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
5187                         + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
5188                 final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
5189                         maxDelayMillis);
5190 
5191                 Message message = mHandler.obtainMessage(userId);
5192                 mHandler.sendMessageDelayed(message, writeDelayMillis);
5193             } else {
5194                 mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
5195                 Message message = mHandler.obtainMessage(userId);
5196                 mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
5197                 mWriteScheduled.put(userId, true);
5198             }
5199         }
5200 
writePermissionsSync(int userId)5201         private void writePermissionsSync(int userId) {
5202             AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId),
5203                     "package-perms-" + userId);
5204 
5205             ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
5206             ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
5207 
5208             synchronized (mPersistenceLock) {
5209                 mWriteScheduled.delete(userId);
5210 
5211                 final int packageCount = mPackages.size();
5212                 for (int i = 0; i < packageCount; i++) {
5213                     String packageName = mPackages.keyAt(i);
5214                     PackageSetting packageSetting = mPackages.valueAt(i);
5215                     if (packageSetting.sharedUser == null) {
5216                         PermissionsState permissionsState = packageSetting.getPermissionsState();
5217                         List<PermissionState> permissionsStates = permissionsState
5218                                 .getRuntimePermissionStates(userId);
5219                         if (!permissionsStates.isEmpty()) {
5220                             permissionsForPackage.put(packageName, permissionsStates);
5221                         }
5222                     }
5223                 }
5224 
5225                 final int sharedUserCount = mSharedUsers.size();
5226                 for (int i = 0; i < sharedUserCount; i++) {
5227                     String sharedUserName = mSharedUsers.keyAt(i);
5228                     SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
5229                     PermissionsState permissionsState = sharedUser.getPermissionsState();
5230                     List<PermissionState> permissionsStates = permissionsState
5231                             .getRuntimePermissionStates(userId);
5232                     if (!permissionsStates.isEmpty()) {
5233                         permissionsForSharedUser.put(sharedUserName, permissionsStates);
5234                     }
5235                 }
5236             }
5237 
5238             FileOutputStream out = null;
5239             try {
5240                 out = destination.startWrite();
5241 
5242                 XmlSerializer serializer = Xml.newSerializer();
5243                 serializer.setOutput(out, StandardCharsets.UTF_8.name());
5244                 serializer.setFeature(
5245                         "http://xmlpull.org/v1/doc/features.html#indent-output", true);
5246                 serializer.startDocument(null, true);
5247 
5248                 serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
5249 
5250                 final int version = mVersions.get(userId, INITIAL_VERSION);
5251                 serializer.attribute(null, ATTR_VERSION, Integer.toString(version));
5252 
5253                 String fingerprint = mFingerprints.get(userId);
5254                 if (fingerprint != null) {
5255                     serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
5256                 }
5257 
5258                 final int packageCount = permissionsForPackage.size();
5259                 for (int i = 0; i < packageCount; i++) {
5260                     String packageName = permissionsForPackage.keyAt(i);
5261                     List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
5262                     serializer.startTag(null, TAG_PACKAGE);
5263                     serializer.attribute(null, ATTR_NAME, packageName);
5264                     writePermissions(serializer, permissionStates);
5265                     serializer.endTag(null, TAG_PACKAGE);
5266                 }
5267 
5268                 final int sharedUserCount = permissionsForSharedUser.size();
5269                 for (int i = 0; i < sharedUserCount; i++) {
5270                     String packageName = permissionsForSharedUser.keyAt(i);
5271                     List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
5272                     serializer.startTag(null, TAG_SHARED_USER);
5273                     serializer.attribute(null, ATTR_NAME, packageName);
5274                     writePermissions(serializer, permissionStates);
5275                     serializer.endTag(null, TAG_SHARED_USER);
5276                 }
5277 
5278                 serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
5279 
5280                 serializer.endDocument();
5281                 destination.finishWrite(out);
5282 
5283                 if (Build.FINGERPRINT.equals(fingerprint)) {
5284                     mDefaultPermissionsGranted.put(userId, true);
5285                 }
5286             // Any error while writing is fatal.
5287             } catch (Throwable t) {
5288                 Slog.wtf(PackageManagerService.TAG,
5289                         "Failed to write settings, restoring backup", t);
5290                 destination.failWrite(out);
5291             } finally {
5292                 IoUtils.closeQuietly(out);
5293             }
5294         }
5295 
5296         @GuardedBy("Settings.this.mLock")
onUserRemovedLPw(int userId)5297         private void onUserRemovedLPw(int userId) {
5298             // Make sure we do not
5299             mHandler.removeMessages(userId);
5300 
5301             for (SettingBase sb : mPackages.values()) {
5302                 revokeRuntimePermissionsAndClearFlags(sb, userId);
5303             }
5304 
5305             for (SettingBase sb : mSharedUsers.values()) {
5306                 revokeRuntimePermissionsAndClearFlags(sb, userId);
5307             }
5308 
5309             mDefaultPermissionsGranted.delete(userId);
5310             mVersions.delete(userId);
5311             mFingerprints.remove(userId);
5312         }
5313 
revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId)5314         private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5315             PermissionsState permissionsState = sb.getPermissionsState();
5316             for (PermissionState permissionState
5317                     : permissionsState.getRuntimePermissionStates(userId)) {
5318                 BasePermission bp = mPermissions.getPermission(permissionState.getName());
5319                 if (bp != null) {
5320                     permissionsState.revokeRuntimePermission(bp, userId);
5321                     permissionsState.updatePermissionFlags(bp, userId,
5322                             PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
5323                 }
5324             }
5325         }
5326 
deleteUserRuntimePermissionsFile(int userId)5327         public void deleteUserRuntimePermissionsFile(int userId) {
5328             getUserRuntimePermissionsFile(userId).delete();
5329         }
5330 
5331         @GuardedBy("Settings.this.mLock")
readStateForUserSyncLPr(int userId)5332         public void readStateForUserSyncLPr(int userId) {
5333             File permissionsFile = getUserRuntimePermissionsFile(userId);
5334             if (!permissionsFile.exists()) {
5335                 return;
5336             }
5337 
5338             FileInputStream in;
5339             try {
5340                 in = new AtomicFile(permissionsFile).openRead();
5341             } catch (FileNotFoundException fnfe) {
5342                 Slog.i(PackageManagerService.TAG, "No permissions state");
5343                 return;
5344             }
5345 
5346             try {
5347                 XmlPullParser parser = Xml.newPullParser();
5348                 parser.setInput(in, null);
5349                 parseRuntimePermissionsLPr(parser, userId);
5350 
5351             } catch (XmlPullParserException | IOException e) {
5352                 throw new IllegalStateException("Failed parsing permissions file: "
5353                         + permissionsFile , e);
5354             } finally {
5355                 IoUtils.closeQuietly(in);
5356             }
5357         }
5358 
5359         // Private internals
5360 
5361         @GuardedBy("Settings.this.mLock")
parseRuntimePermissionsLPr(XmlPullParser parser, int userId)5362         private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5363                 throws IOException, XmlPullParserException {
5364             final int outerDepth = parser.getDepth();
5365             int type;
5366             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5367                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5368                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5369                     continue;
5370                 }
5371 
5372                 switch (parser.getName()) {
5373                     case TAG_RUNTIME_PERMISSIONS: {
5374                         // If the permisions settings file exists but the version is not set this is
5375                         // an upgrade from P->Q. Hence mark it with the special UPGRADE_VERSION
5376                         int version = XmlUtils.readIntAttribute(parser, ATTR_VERSION,
5377                                 UPGRADE_VERSION);
5378                         mVersions.put(userId, version);
5379                         String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5380                         mFingerprints.put(userId, fingerprint);
5381                         final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5382                         mDefaultPermissionsGranted.put(userId, defaultsGranted);
5383                     } break;
5384 
5385                     case TAG_PACKAGE: {
5386                         String name = parser.getAttributeValue(null, ATTR_NAME);
5387                         PackageSetting ps = mPackages.get(name);
5388                         if (ps == null) {
5389                             Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5390                             XmlUtils.skipCurrentTag(parser);
5391                             continue;
5392                         }
5393                         parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5394                     } break;
5395 
5396                     case TAG_SHARED_USER: {
5397                         String name = parser.getAttributeValue(null, ATTR_NAME);
5398                         SharedUserSetting sus = mSharedUsers.get(name);
5399                         if (sus == null) {
5400                             Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5401                             XmlUtils.skipCurrentTag(parser);
5402                             continue;
5403                         }
5404                         parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5405                     } break;
5406                 }
5407             }
5408         }
5409 
parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState, int userId)5410         private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5411                 int userId) throws IOException, XmlPullParserException {
5412             final int outerDepth = parser.getDepth();
5413             int type;
5414             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5415                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5416                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5417                     continue;
5418                 }
5419 
5420                 switch (parser.getName()) {
5421                     case TAG_ITEM: {
5422                         String name = parser.getAttributeValue(null, ATTR_NAME);
5423                         BasePermission bp = mPermissions.getPermission(name);
5424                         if (bp == null) {
5425                             Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5426                             XmlUtils.skipCurrentTag(parser);
5427                             continue;
5428                         }
5429 
5430                         String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5431                         final boolean granted = grantedStr == null
5432                                 || Boolean.parseBoolean(grantedStr);
5433 
5434                         String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5435                         final int flags = (flagsStr != null)
5436                                 ? Integer.parseInt(flagsStr, 16) : 0;
5437 
5438                         if (granted) {
5439                             permissionsState.grantRuntimePermission(bp, userId);
5440                             permissionsState.updatePermissionFlags(bp, userId,
5441                                         PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
5442                         } else {
5443                             permissionsState.updatePermissionFlags(bp, userId,
5444                                     PackageManager.MASK_PERMISSION_FLAGS_ALL, flags);
5445                         }
5446 
5447                     } break;
5448                 }
5449             }
5450         }
5451 
writePermissions(XmlSerializer serializer, List<PermissionState> permissionStates)5452         private void writePermissions(XmlSerializer serializer,
5453                 List<PermissionState> permissionStates) throws IOException {
5454             for (PermissionState permissionState : permissionStates) {
5455                 serializer.startTag(null, TAG_ITEM);
5456                 serializer.attribute(null, ATTR_NAME,permissionState.getName());
5457                 serializer.attribute(null, ATTR_GRANTED,
5458                         String.valueOf(permissionState.isGranted()));
5459                 serializer.attribute(null, ATTR_FLAGS,
5460                         Integer.toHexString(permissionState.getFlags()));
5461                 serializer.endTag(null, TAG_ITEM);
5462             }
5463         }
5464 
5465         private final class MyHandler extends Handler {
MyHandler()5466             public MyHandler() {
5467                 super(BackgroundThread.getHandler().getLooper());
5468             }
5469 
5470             @Override
handleMessage(Message message)5471             public void handleMessage(Message message) {
5472                 final int userId = message.what;
5473                 Runnable callback = (Runnable) message.obj;
5474                 writePermissionsSync(userId);
5475                 if (callback != null) {
5476                     callback.run();
5477                 }
5478             }
5479         }
5480     }
5481 }
5482