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