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