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