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