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