OSDN Git Service

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