OSDN Git Service

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