OSDN Git Service

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