Settings.java revision af6f195b15015f8ae5896aa777ff647dfe488114
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 != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4641            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4642            pw.print(prefix); pw.println("  declared permissions:");
4643            for (int i=0; i<perms.size(); i++) {
4644                PackageParser.Permission perm = perms.get(i);
4645                if (permissionNames != null
4646                        && !permissionNames.contains(perm.info.name)) {
4647                    continue;
4648                }
4649                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4650                pw.print(": prot=");
4651                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4652                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4653                    pw.print(", COSTS_MONEY");
4654                }
4655                if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4656                    pw.print(", HIDDEN");
4657                }
4658                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4659                    pw.print(", INSTALLED");
4660                }
4661                pw.println();
4662            }
4663        }
4664
4665        if ((permissionNames != null || dumpAll) && ps.pkg != null
4666                && ps.pkg.requestedPermissions != null
4667                && ps.pkg.requestedPermissions.size() > 0) {
4668            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4669            pw.print(prefix); pw.println("  requested permissions:");
4670            for (int i=0; i<perms.size(); i++) {
4671                String perm = perms.get(i);
4672                if (permissionNames != null
4673                        && !permissionNames.contains(perm)) {
4674                    continue;
4675                }
4676                pw.print(prefix); pw.print("    "); pw.println(perm);
4677            }
4678        }
4679
4680        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4681            PermissionsState permissionsState = ps.getPermissionsState();
4682            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4683        }
4684
4685        for (UserInfo user : users) {
4686            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4687            pw.print("ceDataInode=");
4688            pw.print(ps.getCeDataInode(user.id));
4689            pw.print(" installed=");
4690            pw.print(ps.getInstalled(user.id));
4691            pw.print(" hidden=");
4692            pw.print(ps.getHidden(user.id));
4693            pw.print(" suspended=");
4694            pw.print(ps.getSuspended(user.id));
4695            pw.print(" stopped=");
4696            pw.print(ps.getStopped(user.id));
4697            pw.print(" notLaunched=");
4698            pw.print(ps.getNotLaunched(user.id));
4699            pw.print(" enabled=");
4700            pw.print(ps.getEnabled(user.id));
4701            pw.print(" instant=");
4702            pw.print(ps.getInstantApp(user.id));
4703            pw.print(" virtual=");
4704            pw.println(ps.getVirtulalPreload(user.id));
4705
4706            String[] overlayPaths = ps.getOverlayPaths(user.id);
4707            if (overlayPaths != null && overlayPaths.length > 0) {
4708                pw.print(prefix); pw.println("  overlay paths:");
4709                for (String path : overlayPaths) {
4710                    pw.print(prefix); pw.print("    "); pw.println(path);
4711                }
4712            }
4713
4714            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4715            if (lastDisabledAppCaller != null) {
4716                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4717                        pw.println(lastDisabledAppCaller);
4718            }
4719
4720            if (ps.sharedUser == null) {
4721                PermissionsState permissionsState = ps.getPermissionsState();
4722                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4723                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4724                        .getRuntimePermissionStates(user.id), dumpAll);
4725            }
4726
4727            String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4728            if (harmfulAppWarning != null) {
4729                pw.print(prefix); pw.print("      harmfulAppWarning: ");
4730                pw.println(harmfulAppWarning);
4731            }
4732
4733            if (permissionNames == null) {
4734                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4735                if (cmp != null && cmp.size() > 0) {
4736                    pw.print(prefix); pw.println("    disabledComponents:");
4737                    for (String s : cmp) {
4738                        pw.print(prefix); pw.print("      "); pw.println(s);
4739                    }
4740                }
4741                cmp = ps.getEnabledComponents(user.id);
4742                if (cmp != null && cmp.size() > 0) {
4743                    pw.print(prefix); pw.println("    enabledComponents:");
4744                    for (String s : cmp) {
4745                        pw.print(prefix); pw.print("      "); pw.println(s);
4746                    }
4747                }
4748            }
4749        }
4750    }
4751
4752    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4753            DumpState dumpState, boolean checkin) {
4754        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4755        final Date date = new Date();
4756        boolean printedSomething = false;
4757        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4758        for (final PackageSetting ps : mPackages.values()) {
4759            if (packageName != null && !packageName.equals(ps.realName)
4760                    && !packageName.equals(ps.name)) {
4761                continue;
4762            }
4763            if (permissionNames != null
4764                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4765                continue;
4766            }
4767
4768            if (!checkin && packageName != null) {
4769                dumpState.setSharedUser(ps.sharedUser);
4770            }
4771
4772            if (!checkin && !printedSomething) {
4773                if (dumpState.onTitlePrinted())
4774                    pw.println();
4775                pw.println("Packages:");
4776                printedSomething = true;
4777            }
4778            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4779                    packageName != null);
4780        }
4781
4782        printedSomething = false;
4783        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4784            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4785                if (packageName != null && !packageName.equals(e.getKey())
4786                        && !packageName.equals(e.getValue())) {
4787                    continue;
4788                }
4789                if (!checkin) {
4790                    if (!printedSomething) {
4791                        if (dumpState.onTitlePrinted())
4792                            pw.println();
4793                        pw.println("Renamed packages:");
4794                        printedSomething = true;
4795                    }
4796                    pw.print("  ");
4797                } else {
4798                    pw.print("ren,");
4799                }
4800                pw.print(e.getKey());
4801                pw.print(checkin ? " -> " : ",");
4802                pw.println(e.getValue());
4803            }
4804        }
4805
4806        printedSomething = false;
4807        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4808            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4809                if (packageName != null && !packageName.equals(ps.realName)
4810                        && !packageName.equals(ps.name)) {
4811                    continue;
4812                }
4813                if (!checkin && !printedSomething) {
4814                    if (dumpState.onTitlePrinted())
4815                        pw.println();
4816                    pw.println("Hidden system packages:");
4817                    printedSomething = true;
4818                }
4819                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4820                        users, packageName != null);
4821            }
4822        }
4823    }
4824
4825    void dumpPackagesProto(ProtoOutputStream proto) {
4826        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4827
4828        final int count = mPackages.size();
4829        for (int i = 0; i < count; i++) {
4830            final PackageSetting ps = mPackages.valueAt(i);
4831            ps.writeToProto(proto, PackageServiceDumpProto.PACKAGES, users);
4832        }
4833    }
4834
4835    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4836            DumpState dumpState) {
4837        mPermissions.dumpPermissions(pw, packageName, permissionNames,
4838                (mReadExternalStorageEnforced == Boolean.TRUE), dumpState);
4839    }
4840
4841    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4842            DumpState dumpState, boolean checkin) {
4843        boolean printedSomething = false;
4844        for (SharedUserSetting su : mSharedUsers.values()) {
4845            if (packageName != null && su != dumpState.getSharedUser()) {
4846                continue;
4847            }
4848            if (permissionNames != null
4849                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4850                continue;
4851            }
4852            if (!checkin) {
4853                if (!printedSomething) {
4854                    if (dumpState.onTitlePrinted())
4855                        pw.println();
4856                    pw.println("Shared users:");
4857                    printedSomething = true;
4858                }
4859                pw.print("  SharedUser [");
4860                pw.print(su.name);
4861                pw.print("] (");
4862                pw.print(Integer.toHexString(System.identityHashCode(su)));
4863                        pw.println("):");
4864
4865                String prefix = "    ";
4866                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4867
4868                PermissionsState permissionsState = su.getPermissionsState();
4869                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4870
4871                for (int userId : UserManagerService.getInstance().getUserIds()) {
4872                    final int[] gids = permissionsState.computeGids(userId);
4873                    List<PermissionState> permissions = permissionsState
4874                            .getRuntimePermissionStates(userId);
4875                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4876                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4877                        dumpGidsLPr(pw, prefix + "  ", gids);
4878                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4879                                packageName != null);
4880                    }
4881                }
4882            } else {
4883                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4884            }
4885        }
4886    }
4887
4888    void dumpSharedUsersProto(ProtoOutputStream proto) {
4889        final int count = mSharedUsers.size();
4890        for (int i = 0; i < count; i++) {
4891            mSharedUsers.valueAt(i).writeToProto(proto, PackageServiceDumpProto.SHARED_USERS);
4892        }
4893    }
4894
4895    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4896        pw.println("Settings parse messages:");
4897        pw.print(mReadMessages.toString());
4898    }
4899
4900    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4901        if (mRestoredUserGrants.size() > 0) {
4902            pw.println();
4903            pw.println("Restored (pending) permission grants:");
4904            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4905                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4906                        mRestoredUserGrants.valueAt(userIndex);
4907                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4908                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4909                    pw.print("  User "); pw.println(userId);
4910
4911                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4912                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4913                        if (grants != null && grants.size() > 0) {
4914                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4915                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4916
4917                            for (RestoredPermissionGrant g : grants) {
4918                                pw.print("      ");
4919                                pw.print(g.permissionName);
4920                                if (g.granted) {
4921                                    pw.print(" GRANTED");
4922                                }
4923                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4924                                    pw.print(" user_set");
4925                                }
4926                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4927                                    pw.print(" user_fixed");
4928                                }
4929                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4930                                    pw.print(" revoke_on_upgrade");
4931                                }
4932                                pw.println();
4933                            }
4934                        }
4935                    }
4936                }
4937            }
4938            pw.println();
4939        }
4940    }
4941
4942    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4943        if (pkg == null) {
4944            pw.print("unknown");
4945        } else {
4946            // [base:10, config.mdpi, config.xhdpi:12]
4947            pw.print("[");
4948            pw.print("base");
4949            if (pkg.baseRevisionCode != 0) {
4950                pw.print(":"); pw.print(pkg.baseRevisionCode);
4951            }
4952            if (pkg.splitNames != null) {
4953                for (int i = 0; i < pkg.splitNames.length; i++) {
4954                    pw.print(", ");
4955                    pw.print(pkg.splitNames[i]);
4956                    if (pkg.splitRevisionCodes[i] != 0) {
4957                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4958                    }
4959                }
4960            }
4961            pw.print("]");
4962        }
4963    }
4964
4965    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4966        if (!ArrayUtils.isEmpty(gids)) {
4967            pw.print(prefix);
4968            pw.print("gids="); pw.println(
4969                    PackageManagerService.arrayToString(gids));
4970        }
4971    }
4972
4973    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4974            List<PermissionState> permissionStates, boolean dumpAll) {
4975        if (!permissionStates.isEmpty() || dumpAll) {
4976            pw.print(prefix); pw.println("runtime permissions:");
4977            for (PermissionState permissionState : permissionStates) {
4978                if (permissionNames != null
4979                        && !permissionNames.contains(permissionState.getName())) {
4980                    continue;
4981                }
4982                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4983                pw.print(": granted="); pw.print(permissionState.isGranted());
4984                    pw.println(permissionFlagsToString(", flags=",
4985                            permissionState.getFlags()));
4986            }
4987        }
4988    }
4989
4990    private static String permissionFlagsToString(String prefix, int flags) {
4991        StringBuilder flagsString = null;
4992        while (flags != 0) {
4993            if (flagsString == null) {
4994                flagsString = new StringBuilder();
4995                flagsString.append(prefix);
4996                flagsString.append("[ ");
4997            }
4998            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4999            flags &= ~flag;
5000            flagsString.append(PackageManager.permissionFlagToString(flag));
5001            flagsString.append(' ');
5002        }
5003        if (flagsString != null) {
5004            flagsString.append(']');
5005            return flagsString.toString();
5006        } else {
5007            return "";
5008        }
5009    }
5010
5011    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
5012            PermissionsState permissionsState) {
5013        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
5014        if (!permissionStates.isEmpty()) {
5015            pw.print(prefix); pw.println("install permissions:");
5016            for (PermissionState permissionState : permissionStates) {
5017                if (permissionNames != null
5018                        && !permissionNames.contains(permissionState.getName())) {
5019                    continue;
5020                }
5021                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5022                    pw.print(": granted="); pw.print(permissionState.isGranted());
5023                    pw.println(permissionFlagsToString(", flags=",
5024                        permissionState.getFlags()));
5025            }
5026        }
5027    }
5028
5029    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
5030        if (sync) {
5031            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
5032        } else {
5033            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
5034        }
5035    }
5036
5037    private final class RuntimePermissionPersistence {
5038        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
5039        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
5040
5041        private final Handler mHandler = new MyHandler();
5042
5043        private final Object mPersistenceLock;
5044
5045        @GuardedBy("mLock")
5046        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
5047
5048        @GuardedBy("mLock")
5049        // The mapping keys are user ids.
5050        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
5051
5052        @GuardedBy("mLock")
5053        // The mapping keys are user ids.
5054        private final SparseArray<String> mFingerprints = new SparseArray<>();
5055
5056        @GuardedBy("mLock")
5057        // The mapping keys are user ids.
5058        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
5059
5060        public RuntimePermissionPersistence(Object persistenceLock) {
5061            mPersistenceLock = persistenceLock;
5062        }
5063
5064        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
5065            return mDefaultPermissionsGranted.get(userId);
5066        }
5067
5068        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
5069            mFingerprints.put(userId, Build.FINGERPRINT);
5070            writePermissionsForUserAsyncLPr(userId);
5071        }
5072
5073        public void writePermissionsForUserSyncLPr(int userId) {
5074            mHandler.removeMessages(userId);
5075            writePermissionsSync(userId);
5076        }
5077
5078        public void writePermissionsForUserAsyncLPr(int userId) {
5079            final long currentTimeMillis = SystemClock.uptimeMillis();
5080
5081            if (mWriteScheduled.get(userId)) {
5082                mHandler.removeMessages(userId);
5083
5084                // If enough time passed, write without holding off anymore.
5085                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
5086                        .get(userId);
5087                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
5088                        - lastNotWrittenMutationTimeMillis;
5089                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
5090                    mHandler.obtainMessage(userId).sendToTarget();
5091                    return;
5092                }
5093
5094                // Hold off a bit more as settings are frequently changing.
5095                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
5096                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
5097                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
5098                        maxDelayMillis);
5099
5100                Message message = mHandler.obtainMessage(userId);
5101                mHandler.sendMessageDelayed(message, writeDelayMillis);
5102            } else {
5103                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
5104                Message message = mHandler.obtainMessage(userId);
5105                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
5106                mWriteScheduled.put(userId, true);
5107            }
5108        }
5109
5110        private void writePermissionsSync(int userId) {
5111            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId),
5112                    "package-perms-" + userId);
5113
5114            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
5115            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
5116
5117            synchronized (mPersistenceLock) {
5118                mWriteScheduled.delete(userId);
5119
5120                final int packageCount = mPackages.size();
5121                for (int i = 0; i < packageCount; i++) {
5122                    String packageName = mPackages.keyAt(i);
5123                    PackageSetting packageSetting = mPackages.valueAt(i);
5124                    if (packageSetting.sharedUser == null) {
5125                        PermissionsState permissionsState = packageSetting.getPermissionsState();
5126                        List<PermissionState> permissionsStates = permissionsState
5127                                .getRuntimePermissionStates(userId);
5128                        if (!permissionsStates.isEmpty()) {
5129                            permissionsForPackage.put(packageName, permissionsStates);
5130                        }
5131                    }
5132                }
5133
5134                final int sharedUserCount = mSharedUsers.size();
5135                for (int i = 0; i < sharedUserCount; i++) {
5136                    String sharedUserName = mSharedUsers.keyAt(i);
5137                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
5138                    PermissionsState permissionsState = sharedUser.getPermissionsState();
5139                    List<PermissionState> permissionsStates = permissionsState
5140                            .getRuntimePermissionStates(userId);
5141                    if (!permissionsStates.isEmpty()) {
5142                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
5143                    }
5144                }
5145            }
5146
5147            FileOutputStream out = null;
5148            try {
5149                out = destination.startWrite();
5150
5151                XmlSerializer serializer = Xml.newSerializer();
5152                serializer.setOutput(out, StandardCharsets.UTF_8.name());
5153                serializer.setFeature(
5154                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
5155                serializer.startDocument(null, true);
5156
5157                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
5158
5159                String fingerprint = mFingerprints.get(userId);
5160                if (fingerprint != null) {
5161                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
5162                }
5163
5164                final int packageCount = permissionsForPackage.size();
5165                for (int i = 0; i < packageCount; i++) {
5166                    String packageName = permissionsForPackage.keyAt(i);
5167                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
5168                    serializer.startTag(null, TAG_PACKAGE);
5169                    serializer.attribute(null, ATTR_NAME, packageName);
5170                    writePermissions(serializer, permissionStates);
5171                    serializer.endTag(null, TAG_PACKAGE);
5172                }
5173
5174                final int sharedUserCount = permissionsForSharedUser.size();
5175                for (int i = 0; i < sharedUserCount; i++) {
5176                    String packageName = permissionsForSharedUser.keyAt(i);
5177                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
5178                    serializer.startTag(null, TAG_SHARED_USER);
5179                    serializer.attribute(null, ATTR_NAME, packageName);
5180                    writePermissions(serializer, permissionStates);
5181                    serializer.endTag(null, TAG_SHARED_USER);
5182                }
5183
5184                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
5185
5186                // Now any restored permission grants that are waiting for the apps
5187                // in question to be installed.  These are stored as per-package
5188                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
5189                // number of individual permission grant entities.
5190                if (mRestoredUserGrants.get(userId) != null) {
5191                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
5192                            mRestoredUserGrants.get(userId);
5193                    if (restoredGrants != null) {
5194                        final int pkgCount = restoredGrants.size();
5195                        for (int i = 0; i < pkgCount; i++) {
5196                            final ArraySet<RestoredPermissionGrant> pkgGrants =
5197                                    restoredGrants.valueAt(i);
5198                            if (pkgGrants != null && pkgGrants.size() > 0) {
5199                                final String pkgName = restoredGrants.keyAt(i);
5200                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5201                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
5202
5203                                final int N = pkgGrants.size();
5204                                for (int z = 0; z < N; z++) {
5205                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
5206                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
5207                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
5208
5209                                    if (g.granted) {
5210                                        serializer.attribute(null, ATTR_GRANTED, "true");
5211                                    }
5212
5213                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
5214                                        serializer.attribute(null, ATTR_USER_SET, "true");
5215                                    }
5216                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
5217                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
5218                                    }
5219                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
5220                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
5221                                    }
5222                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
5223                                }
5224                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5225                            }
5226                        }
5227                    }
5228                }
5229
5230                serializer.endDocument();
5231                destination.finishWrite(out);
5232
5233                if (Build.FINGERPRINT.equals(fingerprint)) {
5234                    mDefaultPermissionsGranted.put(userId, true);
5235                }
5236            // Any error while writing is fatal.
5237            } catch (Throwable t) {
5238                Slog.wtf(PackageManagerService.TAG,
5239                        "Failed to write settings, restoring backup", t);
5240                destination.failWrite(out);
5241            } finally {
5242                IoUtils.closeQuietly(out);
5243            }
5244        }
5245
5246        private void onUserRemovedLPw(int userId) {
5247            // Make sure we do not
5248            mHandler.removeMessages(userId);
5249
5250            for (SettingBase sb : mPackages.values()) {
5251                revokeRuntimePermissionsAndClearFlags(sb, userId);
5252            }
5253
5254            for (SettingBase sb : mSharedUsers.values()) {
5255                revokeRuntimePermissionsAndClearFlags(sb, userId);
5256            }
5257
5258            mDefaultPermissionsGranted.delete(userId);
5259            mFingerprints.remove(userId);
5260        }
5261
5262        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5263            PermissionsState permissionsState = sb.getPermissionsState();
5264            for (PermissionState permissionState
5265                    : permissionsState.getRuntimePermissionStates(userId)) {
5266                BasePermission bp = mPermissions.getPermission(permissionState.getName());
5267                if (bp != null) {
5268                    permissionsState.revokeRuntimePermission(bp, userId);
5269                    permissionsState.updatePermissionFlags(bp, userId,
5270                            PackageManager.MASK_PERMISSION_FLAGS, 0);
5271                }
5272            }
5273        }
5274
5275        public void deleteUserRuntimePermissionsFile(int userId) {
5276            getUserRuntimePermissionsFile(userId).delete();
5277        }
5278
5279        public void readStateForUserSyncLPr(int userId) {
5280            File permissionsFile = getUserRuntimePermissionsFile(userId);
5281            if (!permissionsFile.exists()) {
5282                return;
5283            }
5284
5285            FileInputStream in;
5286            try {
5287                in = new AtomicFile(permissionsFile).openRead();
5288            } catch (FileNotFoundException fnfe) {
5289                Slog.i(PackageManagerService.TAG, "No permissions state");
5290                return;
5291            }
5292
5293            try {
5294                XmlPullParser parser = Xml.newPullParser();
5295                parser.setInput(in, null);
5296                parseRuntimePermissionsLPr(parser, userId);
5297
5298            } catch (XmlPullParserException | IOException e) {
5299                throw new IllegalStateException("Failed parsing permissions file: "
5300                        + permissionsFile , e);
5301            } finally {
5302                IoUtils.closeQuietly(in);
5303            }
5304        }
5305
5306        // Backup/restore support
5307
5308        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
5309                boolean isGranted, int restoredFlagSet, int userId) {
5310            // This change will be remembered at write-settings time
5311            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
5312                    mRestoredUserGrants.get(userId);
5313            if (grantsByPackage == null) {
5314                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
5315                mRestoredUserGrants.put(userId, grantsByPackage);
5316            }
5317
5318            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
5319            if (grants == null) {
5320                grants = new ArraySet<RestoredPermissionGrant>();
5321                grantsByPackage.put(pkgName, grants);
5322            }
5323
5324            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
5325                    isGranted, restoredFlagSet);
5326            grants.add(grant);
5327        }
5328
5329        // Private internals
5330
5331        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5332                throws IOException, XmlPullParserException {
5333            final int outerDepth = parser.getDepth();
5334            int type;
5335            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5336                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5337                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5338                    continue;
5339                }
5340
5341                switch (parser.getName()) {
5342                    case TAG_RUNTIME_PERMISSIONS: {
5343                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5344                        mFingerprints.put(userId, fingerprint);
5345                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5346                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
5347                    } break;
5348
5349                    case TAG_PACKAGE: {
5350                        String name = parser.getAttributeValue(null, ATTR_NAME);
5351                        PackageSetting ps = mPackages.get(name);
5352                        if (ps == null) {
5353                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5354                            XmlUtils.skipCurrentTag(parser);
5355                            continue;
5356                        }
5357                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5358                    } break;
5359
5360                    case TAG_SHARED_USER: {
5361                        String name = parser.getAttributeValue(null, ATTR_NAME);
5362                        SharedUserSetting sus = mSharedUsers.get(name);
5363                        if (sus == null) {
5364                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5365                            XmlUtils.skipCurrentTag(parser);
5366                            continue;
5367                        }
5368                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5369                    } break;
5370
5371                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
5372                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
5373                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
5374                    } break;
5375                }
5376            }
5377        }
5378
5379        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
5380                final String pkgName, final int userId) throws IOException, XmlPullParserException {
5381            final int outerDepth = parser.getDepth();
5382            int type;
5383            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5384                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5385                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5386                    continue;
5387                }
5388
5389                switch (parser.getName()) {
5390                    case TAG_PERMISSION_ENTRY: {
5391                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
5392                        final boolean isGranted = "true".equals(
5393                                parser.getAttributeValue(null, ATTR_GRANTED));
5394
5395                        int permBits = 0;
5396                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
5397                            permBits |= FLAG_PERMISSION_USER_SET;
5398                        }
5399                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
5400                            permBits |= FLAG_PERMISSION_USER_FIXED;
5401                        }
5402                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
5403                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
5404                        }
5405
5406                        if (isGranted || permBits != 0) {
5407                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5408                        }
5409                    } break;
5410                }
5411            }
5412        }
5413
5414        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5415                int userId) throws IOException, XmlPullParserException {
5416            final int outerDepth = parser.getDepth();
5417            int type;
5418            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5419                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5420                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5421                    continue;
5422                }
5423
5424                switch (parser.getName()) {
5425                    case TAG_ITEM: {
5426                        String name = parser.getAttributeValue(null, ATTR_NAME);
5427                        BasePermission bp = mPermissions.getPermission(name);
5428                        if (bp == null) {
5429                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5430                            XmlUtils.skipCurrentTag(parser);
5431                            continue;
5432                        }
5433
5434                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5435                        final boolean granted = grantedStr == null
5436                                || Boolean.parseBoolean(grantedStr);
5437
5438                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5439                        final int flags = (flagsStr != null)
5440                                ? Integer.parseInt(flagsStr, 16) : 0;
5441
5442                        if (granted) {
5443                            permissionsState.grantRuntimePermission(bp, userId);
5444                            permissionsState.updatePermissionFlags(bp, userId,
5445                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5446                        } else {
5447                            permissionsState.updatePermissionFlags(bp, userId,
5448                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5449                        }
5450
5451                    } break;
5452                }
5453            }
5454        }
5455
5456        private void writePermissions(XmlSerializer serializer,
5457                List<PermissionState> permissionStates) throws IOException {
5458            for (PermissionState permissionState : permissionStates) {
5459                serializer.startTag(null, TAG_ITEM);
5460                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5461                serializer.attribute(null, ATTR_GRANTED,
5462                        String.valueOf(permissionState.isGranted()));
5463                serializer.attribute(null, ATTR_FLAGS,
5464                        Integer.toHexString(permissionState.getFlags()));
5465                serializer.endTag(null, TAG_ITEM);
5466            }
5467        }
5468
5469        private final class MyHandler extends Handler {
5470            public MyHandler() {
5471                super(BackgroundThread.getHandler().getLooper());
5472            }
5473
5474            @Override
5475            public void handleMessage(Message message) {
5476                final int userId = message.what;
5477                Runnable callback = (Runnable) message.obj;
5478                writePermissionsSync(userId);
5479                if (callback != null) {
5480                    callback.run();
5481                }
5482            }
5483        }
5484    }
5485}
5486