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