Settings.java revision 77029c5b16351775cb2333369ef9a4bc1d9acf58
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        // Keep the old stopped packages around until we know the new ones have
1998        // been successfully written.
1999        File userPackagesStateFile = getUserPackagesStateFile(userId);
2000        File backupFile = getUserPackagesStateBackupFile(userId);
2001        new File(userPackagesStateFile.getParent()).mkdirs();
2002        if (userPackagesStateFile.exists()) {
2003            // Presence of backup settings file indicates that we failed
2004            // to persist packages earlier. So preserve the older
2005            // backup for future reference since the current packages
2006            // might have been corrupted.
2007            if (!backupFile.exists()) {
2008                if (!userPackagesStateFile.renameTo(backupFile)) {
2009                    Slog.wtf(PackageManagerService.TAG,
2010                            "Unable to backup user packages state file, "
2011                            + "current changes will be lost at reboot");
2012                    return;
2013                }
2014            } else {
2015                userPackagesStateFile.delete();
2016                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
2017            }
2018        }
2019
2020        try {
2021            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
2022            final BufferedOutputStream str = new BufferedOutputStream(fstr);
2023
2024            final XmlSerializer serializer = new FastXmlSerializer();
2025            serializer.setOutput(str, StandardCharsets.UTF_8.name());
2026            serializer.startDocument(null, true);
2027            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2028
2029            serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
2030
2031            for (final PackageSetting pkg : mPackages.values()) {
2032                final PackageUserState ustate = pkg.readUserState(userId);
2033                if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
2034
2035                serializer.startTag(null, TAG_PACKAGE);
2036                serializer.attribute(null, ATTR_NAME, pkg.name);
2037                if (ustate.ceDataInode != 0) {
2038                    XmlUtils.writeLongAttribute(serializer, ATTR_CE_DATA_INODE, ustate.ceDataInode);
2039                }
2040                if (!ustate.installed) {
2041                    serializer.attribute(null, ATTR_INSTALLED, "false");
2042                }
2043                if (ustate.stopped) {
2044                    serializer.attribute(null, ATTR_STOPPED, "true");
2045                }
2046                if (ustate.notLaunched) {
2047                    serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
2048                }
2049                if (ustate.hidden) {
2050                    serializer.attribute(null, ATTR_HIDDEN, "true");
2051                }
2052                if (ustate.suspended) {
2053                    serializer.attribute(null, ATTR_SUSPENDED, "true");
2054                }
2055                if (ustate.instantApp) {
2056                    serializer.attribute(null, ATTR_INSTANT_APP, "true");
2057                }
2058                if (ustate.virtualPreload) {
2059                    serializer.attribute(null, ATTR_VIRTUAL_PRELOAD, "true");
2060                }
2061                if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
2062                    serializer.attribute(null, ATTR_ENABLED,
2063                            Integer.toString(ustate.enabled));
2064                    if (ustate.lastDisableAppCaller != null) {
2065                        serializer.attribute(null, ATTR_ENABLED_CALLER,
2066                                ustate.lastDisableAppCaller);
2067                    }
2068                }
2069                if (ustate.domainVerificationStatus !=
2070                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
2071                    XmlUtils.writeIntAttribute(serializer, ATTR_DOMAIN_VERIFICATON_STATE,
2072                            ustate.domainVerificationStatus);
2073                }
2074                if (ustate.appLinkGeneration != 0) {
2075                    XmlUtils.writeIntAttribute(serializer, ATTR_APP_LINK_GENERATION,
2076                            ustate.appLinkGeneration);
2077                }
2078                if (ustate.installReason != PackageManager.INSTALL_REASON_UNKNOWN) {
2079                    serializer.attribute(null, ATTR_INSTALL_REASON,
2080                            Integer.toString(ustate.installReason));
2081                }
2082                if (ustate.harmfulAppWarning != null) {
2083                    serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
2084                            ustate.harmfulAppWarning);
2085                }
2086                if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
2087                    serializer.startTag(null, TAG_ENABLED_COMPONENTS);
2088                    for (final String name : ustate.enabledComponents) {
2089                        serializer.startTag(null, TAG_ITEM);
2090                        serializer.attribute(null, ATTR_NAME, name);
2091                        serializer.endTag(null, TAG_ITEM);
2092                    }
2093                    serializer.endTag(null, TAG_ENABLED_COMPONENTS);
2094                }
2095                if (!ArrayUtils.isEmpty(ustate.disabledComponents)) {
2096                    serializer.startTag(null, TAG_DISABLED_COMPONENTS);
2097                    for (final String name : ustate.disabledComponents) {
2098                        serializer.startTag(null, TAG_ITEM);
2099                        serializer.attribute(null, ATTR_NAME, name);
2100                        serializer.endTag(null, TAG_ITEM);
2101                    }
2102                    serializer.endTag(null, TAG_DISABLED_COMPONENTS);
2103                }
2104
2105                serializer.endTag(null, TAG_PACKAGE);
2106            }
2107
2108            writePreferredActivitiesLPr(serializer, userId, true);
2109            writePersistentPreferredActivitiesLPr(serializer, userId);
2110            writeCrossProfileIntentFiltersLPr(serializer, userId);
2111            writeDefaultAppsLPr(serializer, userId);
2112            writeBlockUninstallPackagesLPr(serializer, userId);
2113
2114            serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
2115
2116            serializer.endDocument();
2117
2118            str.flush();
2119            FileUtils.sync(fstr);
2120            str.close();
2121
2122            // New settings successfully written, old ones are no longer
2123            // needed.
2124            backupFile.delete();
2125            FileUtils.setPermissions(userPackagesStateFile.toString(),
2126                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
2127                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2128                    -1, -1);
2129
2130            // Done, all is good!
2131            return;
2132        } catch(java.io.IOException e) {
2133            Slog.wtf(PackageManagerService.TAG,
2134                    "Unable to write package manager user packages state, "
2135                    + " current changes will be lost at reboot", e);
2136        }
2137
2138        // Clean up partially written files
2139        if (userPackagesStateFile.exists()) {
2140            if (!userPackagesStateFile.delete()) {
2141                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
2142                        + mStoppedPackagesFilename);
2143            }
2144        }
2145    }
2146
2147    void readInstallPermissionsLPr(XmlPullParser parser,
2148            PermissionsState permissionsState) throws IOException, XmlPullParserException {
2149        int outerDepth = parser.getDepth();
2150        int type;
2151        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2152                && (type != XmlPullParser.END_TAG
2153                || parser.getDepth() > outerDepth)) {
2154            if (type == XmlPullParser.END_TAG
2155                    || type == XmlPullParser.TEXT) {
2156                continue;
2157            }
2158            String tagName = parser.getName();
2159            if (tagName.equals(TAG_ITEM)) {
2160                String name = parser.getAttributeValue(null, ATTR_NAME);
2161
2162                BasePermission bp = mPermissions.getPermission(name);
2163                if (bp == null) {
2164                    Slog.w(PackageManagerService.TAG, "Unknown permission: " + name);
2165                    XmlUtils.skipCurrentTag(parser);
2166                    continue;
2167                }
2168
2169                String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
2170                final boolean granted = grantedStr == null
2171                        || Boolean.parseBoolean(grantedStr);
2172
2173                String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
2174                final int flags = (flagsStr != null)
2175                        ? Integer.parseInt(flagsStr, 16) : 0;
2176
2177                if (granted) {
2178                    if (permissionsState.grantInstallPermission(bp) ==
2179                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
2180                        Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2181                        XmlUtils.skipCurrentTag(parser);
2182                    } else {
2183                        permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2184                                PackageManager.MASK_PERMISSION_FLAGS, flags);
2185                    }
2186                } else {
2187                    if (permissionsState.revokeInstallPermission(bp) ==
2188                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
2189                        Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2190                        XmlUtils.skipCurrentTag(parser);
2191                    } else {
2192                        permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2193                                PackageManager.MASK_PERMISSION_FLAGS, flags);
2194                    }
2195                }
2196            } else {
2197                Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: "
2198                        + parser.getName());
2199                XmlUtils.skipCurrentTag(parser);
2200            }
2201        }
2202    }
2203
2204    void writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates)
2205            throws IOException {
2206        if (permissionStates.isEmpty()) {
2207            return;
2208        }
2209
2210        serializer.startTag(null, TAG_PERMISSIONS);
2211
2212        for (PermissionState permissionState : permissionStates) {
2213            serializer.startTag(null, TAG_ITEM);
2214            serializer.attribute(null, ATTR_NAME, permissionState.getName());
2215            serializer.attribute(null, ATTR_GRANTED, String.valueOf(permissionState.isGranted()));
2216            serializer.attribute(null, ATTR_FLAGS, Integer.toHexString(permissionState.getFlags()));
2217            serializer.endTag(null, TAG_ITEM);
2218        }
2219
2220        serializer.endTag(null, TAG_PERMISSIONS);
2221    }
2222
2223    void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames)
2224            throws IOException {
2225        if (childPackageNames == null) {
2226            return;
2227        }
2228        final int childCount = childPackageNames.size();
2229        for (int i = 0; i < childCount; i++) {
2230            String childPackageName = childPackageNames.get(i);
2231            serializer.startTag(null, TAG_CHILD_PACKAGE);
2232            serializer.attribute(null, ATTR_NAME, childPackageName);
2233            serializer.endTag(null, TAG_CHILD_PACKAGE);
2234        }
2235    }
2236
2237    void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)
2238            throws IOException, XmlPullParserException {
2239        int outerDepth = parser.getDepth();
2240        int type;
2241        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2242                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2243            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2244                continue;
2245            }
2246            String libName = parser.getAttributeValue(null, ATTR_NAME);
2247            String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION);
2248
2249            long libVersion = -1;
2250            try {
2251                libVersion = Long.parseLong(libVersionStr);
2252            } catch (NumberFormatException e) {
2253                // ignore
2254            }
2255
2256            if (libName != null && libVersion >= 0) {
2257                outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class,
2258                        outPs.usesStaticLibraries, libName);
2259                outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong(
2260                        outPs.usesStaticLibrariesVersions, libVersion);
2261            }
2262
2263            XmlUtils.skipCurrentTag(parser);
2264        }
2265    }
2266
2267    void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries,
2268            long[] usesStaticLibraryVersions) throws IOException {
2269        if (ArrayUtils.isEmpty(usesStaticLibraries) || ArrayUtils.isEmpty(usesStaticLibraryVersions)
2270                || usesStaticLibraries.length != usesStaticLibraryVersions.length) {
2271            return;
2272        }
2273        final int libCount = usesStaticLibraries.length;
2274        for (int i = 0; i < libCount; i++) {
2275            final String libName = usesStaticLibraries[i];
2276            final long libVersion = usesStaticLibraryVersions[i];
2277            serializer.startTag(null, TAG_USES_STATIC_LIB);
2278            serializer.attribute(null, ATTR_NAME, libName);
2279            serializer.attribute(null, ATTR_VERSION, Long.toString(libVersion));
2280            serializer.endTag(null, TAG_USES_STATIC_LIB);
2281        }
2282    }
2283
2284    // Note: assumed "stopped" field is already cleared in all packages.
2285    // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
2286    void readStoppedLPw() {
2287        FileInputStream str = null;
2288        if (mBackupStoppedPackagesFilename.exists()) {
2289            try {
2290                str = new FileInputStream(mBackupStoppedPackagesFilename);
2291                mReadMessages.append("Reading from backup stopped packages file\n");
2292                PackageManagerService.reportSettingsProblem(Log.INFO,
2293                        "Need to read from backup stopped packages file");
2294                if (mSettingsFilename.exists()) {
2295                    // If both the backup and normal file exist, we
2296                    // ignore the normal one since it might have been
2297                    // corrupted.
2298                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
2299                            + mStoppedPackagesFilename);
2300                    mStoppedPackagesFilename.delete();
2301                }
2302            } catch (java.io.IOException e) {
2303                // We'll try for the normal settings file.
2304            }
2305        }
2306
2307        try {
2308            if (str == null) {
2309                if (!mStoppedPackagesFilename.exists()) {
2310                    mReadMessages.append("No stopped packages file found\n");
2311                    PackageManagerService.reportSettingsProblem(Log.INFO,
2312                            "No stopped packages file file; assuming all started");
2313                    // At first boot, make sure no packages are stopped.
2314                    // We usually want to have third party apps initialize
2315                    // in the stopped state, but not at first boot.
2316                    for (PackageSetting pkg : mPackages.values()) {
2317                        pkg.setStopped(false, 0);
2318                        pkg.setNotLaunched(false, 0);
2319                    }
2320                    return;
2321                }
2322                str = new FileInputStream(mStoppedPackagesFilename);
2323            }
2324            final XmlPullParser parser = Xml.newPullParser();
2325            parser.setInput(str, null);
2326
2327            int type;
2328            while ((type=parser.next()) != XmlPullParser.START_TAG
2329                       && type != XmlPullParser.END_DOCUMENT) {
2330                ;
2331            }
2332
2333            if (type != XmlPullParser.START_TAG) {
2334                mReadMessages.append("No start tag found in stopped packages file\n");
2335                PackageManagerService.reportSettingsProblem(Log.WARN,
2336                        "No start tag found in package manager stopped packages");
2337                return;
2338            }
2339
2340            int outerDepth = parser.getDepth();
2341            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2342                   && (type != XmlPullParser.END_TAG
2343                           || parser.getDepth() > outerDepth)) {
2344                if (type == XmlPullParser.END_TAG
2345                        || type == XmlPullParser.TEXT) {
2346                    continue;
2347                }
2348
2349                String tagName = parser.getName();
2350                if (tagName.equals(TAG_PACKAGE)) {
2351                    String name = parser.getAttributeValue(null, ATTR_NAME);
2352                    PackageSetting ps = mPackages.get(name);
2353                    if (ps != null) {
2354                        ps.setStopped(true, 0);
2355                        if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
2356                            ps.setNotLaunched(true, 0);
2357                        }
2358                    } else {
2359                        Slog.w(PackageManagerService.TAG,
2360                                "No package known for stopped package " + name);
2361                    }
2362                    XmlUtils.skipCurrentTag(parser);
2363                } else {
2364                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
2365                          + parser.getName());
2366                    XmlUtils.skipCurrentTag(parser);
2367                }
2368            }
2369
2370            str.close();
2371
2372        } catch (XmlPullParserException e) {
2373            mReadMessages.append("Error reading: " + e.toString());
2374            PackageManagerService.reportSettingsProblem(Log.ERROR,
2375                    "Error reading stopped packages: " + e);
2376            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2377                    e);
2378
2379        } catch (java.io.IOException e) {
2380            mReadMessages.append("Error reading: " + e.toString());
2381            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2382            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2383                    e);
2384
2385        }
2386    }
2387
2388    void writeLPr() {
2389        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
2390
2391        // Keep the old settings around until we know the new ones have
2392        // been successfully written.
2393        if (mSettingsFilename.exists()) {
2394            // Presence of backup settings file indicates that we failed
2395            // to persist settings earlier. So preserve the older
2396            // backup for future reference since the current settings
2397            // might have been corrupted.
2398            if (!mBackupSettingsFilename.exists()) {
2399                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
2400                    Slog.wtf(PackageManagerService.TAG,
2401                            "Unable to backup package manager settings, "
2402                            + " current changes will be lost at reboot");
2403                    return;
2404                }
2405            } else {
2406                mSettingsFilename.delete();
2407                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
2408            }
2409        }
2410
2411        mPastSignatures.clear();
2412
2413        try {
2414            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
2415            BufferedOutputStream str = new BufferedOutputStream(fstr);
2416
2417            //XmlSerializer serializer = XmlUtils.serializerInstance();
2418            XmlSerializer serializer = new FastXmlSerializer();
2419            serializer.setOutput(str, StandardCharsets.UTF_8.name());
2420            serializer.startDocument(null, true);
2421            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2422
2423            serializer.startTag(null, "packages");
2424
2425            for (int i = 0; i < mVersion.size(); i++) {
2426                final String volumeUuid = mVersion.keyAt(i);
2427                final VersionInfo ver = mVersion.valueAt(i);
2428
2429                serializer.startTag(null, TAG_VERSION);
2430                XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid);
2431                XmlUtils.writeIntAttribute(serializer, ATTR_SDK_VERSION, ver.sdkVersion);
2432                XmlUtils.writeIntAttribute(serializer, ATTR_DATABASE_VERSION, ver.databaseVersion);
2433                XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint);
2434                serializer.endTag(null, TAG_VERSION);
2435            }
2436
2437            if (mVerifierDeviceIdentity != null) {
2438                serializer.startTag(null, "verifier");
2439                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
2440                serializer.endTag(null, "verifier");
2441            }
2442
2443            if (mReadExternalStorageEnforced != null) {
2444                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
2445                serializer.attribute(
2446                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
2447                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
2448            }
2449
2450            serializer.startTag(null, "permission-trees");
2451            mPermissions.writePermissionTrees(serializer);
2452            serializer.endTag(null, "permission-trees");
2453
2454            serializer.startTag(null, "permissions");
2455            mPermissions.writePermissions(serializer);
2456            serializer.endTag(null, "permissions");
2457
2458            for (final PackageSetting pkg : mPackages.values()) {
2459                writePackageLPr(serializer, pkg);
2460            }
2461
2462            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
2463                writeDisabledSysPackageLPr(serializer, pkg);
2464            }
2465
2466            for (final SharedUserSetting usr : mSharedUsers.values()) {
2467                serializer.startTag(null, "shared-user");
2468                serializer.attribute(null, ATTR_NAME, usr.name);
2469                serializer.attribute(null, "userId",
2470                        Integer.toString(usr.userId));
2471                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
2472                writePermissionsLPr(serializer, usr.getPermissionsState()
2473                        .getInstallPermissionStates());
2474                serializer.endTag(null, "shared-user");
2475            }
2476
2477            if (mPackagesToBeCleaned.size() > 0) {
2478                for (PackageCleanItem item : mPackagesToBeCleaned) {
2479                    final String userStr = Integer.toString(item.userId);
2480                    serializer.startTag(null, "cleaning-package");
2481                    serializer.attribute(null, ATTR_NAME, item.packageName);
2482                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
2483                    serializer.attribute(null, ATTR_USER, userStr);
2484                    serializer.endTag(null, "cleaning-package");
2485                }
2486            }
2487
2488            if (mRenamedPackages.size() > 0) {
2489                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
2490                    serializer.startTag(null, "renamed-package");
2491                    serializer.attribute(null, "new", e.getKey());
2492                    serializer.attribute(null, "old", e.getValue());
2493                    serializer.endTag(null, "renamed-package");
2494                }
2495            }
2496
2497            final int numIVIs = mRestoredIntentFilterVerifications.size();
2498            if (numIVIs > 0) {
2499                if (DEBUG_DOMAIN_VERIFICATION) {
2500                    Slog.i(TAG, "Writing restored-ivi entries to packages.xml");
2501                }
2502                serializer.startTag(null, "restored-ivi");
2503                for (int i = 0; i < numIVIs; i++) {
2504                    IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i);
2505                    writeDomainVerificationsLPr(serializer, ivi);
2506                }
2507                serializer.endTag(null, "restored-ivi");
2508            } else {
2509                if (DEBUG_DOMAIN_VERIFICATION) {
2510                    Slog.i(TAG, "  no restored IVI entries to write");
2511                }
2512            }
2513
2514            mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
2515
2516            serializer.endTag(null, "packages");
2517
2518            serializer.endDocument();
2519
2520            str.flush();
2521            FileUtils.sync(fstr);
2522            str.close();
2523
2524            // New settings successfully written, old ones are no longer
2525            // needed.
2526            mBackupSettingsFilename.delete();
2527            FileUtils.setPermissions(mSettingsFilename.toString(),
2528                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
2529                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2530                    -1, -1);
2531
2532            writeKernelMappingLPr();
2533            writePackageListLPr();
2534            writeAllUsersPackageRestrictionsLPr();
2535            writeAllRuntimePermissionsLPr();
2536            return;
2537
2538        } catch(java.io.IOException e) {
2539            Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
2540                    + "current changes will be lost at reboot", e);
2541        }
2542        // Clean up partially written files
2543        if (mSettingsFilename.exists()) {
2544            if (!mSettingsFilename.delete()) {
2545                Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
2546                        + mSettingsFilename);
2547            }
2548        }
2549        //Debug.stopMethodTracing();
2550    }
2551
2552    private void writeKernelRemoveUserLPr(int userId) {
2553        if (mKernelMappingFilename == null) return;
2554
2555        File removeUserIdFile = new File(mKernelMappingFilename, "remove_userid");
2556        if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + userId + " to " + removeUserIdFile
2557                .getAbsolutePath());
2558        writeIntToFile(removeUserIdFile, userId);
2559    }
2560
2561    void writeKernelMappingLPr() {
2562        if (mKernelMappingFilename == null) return;
2563
2564        final String[] known = mKernelMappingFilename.list();
2565        final ArraySet<String> knownSet = new ArraySet<>(known.length);
2566        for (String name : known) {
2567            knownSet.add(name);
2568        }
2569
2570        for (final PackageSetting ps : mPackages.values()) {
2571            // Package is actively claimed
2572            knownSet.remove(ps.name);
2573            writeKernelMappingLPr(ps);
2574        }
2575
2576        // Remove any unclaimed mappings
2577        for (int i = 0; i < knownSet.size(); i++) {
2578            final String name = knownSet.valueAt(i);
2579            if (DEBUG_KERNEL) Slog.d(TAG, "Dropping mapping " + name);
2580
2581            mKernelMapping.remove(name);
2582            new File(mKernelMappingFilename, name).delete();
2583        }
2584    }
2585
2586    void writeKernelMappingLPr(PackageSetting ps) {
2587        if (mKernelMappingFilename == null || ps == null || ps.name == null) return;
2588
2589        KernelPackageState cur = mKernelMapping.get(ps.name);
2590        final boolean firstTime = cur == null;
2591        int[] excludedUserIds = ps.getNotInstalledUserIds();
2592        final boolean userIdsChanged = firstTime
2593                || !Arrays.equals(excludedUserIds, cur.excludedUserIds);
2594
2595        // Package directory
2596        final File dir = new File(mKernelMappingFilename, ps.name);
2597
2598        if (firstTime) {
2599            dir.mkdir();
2600            // Create a new mapping state
2601            cur = new KernelPackageState();
2602            mKernelMapping.put(ps.name, cur);
2603        }
2604
2605        // If mapping is incorrect or non-existent, write the appid file
2606        if (cur.appId != ps.appId) {
2607            final File appIdFile = new File(dir, "appid");
2608            writeIntToFile(appIdFile, ps.appId);
2609            if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + ps.name + " to " + ps.appId);
2610        }
2611
2612        if (userIdsChanged) {
2613            // Build the exclusion list -- the ids to add to the exclusion list
2614            for (int i = 0; i < excludedUserIds.length; i++) {
2615                if (cur.excludedUserIds == null || !ArrayUtils.contains(cur.excludedUserIds,
2616                        excludedUserIds[i])) {
2617                    writeIntToFile(new File(dir, "excluded_userids"), excludedUserIds[i]);
2618                    if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + excludedUserIds[i] + " to "
2619                            + ps.name + "/excluded_userids");
2620                }
2621            }
2622            // Build the inclusion list -- the ids to remove from the exclusion list
2623            if (cur.excludedUserIds != null) {
2624                for (int i = 0; i < cur.excludedUserIds.length; i++) {
2625                    if (!ArrayUtils.contains(excludedUserIds, cur.excludedUserIds[i])) {
2626                        writeIntToFile(new File(dir, "clear_userid"),
2627                                cur.excludedUserIds[i]);
2628                        if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + cur.excludedUserIds[i] + " to "
2629                                + ps.name + "/clear_userid");
2630
2631                    }
2632                }
2633            }
2634            cur.excludedUserIds = excludedUserIds;
2635        }
2636    }
2637
2638    private void writeIntToFile(File file, int value) {
2639        try {
2640            FileUtils.bytesToFile(file.getAbsolutePath(),
2641                    Integer.toString(value).getBytes(StandardCharsets.US_ASCII));
2642        } catch (IOException ignored) {
2643            Slog.w(TAG, "Couldn't write " + value + " to " + file.getAbsolutePath());
2644        }
2645    }
2646
2647    void writePackageListLPr() {
2648        writePackageListLPr(-1);
2649    }
2650
2651    void writePackageListLPr(int creatingUserId) {
2652        // Only derive GIDs for active users (not dying)
2653        final List<UserInfo> users = UserManagerService.getInstance().getUsers(true);
2654        int[] userIds = new int[users.size()];
2655        for (int i = 0; i < userIds.length; i++) {
2656            userIds[i] = users.get(i).id;
2657        }
2658        if (creatingUserId != -1) {
2659            userIds = ArrayUtils.appendInt(userIds, creatingUserId);
2660        }
2661
2662        // Write package list file now, use a JournaledFile.
2663        File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
2664        JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
2665
2666        final File writeTarget = journal.chooseForWrite();
2667        FileOutputStream fstr;
2668        BufferedWriter writer = null;
2669        try {
2670            fstr = new FileOutputStream(writeTarget);
2671            writer = new BufferedWriter(new OutputStreamWriter(fstr, Charset.defaultCharset()));
2672            FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
2673
2674            StringBuilder sb = new StringBuilder();
2675            for (final PackageSetting pkg : mPackages.values()) {
2676                if (pkg.pkg == null || pkg.pkg.applicationInfo == null
2677                        || pkg.pkg.applicationInfo.dataDir == null) {
2678                    if (!"android".equals(pkg.name)) {
2679                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
2680                    }
2681                    continue;
2682                }
2683
2684                final ApplicationInfo ai = pkg.pkg.applicationInfo;
2685                final String dataPath = ai.dataDir;
2686                final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
2687                final int[] gids = pkg.getPermissionsState().computeGids(userIds);
2688
2689                // Avoid any application that has a space in its path.
2690                if (dataPath.indexOf(' ') >= 0)
2691                    continue;
2692
2693                // we store on each line the following information for now:
2694                //
2695                // pkgName    - package name
2696                // userId     - application-specific user id
2697                // debugFlag  - 0 or 1 if the package is debuggable.
2698                // dataPath   - path to package's data path
2699                // seinfo     - seinfo label for the app (assigned at install time)
2700                // gids       - supplementary gids this app launches with
2701                //
2702                // NOTE: We prefer not to expose all ApplicationInfo flags for now.
2703                //
2704                // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
2705                // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
2706                //   frameworks/base/libs/packagelistparser
2707                //   system/core/run-as/run-as.c
2708                //
2709                sb.setLength(0);
2710                sb.append(ai.packageName);
2711                sb.append(" ");
2712                sb.append(ai.uid);
2713                sb.append(isDebug ? " 1 " : " 0 ");
2714                sb.append(dataPath);
2715                sb.append(" ");
2716                sb.append(ai.seInfo);
2717                sb.append(" ");
2718                if (gids != null && gids.length > 0) {
2719                    sb.append(gids[0]);
2720                    for (int i = 1; i < gids.length; i++) {
2721                        sb.append(",");
2722                        sb.append(gids[i]);
2723                    }
2724                } else {
2725                    sb.append("none");
2726                }
2727                sb.append("\n");
2728                writer.append(sb);
2729            }
2730            writer.flush();
2731            FileUtils.sync(fstr);
2732            writer.close();
2733            journal.commit();
2734        } catch (Exception e) {
2735            Slog.wtf(TAG, "Failed to write packages.list", e);
2736            IoUtils.closeQuietly(writer);
2737            journal.rollback();
2738        }
2739    }
2740
2741    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2742            throws java.io.IOException {
2743        serializer.startTag(null, "updated-package");
2744        serializer.attribute(null, ATTR_NAME, pkg.name);
2745        if (pkg.realName != null) {
2746            serializer.attribute(null, "realName", pkg.realName);
2747        }
2748        serializer.attribute(null, "codePath", pkg.codePathString);
2749        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2750        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2751        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2752        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2753        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2754            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2755        }
2756        if (pkg.legacyNativeLibraryPathString != null) {
2757            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2758        }
2759        if (pkg.primaryCpuAbiString != null) {
2760           serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2761        }
2762        if (pkg.secondaryCpuAbiString != null) {
2763            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2764        }
2765        if (pkg.cpuAbiOverrideString != null) {
2766            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2767        }
2768
2769        if (pkg.sharedUser == null) {
2770            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2771        } else {
2772            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2773        }
2774
2775        if (pkg.parentPackageName != null) {
2776            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2777        }
2778
2779        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2780
2781        writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
2782
2783        // If this is a shared user, the permissions will be written there.
2784        if (pkg.sharedUser == null) {
2785            writePermissionsLPr(serializer, pkg.getPermissionsState()
2786                    .getInstallPermissionStates());
2787        }
2788
2789        serializer.endTag(null, "updated-package");
2790    }
2791
2792    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2793            throws java.io.IOException {
2794        serializer.startTag(null, "package");
2795        serializer.attribute(null, ATTR_NAME, pkg.name);
2796        if (pkg.realName != null) {
2797            serializer.attribute(null, "realName", pkg.realName);
2798        }
2799        serializer.attribute(null, "codePath", pkg.codePathString);
2800        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2801            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2802        }
2803
2804        if (pkg.legacyNativeLibraryPathString != null) {
2805            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2806        }
2807        if (pkg.primaryCpuAbiString != null) {
2808            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2809        }
2810        if (pkg.secondaryCpuAbiString != null) {
2811            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2812        }
2813        if (pkg.cpuAbiOverrideString != null) {
2814            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2815        }
2816
2817        serializer.attribute(null, "publicFlags", Integer.toString(pkg.pkgFlags));
2818        serializer.attribute(null, "privateFlags", Integer.toString(pkg.pkgPrivateFlags));
2819        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2820        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2821        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2822        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2823        if (pkg.sharedUser == null) {
2824            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2825        } else {
2826            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2827        }
2828        if (pkg.uidError) {
2829            serializer.attribute(null, "uidError", "true");
2830        }
2831        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2832            serializer.attribute(null, "installStatus", "false");
2833        }
2834        if (pkg.installerPackageName != null) {
2835            serializer.attribute(null, "installer", pkg.installerPackageName);
2836        }
2837        if (pkg.isOrphaned) {
2838            serializer.attribute(null, "isOrphaned", "true");
2839        }
2840        if (pkg.volumeUuid != null) {
2841            serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
2842        }
2843        if (pkg.categoryHint != ApplicationInfo.CATEGORY_UNDEFINED) {
2844            serializer.attribute(null, "categoryHint",
2845                    Integer.toString(pkg.categoryHint));
2846        }
2847        if (pkg.parentPackageName != null) {
2848            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2849        }
2850        if (pkg.updateAvailable) {
2851            serializer.attribute(null, "updateAvailable", "true");
2852        }
2853
2854        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2855
2856        writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
2857
2858        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
2859
2860        writePermissionsLPr(serializer, pkg.getPermissionsState()
2861                    .getInstallPermissionStates());
2862
2863        writeSigningKeySetLPr(serializer, pkg.keySetData);
2864        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
2865        writeKeySetAliasesLPr(serializer, pkg.keySetData);
2866        writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
2867
2868        serializer.endTag(null, "package");
2869    }
2870
2871    void writeSigningKeySetLPr(XmlSerializer serializer,
2872            PackageKeySetData data) throws IOException {
2873        serializer.startTag(null, "proper-signing-keyset");
2874        serializer.attribute(null, "identifier",
2875                Long.toString(data.getProperSigningKeySet()));
2876        serializer.endTag(null, "proper-signing-keyset");
2877    }
2878
2879    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2880            PackageKeySetData data) throws IOException {
2881        if (data.isUsingUpgradeKeySets()) {
2882            for (long id : data.getUpgradeKeySets()) {
2883                serializer.startTag(null, "upgrade-keyset");
2884                serializer.attribute(null, "identifier", Long.toString(id));
2885                serializer.endTag(null, "upgrade-keyset");
2886            }
2887        }
2888    }
2889
2890    void writeKeySetAliasesLPr(XmlSerializer serializer,
2891            PackageKeySetData data) throws IOException {
2892        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2893            serializer.startTag(null, "defined-keyset");
2894            serializer.attribute(null, "alias", e.getKey());
2895            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2896            serializer.endTag(null, "defined-keyset");
2897        }
2898    }
2899
2900    void writePermissionLPr(XmlSerializer serializer, BasePermission bp) throws IOException {
2901        bp.writeLPr(serializer);
2902    }
2903
2904    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
2905        final ArraySet<String> kList = new ArraySet<String>(mPackages.keySet());
2906        final Iterator<String> its = kList.iterator();
2907        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
2908        while (its.hasNext()) {
2909            final String key = its.next();
2910            final PackageSetting ps = mPackages.get(key);
2911            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2912                ret.add(ps);
2913            }
2914        }
2915        return ret;
2916    }
2917
2918    void addPackageToCleanLPw(PackageCleanItem pkg) {
2919        if (!mPackagesToBeCleaned.contains(pkg)) {
2920            mPackagesToBeCleaned.add(pkg);
2921        }
2922    }
2923
2924    boolean readLPw(@NonNull List<UserInfo> users) {
2925        FileInputStream str = null;
2926        if (mBackupSettingsFilename.exists()) {
2927            try {
2928                str = new FileInputStream(mBackupSettingsFilename);
2929                mReadMessages.append("Reading from backup settings file\n");
2930                PackageManagerService.reportSettingsProblem(Log.INFO,
2931                        "Need to read from backup settings file");
2932                if (mSettingsFilename.exists()) {
2933                    // If both the backup and settings file exist, we
2934                    // ignore the settings since it might have been
2935                    // corrupted.
2936                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2937                            + mSettingsFilename);
2938                    mSettingsFilename.delete();
2939                }
2940            } catch (java.io.IOException e) {
2941                // We'll try for the normal settings file.
2942            }
2943        }
2944
2945        mPendingPackages.clear();
2946        mPastSignatures.clear();
2947        mKeySetRefs.clear();
2948        mInstallerPackages.clear();
2949
2950        try {
2951            if (str == null) {
2952                if (!mSettingsFilename.exists()) {
2953                    mReadMessages.append("No settings file found\n");
2954                    PackageManagerService.reportSettingsProblem(Log.INFO,
2955                            "No settings file; creating initial state");
2956                    // It's enough to just touch version details to create them
2957                    // with default values
2958                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
2959                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
2960                    return false;
2961                }
2962                str = new FileInputStream(mSettingsFilename);
2963            }
2964            XmlPullParser parser = Xml.newPullParser();
2965            parser.setInput(str, StandardCharsets.UTF_8.name());
2966
2967            int type;
2968            while ((type = parser.next()) != XmlPullParser.START_TAG
2969                    && type != XmlPullParser.END_DOCUMENT) {
2970                ;
2971            }
2972
2973            if (type != XmlPullParser.START_TAG) {
2974                mReadMessages.append("No start tag found in settings file\n");
2975                PackageManagerService.reportSettingsProblem(Log.WARN,
2976                        "No start tag found in package manager settings");
2977                Slog.wtf(PackageManagerService.TAG,
2978                        "No start tag found in package manager settings");
2979                return false;
2980            }
2981
2982            int outerDepth = parser.getDepth();
2983            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2984                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2985                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2986                    continue;
2987                }
2988
2989                String tagName = parser.getName();
2990                if (tagName.equals("package")) {
2991                    readPackageLPw(parser);
2992                } else if (tagName.equals("permissions")) {
2993                    mPermissions.readPermissions(parser);
2994                } else if (tagName.equals("permission-trees")) {
2995                    mPermissions.readPermissionTrees(parser);
2996                } else if (tagName.equals("shared-user")) {
2997                    readSharedUserLPw(parser);
2998                } else if (tagName.equals("preferred-packages")) {
2999                    // no longer used.
3000                } else if (tagName.equals("preferred-activities")) {
3001                    // Upgrading from old single-user implementation;
3002                    // these are the preferred activities for user 0.
3003                    readPreferredActivitiesLPw(parser, 0);
3004                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
3005                    // TODO: check whether this is okay! as it is very
3006                    // similar to how preferred-activities are treated
3007                    readPersistentPreferredActivitiesLPw(parser, 0);
3008                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
3009                    // TODO: check whether this is okay! as it is very
3010                    // similar to how preferred-activities are treated
3011                    readCrossProfileIntentFiltersLPw(parser, 0);
3012                } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
3013                    readDefaultAppsLPw(parser, 0);
3014                } else if (tagName.equals("updated-package")) {
3015                    readDisabledSysPackageLPw(parser);
3016                } else if (tagName.equals("cleaning-package")) {
3017                    String name = parser.getAttributeValue(null, ATTR_NAME);
3018                    String userStr = parser.getAttributeValue(null, ATTR_USER);
3019                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
3020                    if (name != null) {
3021                        int userId = UserHandle.USER_SYSTEM;
3022                        boolean andCode = true;
3023                        try {
3024                            if (userStr != null) {
3025                                userId = Integer.parseInt(userStr);
3026                            }
3027                        } catch (NumberFormatException e) {
3028                        }
3029                        if (codeStr != null) {
3030                            andCode = Boolean.parseBoolean(codeStr);
3031                        }
3032                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
3033                    }
3034                } else if (tagName.equals("renamed-package")) {
3035                    String nname = parser.getAttributeValue(null, "new");
3036                    String oname = parser.getAttributeValue(null, "old");
3037                    if (nname != null && oname != null) {
3038                        mRenamedPackages.put(nname, oname);
3039                    }
3040                } else if (tagName.equals("restored-ivi")) {
3041                    readRestoredIntentFilterVerifications(parser);
3042                } else if (tagName.equals("last-platform-version")) {
3043                    // Upgrade from older XML schema
3044                    final VersionInfo internal = findOrCreateVersion(
3045                            StorageManager.UUID_PRIVATE_INTERNAL);
3046                    final VersionInfo external = findOrCreateVersion(
3047                            StorageManager.UUID_PRIMARY_PHYSICAL);
3048
3049                    internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
3050                    external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
3051                    internal.fingerprint = external.fingerprint =
3052                            XmlUtils.readStringAttribute(parser, "fingerprint");
3053
3054                } else if (tagName.equals("database-version")) {
3055                    // Upgrade from older XML schema
3056                    final VersionInfo internal = findOrCreateVersion(
3057                            StorageManager.UUID_PRIVATE_INTERNAL);
3058                    final VersionInfo external = findOrCreateVersion(
3059                            StorageManager.UUID_PRIMARY_PHYSICAL);
3060
3061                    internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
3062                    external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);
3063
3064                } else if (tagName.equals("verifier")) {
3065                    final String deviceIdentity = parser.getAttributeValue(null, "device");
3066                    try {
3067                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
3068                    } catch (IllegalArgumentException e) {
3069                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
3070                                + e.getMessage());
3071                    }
3072                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
3073                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
3074                    mReadExternalStorageEnforced =
3075                            "1".equals(enforcement) ? Boolean.TRUE : Boolean.FALSE;
3076                } else if (tagName.equals("keyset-settings")) {
3077                    mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
3078                } else if (TAG_VERSION.equals(tagName)) {
3079                    final String volumeUuid = XmlUtils.readStringAttribute(parser,
3080                            ATTR_VOLUME_UUID);
3081                    final VersionInfo ver = findOrCreateVersion(volumeUuid);
3082                    ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
3083                    ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_DATABASE_VERSION);
3084                    ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
3085                } else {
3086                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
3087                            + parser.getName());
3088                    XmlUtils.skipCurrentTag(parser);
3089                }
3090            }
3091
3092            str.close();
3093
3094        } catch (XmlPullParserException e) {
3095            mReadMessages.append("Error reading: " + e.toString());
3096            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
3097            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
3098
3099        } catch (java.io.IOException e) {
3100            mReadMessages.append("Error reading: " + e.toString());
3101            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
3102            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
3103        }
3104
3105        // If the build is setup to drop runtime permissions
3106        // on update drop the files before loading them.
3107        if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
3108            final VersionInfo internal = getInternalVersion();
3109            if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
3110                for (UserInfo user : users) {
3111                    mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
3112                }
3113            }
3114        }
3115
3116        final int N = mPendingPackages.size();
3117
3118        for (int i = 0; i < N; i++) {
3119            final PackageSetting p = mPendingPackages.get(i);
3120            final int sharedUserId = p.getSharedUserId();
3121            final Object idObj = getUserIdLPr(sharedUserId);
3122            if (idObj instanceof SharedUserSetting) {
3123                final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
3124                p.sharedUser = sharedUser;
3125                p.appId = sharedUser.userId;
3126                addPackageSettingLPw(p, sharedUser);
3127            } else if (idObj != null) {
3128                String msg = "Bad package setting: package " + p.name + " has shared uid "
3129                        + sharedUserId + " that is not a shared uid\n";
3130                mReadMessages.append(msg);
3131                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
3132            } else {
3133                String msg = "Bad package setting: package " + p.name + " has shared uid "
3134                        + sharedUserId + " that is not defined\n";
3135                mReadMessages.append(msg);
3136                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
3137            }
3138        }
3139        mPendingPackages.clear();
3140
3141        if (mBackupStoppedPackagesFilename.exists()
3142                || mStoppedPackagesFilename.exists()) {
3143            // Read old file
3144            readStoppedLPw();
3145            mBackupStoppedPackagesFilename.delete();
3146            mStoppedPackagesFilename.delete();
3147            // Migrate to new file format
3148            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
3149        } else {
3150            for (UserInfo user : users) {
3151                readPackageRestrictionsLPr(user.id);
3152            }
3153        }
3154
3155        for (UserInfo user : users) {
3156            mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
3157        }
3158
3159        /*
3160         * Make sure all the updated system packages have their shared users
3161         * associated with them.
3162         */
3163        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
3164        while (disabledIt.hasNext()) {
3165            final PackageSetting disabledPs = disabledIt.next();
3166            final Object id = getUserIdLPr(disabledPs.appId);
3167            if (id != null && id instanceof SharedUserSetting) {
3168                disabledPs.sharedUser = (SharedUserSetting) id;
3169            }
3170        }
3171
3172        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
3173                + mSharedUsers.size() + " shared uids\n");
3174
3175        writeKernelMappingLPr();
3176
3177        return true;
3178    }
3179
3180    void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
3181        // First pull data from any pre-installed apps.
3182        for (PackageSetting ps : mPackages.values()) {
3183            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
3184                    && ps.pkg.preferredActivityFilters != null) {
3185                ArrayList<PackageParser.ActivityIntentInfo> intents
3186                        = ps.pkg.preferredActivityFilters;
3187                for (int i=0; i<intents.size(); i++) {
3188                    PackageParser.ActivityIntentInfo aii = intents.get(i);
3189                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
3190                            ps.name, aii.activity.className), userId);
3191                }
3192            }
3193        }
3194
3195        // Read preferred apps from .../etc/preferred-apps directory.
3196        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
3197        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
3198            return;
3199        }
3200        if (!preferredDir.canRead()) {
3201            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
3202            return;
3203        }
3204
3205        // Iterate over the files in the directory and scan .xml files
3206        for (File f : preferredDir.listFiles()) {
3207            if (!f.getPath().endsWith(".xml")) {
3208                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
3209                continue;
3210            }
3211            if (!f.canRead()) {
3212                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
3213                continue;
3214            }
3215
3216            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
3217            InputStream str = null;
3218            try {
3219                str = new BufferedInputStream(new FileInputStream(f));
3220                XmlPullParser parser = Xml.newPullParser();
3221                parser.setInput(str, null);
3222
3223                int type;
3224                while ((type = parser.next()) != XmlPullParser.START_TAG
3225                        && type != XmlPullParser.END_DOCUMENT) {
3226                    ;
3227                }
3228
3229                if (type != XmlPullParser.START_TAG) {
3230                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
3231                    continue;
3232                }
3233                if (!"preferred-activities".equals(parser.getName())) {
3234                    Slog.w(TAG, "Preferred apps file " + f
3235                            + " does not start with 'preferred-activities'");
3236                    continue;
3237                }
3238                readDefaultPreferredActivitiesLPw(service, parser, userId);
3239            } catch (XmlPullParserException e) {
3240                Slog.w(TAG, "Error reading apps file " + f, e);
3241            } catch (IOException e) {
3242                Slog.w(TAG, "Error reading apps file " + f, e);
3243            } finally {
3244                if (str != null) {
3245                    try {
3246                        str.close();
3247                    } catch (IOException e) {
3248                    }
3249                }
3250            }
3251        }
3252    }
3253
3254    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3255            IntentFilter tmpPa, ComponentName cn, int userId) {
3256        // The initial preferences only specify the target activity
3257        // component and intent-filter, not the set of matches.  So we
3258        // now need to query for the matches to build the correct
3259        // preferred activity entry.
3260        if (PackageManagerService.DEBUG_PREFERRED) {
3261            Log.d(TAG, "Processing preferred:");
3262            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
3263        }
3264        Intent intent = new Intent();
3265        int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE
3266                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
3267        intent.setAction(tmpPa.getAction(0));
3268        for (int i=0; i<tmpPa.countCategories(); i++) {
3269            String cat = tmpPa.getCategory(i);
3270            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
3271                flags |= MATCH_DEFAULT_ONLY;
3272            } else {
3273                intent.addCategory(cat);
3274            }
3275        }
3276
3277        boolean doNonData = true;
3278        boolean hasSchemes = false;
3279
3280        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3281            boolean doScheme = true;
3282            String scheme = tmpPa.getDataScheme(ischeme);
3283            if (scheme != null && !scheme.isEmpty()) {
3284                hasSchemes = true;
3285            }
3286            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
3287                Uri.Builder builder = new Uri.Builder();
3288                builder.scheme(scheme);
3289                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
3290                builder.opaquePart(ssp.getPath());
3291                Intent finalIntent = new Intent(intent);
3292                finalIntent.setData(builder.build());
3293                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3294                        scheme, ssp, null, null, userId);
3295                doScheme = false;
3296            }
3297            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
3298                boolean doAuth = true;
3299                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
3300                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
3301                    Uri.Builder builder = new Uri.Builder();
3302                    builder.scheme(scheme);
3303                    if (auth.getHost() != null) {
3304                        builder.authority(auth.getHost());
3305                    }
3306                    PatternMatcher path = tmpPa.getDataPath(ipath);
3307                    builder.path(path.getPath());
3308                    Intent finalIntent = new Intent(intent);
3309                    finalIntent.setData(builder.build());
3310                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3311                            scheme, null, auth, path, userId);
3312                    doAuth = doScheme = false;
3313                }
3314                if (doAuth) {
3315                    Uri.Builder builder = new Uri.Builder();
3316                    builder.scheme(scheme);
3317                    if (auth.getHost() != null) {
3318                        builder.authority(auth.getHost());
3319                    }
3320                    Intent finalIntent = new Intent(intent);
3321                    finalIntent.setData(builder.build());
3322                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3323                            scheme, null, auth, null, userId);
3324                    doScheme = false;
3325                }
3326            }
3327            if (doScheme) {
3328                Uri.Builder builder = new Uri.Builder();
3329                builder.scheme(scheme);
3330                Intent finalIntent = new Intent(intent);
3331                finalIntent.setData(builder.build());
3332                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3333                        scheme, null, null, null, userId);
3334            }
3335            doNonData = false;
3336        }
3337
3338        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
3339            String mimeType = tmpPa.getDataType(idata);
3340            if (hasSchemes) {
3341                Uri.Builder builder = new Uri.Builder();
3342                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3343                    String scheme = tmpPa.getDataScheme(ischeme);
3344                    if (scheme != null && !scheme.isEmpty()) {
3345                        Intent finalIntent = new Intent(intent);
3346                        builder.scheme(scheme);
3347                        finalIntent.setDataAndType(builder.build(), mimeType);
3348                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3349                                scheme, null, null, null, userId);
3350                    }
3351                }
3352            } else {
3353                Intent finalIntent = new Intent(intent);
3354                finalIntent.setType(mimeType);
3355                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3356                        null, null, null, null, userId);
3357            }
3358            doNonData = false;
3359        }
3360
3361        if (doNonData) {
3362            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
3363                    null, null, null, null, userId);
3364        }
3365    }
3366
3367    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3368            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
3369            IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
3370        flags = service.updateFlagsForResolve(flags, userId, intent, Binder.getCallingUid(), false);
3371        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
3372                intent.getType(), flags, 0);
3373        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
3374                + " results: " + ri);
3375        int systemMatch = 0;
3376        int thirdPartyMatch = 0;
3377        if (ri != null && ri.size() > 1) {
3378            boolean haveAct = false;
3379            ComponentName haveNonSys = null;
3380            ComponentName[] set = new ComponentName[ri.size()];
3381            for (int i=0; i<ri.size(); i++) {
3382                ActivityInfo ai = ri.get(i).activityInfo;
3383                set[i] = new ComponentName(ai.packageName, ai.name);
3384                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3385                    if (ri.get(i).match >= thirdPartyMatch) {
3386                        // Keep track of the best match we find of all third
3387                        // party apps, for use later to determine if we actually
3388                        // want to set a preferred app for this intent.
3389                        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3390                                + ai.packageName + "/" + ai.name + ": non-system!");
3391                        haveNonSys = set[i];
3392                        break;
3393                    }
3394                } else if (cn.getPackageName().equals(ai.packageName)
3395                        && cn.getClassName().equals(ai.name)) {
3396                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3397                            + ai.packageName + "/" + ai.name + ": default!");
3398                    haveAct = true;
3399                    systemMatch = ri.get(i).match;
3400                } else {
3401                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3402                            + ai.packageName + "/" + ai.name + ": skipped");
3403                }
3404            }
3405            if (haveNonSys != null && thirdPartyMatch < systemMatch) {
3406                // If we have a matching third party app, but its match is not as
3407                // good as the built-in system app, then we don't want to actually
3408                // consider it a match because presumably the built-in app is still
3409                // the thing we want users to see by default.
3410                haveNonSys = null;
3411            }
3412            if (haveAct && haveNonSys == null) {
3413                IntentFilter filter = new IntentFilter();
3414                if (intent.getAction() != null) {
3415                    filter.addAction(intent.getAction());
3416                }
3417                if (intent.getCategories() != null) {
3418                    for (String cat : intent.getCategories()) {
3419                        filter.addCategory(cat);
3420                    }
3421                }
3422                if ((flags & MATCH_DEFAULT_ONLY) != 0) {
3423                    filter.addCategory(Intent.CATEGORY_DEFAULT);
3424                }
3425                if (scheme != null) {
3426                    filter.addDataScheme(scheme);
3427                }
3428                if (ssp != null) {
3429                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
3430                }
3431                if (auth != null) {
3432                    filter.addDataAuthority(auth);
3433                }
3434                if (path != null) {
3435                    filter.addDataPath(path);
3436                }
3437                if (intent.getType() != null) {
3438                    try {
3439                        filter.addDataType(intent.getType());
3440                    } catch (IntentFilter.MalformedMimeTypeException ex) {
3441                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
3442                    }
3443                }
3444                PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
3445                editPreferredActivitiesLPw(userId).addFilter(pa);
3446            } else if (haveNonSys == null) {
3447                StringBuilder sb = new StringBuilder();
3448                sb.append("No component ");
3449                sb.append(cn.flattenToShortString());
3450                sb.append(" found setting preferred ");
3451                sb.append(intent);
3452                sb.append("; possible matches are ");
3453                for (int i=0; i<set.length; i++) {
3454                    if (i > 0) sb.append(", ");
3455                    sb.append(set[i].flattenToShortString());
3456                }
3457                Slog.w(TAG, sb.toString());
3458            } else {
3459                Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
3460                        + haveNonSys.flattenToShortString());
3461            }
3462        } else {
3463            Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
3464                    + cn.flattenToShortString());
3465        }
3466    }
3467
3468    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
3469            XmlPullParser parser, int userId)
3470            throws XmlPullParserException, IOException {
3471        int outerDepth = parser.getDepth();
3472        int type;
3473        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3474                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3475            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3476                continue;
3477            }
3478
3479            String tagName = parser.getName();
3480            if (tagName.equals(TAG_ITEM)) {
3481                PreferredActivity tmpPa = new PreferredActivity(parser);
3482                if (tmpPa.mPref.getParseError() == null) {
3483                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
3484                            userId);
3485                } else {
3486                    PackageManagerService.reportSettingsProblem(Log.WARN,
3487                            "Error in package manager settings: <preferred-activity> "
3488                                    + tmpPa.mPref.getParseError() + " at "
3489                                    + parser.getPositionDescription());
3490                }
3491            } else {
3492                PackageManagerService.reportSettingsProblem(Log.WARN,
3493                        "Unknown element under <preferred-activities>: " + parser.getName());
3494                XmlUtils.skipCurrentTag(parser);
3495            }
3496        }
3497    }
3498
3499    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
3500            IOException {
3501        String name = parser.getAttributeValue(null, ATTR_NAME);
3502        String realName = parser.getAttributeValue(null, "realName");
3503        String codePathStr = parser.getAttributeValue(null, "codePath");
3504        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3505
3506        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
3507        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3508
3509        String parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3510
3511        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
3512        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
3513        String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
3514
3515        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
3516            primaryCpuAbiStr = legacyCpuAbiStr;
3517        }
3518
3519        if (resourcePathStr == null) {
3520            resourcePathStr = codePathStr;
3521        }
3522        String version = parser.getAttributeValue(null, "version");
3523        long versionCode = 0;
3524        if (version != null) {
3525            try {
3526                versionCode = Long.parseLong(version);
3527            } catch (NumberFormatException e) {
3528            }
3529        }
3530
3531        int pkgFlags = 0;
3532        int pkgPrivateFlags = 0;
3533        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3534        if (PackageManagerService.locationIsPrivileged(codePathStr)) {
3535            pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3536        }
3537        PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
3538                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
3539                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
3540                parentPackageName, null /*childPackageNames*/, 0 /*sharedUserId*/, null, null);
3541        String timeStampStr = parser.getAttributeValue(null, "ft");
3542        if (timeStampStr != null) {
3543            try {
3544                long timeStamp = Long.parseLong(timeStampStr, 16);
3545                ps.setTimeStamp(timeStamp);
3546            } catch (NumberFormatException e) {
3547            }
3548        } else {
3549            timeStampStr = parser.getAttributeValue(null, "ts");
3550            if (timeStampStr != null) {
3551                try {
3552                    long timeStamp = Long.parseLong(timeStampStr);
3553                    ps.setTimeStamp(timeStamp);
3554                } catch (NumberFormatException e) {
3555                }
3556            }
3557        }
3558        timeStampStr = parser.getAttributeValue(null, "it");
3559        if (timeStampStr != null) {
3560            try {
3561                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
3562            } catch (NumberFormatException e) {
3563            }
3564        }
3565        timeStampStr = parser.getAttributeValue(null, "ut");
3566        if (timeStampStr != null) {
3567            try {
3568                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
3569            } catch (NumberFormatException e) {
3570            }
3571        }
3572        String idStr = parser.getAttributeValue(null, "userId");
3573        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
3574        if (ps.appId <= 0) {
3575            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3576            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3577        }
3578
3579        int outerDepth = parser.getDepth();
3580        int type;
3581        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3582                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3583            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3584                continue;
3585            }
3586
3587            if (parser.getName().equals(TAG_PERMISSIONS)) {
3588                readInstallPermissionsLPr(parser, ps.getPermissionsState());
3589            } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) {
3590                String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3591                if (ps.childPackageNames == null) {
3592                    ps.childPackageNames = new ArrayList<>();
3593                }
3594                ps.childPackageNames.add(childPackageName);
3595            } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) {
3596                readUsesStaticLibLPw(parser, ps);
3597            } else {
3598                PackageManagerService.reportSettingsProblem(Log.WARN,
3599                        "Unknown element under <updated-package>: " + parser.getName());
3600                XmlUtils.skipCurrentTag(parser);
3601            }
3602        }
3603
3604        mDisabledSysPackages.put(name, ps);
3605    }
3606
3607    private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27;
3608    private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
3609    private static int PRE_M_APP_INFO_FLAG_FORWARD_LOCK = 1<<29;
3610    private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
3611
3612    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
3613        String name = null;
3614        String realName = null;
3615        String idStr = null;
3616        String sharedIdStr = null;
3617        String codePathStr = null;
3618        String resourcePathStr = null;
3619        String legacyCpuAbiString = null;
3620        String legacyNativeLibraryPathStr = null;
3621        String primaryCpuAbiString = null;
3622        String secondaryCpuAbiString = null;
3623        String cpuAbiOverrideString = null;
3624        String systemStr = null;
3625        String installerPackageName = null;
3626        String isOrphaned = null;
3627        String volumeUuid = null;
3628        String categoryHintString = null;
3629        String updateAvailable = null;
3630        int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
3631        String uidError = null;
3632        int pkgFlags = 0;
3633        int pkgPrivateFlags = 0;
3634        long timeStamp = 0;
3635        long firstInstallTime = 0;
3636        long lastUpdateTime = 0;
3637        PackageSetting packageSetting = null;
3638        String version = null;
3639        long versionCode = 0;
3640        String parentPackageName;
3641        try {
3642            name = parser.getAttributeValue(null, ATTR_NAME);
3643            realName = parser.getAttributeValue(null, "realName");
3644            idStr = parser.getAttributeValue(null, "userId");
3645            uidError = parser.getAttributeValue(null, "uidError");
3646            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3647            codePathStr = parser.getAttributeValue(null, "codePath");
3648            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3649
3650            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
3651
3652            parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3653
3654            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3655            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
3656            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
3657            cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
3658            updateAvailable = parser.getAttributeValue(null, "updateAvailable");
3659
3660            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
3661                primaryCpuAbiString = legacyCpuAbiString;
3662            }
3663
3664            version = parser.getAttributeValue(null, "version");
3665            if (version != null) {
3666                try {
3667                    versionCode = Long.parseLong(version);
3668                } catch (NumberFormatException e) {
3669                }
3670            }
3671            installerPackageName = parser.getAttributeValue(null, "installer");
3672            isOrphaned = parser.getAttributeValue(null, "isOrphaned");
3673            volumeUuid = parser.getAttributeValue(null, "volumeUuid");
3674            categoryHintString = parser.getAttributeValue(null, "categoryHint");
3675            if (categoryHintString != null) {
3676                try {
3677                    categoryHint = Integer.parseInt(categoryHintString);
3678                } catch (NumberFormatException e) {
3679                }
3680            }
3681
3682            systemStr = parser.getAttributeValue(null, "publicFlags");
3683            if (systemStr != null) {
3684                try {
3685                    pkgFlags = Integer.parseInt(systemStr);
3686                } catch (NumberFormatException e) {
3687                }
3688                systemStr = parser.getAttributeValue(null, "privateFlags");
3689                if (systemStr != null) {
3690                    try {
3691                        pkgPrivateFlags = Integer.parseInt(systemStr);
3692                    } catch (NumberFormatException e) {
3693                    }
3694                }
3695            } else {
3696                // Pre-M -- both public and private flags were stored in one "flags" field.
3697                systemStr = parser.getAttributeValue(null, "flags");
3698                if (systemStr != null) {
3699                    try {
3700                        pkgFlags = Integer.parseInt(systemStr);
3701                    } catch (NumberFormatException e) {
3702                    }
3703                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) {
3704                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
3705                    }
3706                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) {
3707                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
3708                    }
3709                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_FORWARD_LOCK) != 0) {
3710                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK;
3711                    }
3712                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) {
3713                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3714                    }
3715                    pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN
3716                            | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE
3717                            | PRE_M_APP_INFO_FLAG_FORWARD_LOCK
3718                            | PRE_M_APP_INFO_FLAG_PRIVILEGED);
3719                } else {
3720                    // For backward compatibility
3721                    systemStr = parser.getAttributeValue(null, "system");
3722                    if (systemStr != null) {
3723                        pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
3724                                : 0;
3725                    } else {
3726                        // Old settings that don't specify system... just treat
3727                        // them as system, good enough.
3728                        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3729                    }
3730                }
3731            }
3732            String timeStampStr = parser.getAttributeValue(null, "ft");
3733            if (timeStampStr != null) {
3734                try {
3735                    timeStamp = Long.parseLong(timeStampStr, 16);
3736                } catch (NumberFormatException e) {
3737                }
3738            } else {
3739                timeStampStr = parser.getAttributeValue(null, "ts");
3740                if (timeStampStr != null) {
3741                    try {
3742                        timeStamp = Long.parseLong(timeStampStr);
3743                    } catch (NumberFormatException e) {
3744                    }
3745                }
3746            }
3747            timeStampStr = parser.getAttributeValue(null, "it");
3748            if (timeStampStr != null) {
3749                try {
3750                    firstInstallTime = Long.parseLong(timeStampStr, 16);
3751                } catch (NumberFormatException e) {
3752                }
3753            }
3754            timeStampStr = parser.getAttributeValue(null, "ut");
3755            if (timeStampStr != null) {
3756                try {
3757                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
3758                } catch (NumberFormatException e) {
3759                }
3760            }
3761            if (PackageManagerService.DEBUG_SETTINGS)
3762                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
3763                        + " sharedUserId=" + sharedIdStr);
3764            final int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3765            final int sharedUserId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3766            if (resourcePathStr == null) {
3767                resourcePathStr = codePathStr;
3768            }
3769            if (realName != null) {
3770                realName = realName.intern();
3771            }
3772            if (name == null) {
3773                PackageManagerService.reportSettingsProblem(Log.WARN,
3774                        "Error in package manager settings: <package> has no name at "
3775                                + parser.getPositionDescription());
3776            } else if (codePathStr == null) {
3777                PackageManagerService.reportSettingsProblem(Log.WARN,
3778                        "Error in package manager settings: <package> has no codePath at "
3779                                + parser.getPositionDescription());
3780            } else if (userId > 0) {
3781                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
3782                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
3783                        secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
3784                        pkgPrivateFlags, parentPackageName, null /*childPackageNames*/,
3785                        null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/);
3786                if (PackageManagerService.DEBUG_SETTINGS)
3787                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
3788                            + userId + " pkg=" + packageSetting);
3789                if (packageSetting == null) {
3790                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
3791                            + userId + " while parsing settings at "
3792                            + parser.getPositionDescription());
3793                } else {
3794                    packageSetting.setTimeStamp(timeStamp);
3795                    packageSetting.firstInstallTime = firstInstallTime;
3796                    packageSetting.lastUpdateTime = lastUpdateTime;
3797                }
3798            } else if (sharedIdStr != null) {
3799                if (sharedUserId > 0) {
3800                    packageSetting = new PackageSetting(name.intern(), realName, new File(
3801                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
3802                            primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
3803                            versionCode, pkgFlags, pkgPrivateFlags, parentPackageName,
3804                            null /*childPackageNames*/, sharedUserId,
3805                            null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/);
3806                    packageSetting.setTimeStamp(timeStamp);
3807                    packageSetting.firstInstallTime = firstInstallTime;
3808                    packageSetting.lastUpdateTime = lastUpdateTime;
3809                    mPendingPackages.add(packageSetting);
3810                    if (PackageManagerService.DEBUG_SETTINGS)
3811                        Log.i(PackageManagerService.TAG, "Reading package " + name
3812                                + ": sharedUserId=" + sharedUserId + " pkg=" + packageSetting);
3813                } else {
3814                    PackageManagerService.reportSettingsProblem(Log.WARN,
3815                            "Error in package manager settings: package " + name
3816                                    + " has bad sharedId " + sharedIdStr + " at "
3817                                    + parser.getPositionDescription());
3818                }
3819            } else {
3820                PackageManagerService.reportSettingsProblem(Log.WARN,
3821                        "Error in package manager settings: package " + name + " has bad userId "
3822                                + idStr + " at " + parser.getPositionDescription());
3823            }
3824        } catch (NumberFormatException e) {
3825            PackageManagerService.reportSettingsProblem(Log.WARN,
3826                    "Error in package manager settings: package " + name + " has bad userId "
3827                            + idStr + " at " + parser.getPositionDescription());
3828        }
3829        if (packageSetting != null) {
3830            packageSetting.uidError = "true".equals(uidError);
3831            packageSetting.installerPackageName = installerPackageName;
3832            packageSetting.isOrphaned = "true".equals(isOrphaned);
3833            packageSetting.volumeUuid = volumeUuid;
3834            packageSetting.categoryHint = categoryHint;
3835            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
3836            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
3837            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
3838            packageSetting.updateAvailable = "true".equals(updateAvailable);
3839            // Handle legacy string here for single-user mode
3840            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
3841            if (enabledStr != null) {
3842                try {
3843                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
3844                } catch (NumberFormatException e) {
3845                    if (enabledStr.equalsIgnoreCase("true")) {
3846                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
3847                    } else if (enabledStr.equalsIgnoreCase("false")) {
3848                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
3849                    } else if (enabledStr.equalsIgnoreCase("default")) {
3850                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3851                    } else {
3852                        PackageManagerService.reportSettingsProblem(Log.WARN,
3853                                "Error in package manager settings: package " + name
3854                                        + " has bad enabled value: " + idStr + " at "
3855                                        + parser.getPositionDescription());
3856                    }
3857                }
3858            } else {
3859                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3860            }
3861
3862            if (installerPackageName != null) {
3863                mInstallerPackages.add(installerPackageName);
3864            }
3865
3866            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
3867            if (installStatusStr != null) {
3868                if (installStatusStr.equalsIgnoreCase("false")) {
3869                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
3870                } else {
3871                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
3872                }
3873            }
3874
3875            int outerDepth = parser.getDepth();
3876            int type;
3877            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3878                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3879                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3880                    continue;
3881                }
3882
3883                String tagName = parser.getName();
3884                // Legacy
3885                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
3886                    readDisabledComponentsLPw(packageSetting, parser, 0);
3887                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
3888                    readEnabledComponentsLPw(packageSetting, parser, 0);
3889                } else if (tagName.equals("sigs")) {
3890                    packageSetting.signatures.readXml(parser, mPastSignatures);
3891                } else if (tagName.equals(TAG_PERMISSIONS)) {
3892                    readInstallPermissionsLPr(parser,
3893                            packageSetting.getPermissionsState());
3894                    packageSetting.installPermissionsFixed = true;
3895                } else if (tagName.equals("proper-signing-keyset")) {
3896                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3897                    Integer refCt = mKeySetRefs.get(id);
3898                    if (refCt != null) {
3899                        mKeySetRefs.put(id, refCt + 1);
3900                    } else {
3901                        mKeySetRefs.put(id, 1);
3902                    }
3903                    packageSetting.keySetData.setProperSigningKeySet(id);
3904                } else if (tagName.equals("signing-keyset")) {
3905                    // from v1 of keysetmanagerservice - no longer used
3906                } else if (tagName.equals("upgrade-keyset")) {
3907                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3908                    packageSetting.keySetData.addUpgradeKeySetById(id);
3909                } else if (tagName.equals("defined-keyset")) {
3910                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3911                    String alias = parser.getAttributeValue(null, "alias");
3912                    Integer refCt = mKeySetRefs.get(id);
3913                    if (refCt != null) {
3914                        mKeySetRefs.put(id, refCt + 1);
3915                    } else {
3916                        mKeySetRefs.put(id, 1);
3917                    }
3918                    packageSetting.keySetData.addDefinedKeySet(id, alias);
3919                } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
3920                    readDomainVerificationLPw(parser, packageSetting);
3921                } else if (tagName.equals(TAG_CHILD_PACKAGE)) {
3922                    String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3923                    if (packageSetting.childPackageNames == null) {
3924                        packageSetting.childPackageNames = new ArrayList<>();
3925                    }
3926                    packageSetting.childPackageNames.add(childPackageName);
3927                } else {
3928                    PackageManagerService.reportSettingsProblem(Log.WARN,
3929                            "Unknown element under <package>: " + parser.getName());
3930                    XmlUtils.skipCurrentTag(parser);
3931                }
3932            }
3933        } else {
3934            XmlUtils.skipCurrentTag(parser);
3935        }
3936    }
3937
3938    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3939            int userId) throws IOException, XmlPullParserException {
3940        int outerDepth = parser.getDepth();
3941        int type;
3942        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3943                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3944            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3945                continue;
3946            }
3947
3948            String tagName = parser.getName();
3949            if (tagName.equals(TAG_ITEM)) {
3950                String name = parser.getAttributeValue(null, ATTR_NAME);
3951                if (name != null) {
3952                    packageSetting.addDisabledComponent(name.intern(), userId);
3953                } else {
3954                    PackageManagerService.reportSettingsProblem(Log.WARN,
3955                            "Error in package manager settings: <disabled-components> has"
3956                                    + " no name at " + parser.getPositionDescription());
3957                }
3958            } else {
3959                PackageManagerService.reportSettingsProblem(Log.WARN,
3960                        "Unknown element under <disabled-components>: " + parser.getName());
3961            }
3962            XmlUtils.skipCurrentTag(parser);
3963        }
3964    }
3965
3966    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3967            int userId) throws IOException, XmlPullParserException {
3968        int outerDepth = parser.getDepth();
3969        int type;
3970        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3971                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3972            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3973                continue;
3974            }
3975
3976            String tagName = parser.getName();
3977            if (tagName.equals(TAG_ITEM)) {
3978                String name = parser.getAttributeValue(null, ATTR_NAME);
3979                if (name != null) {
3980                    packageSetting.addEnabledComponent(name.intern(), userId);
3981                } else {
3982                    PackageManagerService.reportSettingsProblem(Log.WARN,
3983                            "Error in package manager settings: <enabled-components> has"
3984                                    + " no name at " + parser.getPositionDescription());
3985                }
3986            } else {
3987                PackageManagerService.reportSettingsProblem(Log.WARN,
3988                        "Unknown element under <enabled-components>: " + parser.getName());
3989            }
3990            XmlUtils.skipCurrentTag(parser);
3991        }
3992    }
3993
3994    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
3995        String name = null;
3996        String idStr = null;
3997        int pkgFlags = 0;
3998        int pkgPrivateFlags = 0;
3999        SharedUserSetting su = null;
4000        try {
4001            name = parser.getAttributeValue(null, ATTR_NAME);
4002            idStr = parser.getAttributeValue(null, "userId");
4003            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
4004            if ("true".equals(parser.getAttributeValue(null, "system"))) {
4005                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
4006            }
4007            if (name == null) {
4008                PackageManagerService.reportSettingsProblem(Log.WARN,
4009                        "Error in package manager settings: <shared-user> has no name at "
4010                                + parser.getPositionDescription());
4011            } else if (userId == 0) {
4012                PackageManagerService.reportSettingsProblem(Log.WARN,
4013                        "Error in package manager settings: shared-user " + name
4014                                + " has bad userId " + idStr + " at "
4015                                + parser.getPositionDescription());
4016            } else {
4017                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
4018                        == null) {
4019                    PackageManagerService
4020                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
4021                                    + parser.getPositionDescription());
4022                }
4023            }
4024        } catch (NumberFormatException e) {
4025            PackageManagerService.reportSettingsProblem(Log.WARN,
4026                    "Error in package manager settings: package " + name + " has bad userId "
4027                            + idStr + " at " + parser.getPositionDescription());
4028        }
4029
4030        if (su != null) {
4031            int outerDepth = parser.getDepth();
4032            int type;
4033            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4034                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4035                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4036                    continue;
4037                }
4038
4039                String tagName = parser.getName();
4040                if (tagName.equals("sigs")) {
4041                    su.signatures.readXml(parser, mPastSignatures);
4042                } else if (tagName.equals("perms")) {
4043                    readInstallPermissionsLPr(parser, su.getPermissionsState());
4044                } else {
4045                    PackageManagerService.reportSettingsProblem(Log.WARN,
4046                            "Unknown element under <shared-user>: " + parser.getName());
4047                    XmlUtils.skipCurrentTag(parser);
4048                }
4049            }
4050        } else {
4051            XmlUtils.skipCurrentTag(parser);
4052        }
4053    }
4054
4055    void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
4056            int userHandle, String[] disallowedPackages) {
4057        String[] volumeUuids;
4058        String[] names;
4059        int[] appIds;
4060        String[] seinfos;
4061        int[] targetSdkVersions;
4062        int packagesCount;
4063        synchronized (mPackages) {
4064            Collection<PackageSetting> packages = mPackages.values();
4065            packagesCount = packages.size();
4066            volumeUuids = new String[packagesCount];
4067            names = new String[packagesCount];
4068            appIds = new int[packagesCount];
4069            seinfos = new String[packagesCount];
4070            targetSdkVersions = new int[packagesCount];
4071            Iterator<PackageSetting> packagesIterator = packages.iterator();
4072            for (int i = 0; i < packagesCount; i++) {
4073                PackageSetting ps = packagesIterator.next();
4074                if (ps.pkg == null || ps.pkg.applicationInfo == null) {
4075                    continue;
4076                }
4077                final boolean shouldInstall = ps.isSystem() &&
4078                        !ArrayUtils.contains(disallowedPackages, ps.name);
4079                // Only system apps are initially installed.
4080                ps.setInstalled(shouldInstall, userHandle);
4081                if (!shouldInstall) {
4082                    writeKernelMappingLPr(ps);
4083                }
4084                // Need to create a data directory for all apps under this user. Accumulate all
4085                // required args and call the installer after mPackages lock has been released
4086                volumeUuids[i] = ps.volumeUuid;
4087                names[i] = ps.name;
4088                appIds[i] = ps.appId;
4089                seinfos[i] = ps.pkg.applicationInfo.seInfo;
4090                targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
4091            }
4092        }
4093        for (int i = 0; i < packagesCount; i++) {
4094            if (names[i] == null) {
4095                continue;
4096            }
4097            // TODO: triage flags!
4098            final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
4099            try {
4100                installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
4101                        seinfos[i], targetSdkVersions[i]);
4102            } catch (InstallerException e) {
4103                Slog.w(TAG, "Failed to prepare app data", e);
4104            }
4105        }
4106        synchronized (mPackages) {
4107            applyDefaultPreferredAppsLPw(service, userHandle);
4108        }
4109    }
4110
4111    void removeUserLPw(int userId) {
4112        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
4113        for (Entry<String, PackageSetting> entry : entries) {
4114            entry.getValue().removeUser(userId);
4115        }
4116        mPreferredActivities.remove(userId);
4117        File file = getUserPackagesStateFile(userId);
4118        file.delete();
4119        file = getUserPackagesStateBackupFile(userId);
4120        file.delete();
4121        removeCrossProfileIntentFiltersLPw(userId);
4122
4123        mRuntimePermissionsPersistence.onUserRemovedLPw(userId);
4124
4125        writePackageListLPr();
4126
4127        // Inform kernel that the user was removed, so that packages are marked uninstalled
4128        // for sdcardfs
4129        writeKernelRemoveUserLPr(userId);
4130    }
4131
4132    void removeCrossProfileIntentFiltersLPw(int userId) {
4133        synchronized (mCrossProfileIntentResolvers) {
4134            // userId is the source user
4135            if (mCrossProfileIntentResolvers.get(userId) != null) {
4136                mCrossProfileIntentResolvers.remove(userId);
4137                writePackageRestrictionsLPr(userId);
4138            }
4139            // userId is the target user
4140            int count = mCrossProfileIntentResolvers.size();
4141            for (int i = 0; i < count; i++) {
4142                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
4143                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
4144                boolean needsWriting = false;
4145                ArraySet<CrossProfileIntentFilter> cpifs =
4146                        new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
4147                for (CrossProfileIntentFilter cpif : cpifs) {
4148                    if (cpif.getTargetUserId() == userId) {
4149                        needsWriting = true;
4150                        cpir.removeFilter(cpif);
4151                    }
4152                }
4153                if (needsWriting) {
4154                    writePackageRestrictionsLPr(sourceUserId);
4155                }
4156            }
4157        }
4158    }
4159
4160    // This should be called (at least) whenever an application is removed
4161    private void setFirstAvailableUid(int uid) {
4162        if (uid > mFirstAvailableUid) {
4163            mFirstAvailableUid = uid;
4164        }
4165    }
4166
4167    // Returns -1 if we could not find an available UserId to assign
4168    private int newUserIdLPw(Object obj) {
4169        // Let's be stupidly inefficient for now...
4170        final int N = mUserIds.size();
4171        for (int i = mFirstAvailableUid; i < N; i++) {
4172            if (mUserIds.get(i) == null) {
4173                mUserIds.set(i, obj);
4174                return Process.FIRST_APPLICATION_UID + i;
4175            }
4176        }
4177
4178        // None left?
4179        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
4180            return -1;
4181        }
4182
4183        mUserIds.add(obj);
4184        return Process.FIRST_APPLICATION_UID + N;
4185    }
4186
4187    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
4188        if (mVerifierDeviceIdentity == null) {
4189            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
4190
4191            writeLPr();
4192        }
4193
4194        return mVerifierDeviceIdentity;
4195    }
4196
4197    boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
4198            String childPackageName) {
4199        final int packageCount = mDisabledSysPackages.size();
4200        for (int i = 0; i < packageCount; i++) {
4201            PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
4202            if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
4203                continue;
4204            }
4205            if (disabledPs.name.equals(parentPackageName)) {
4206                continue;
4207            }
4208            final int childCount = disabledPs.childPackageNames.size();
4209            for (int j = 0; j < childCount; j++) {
4210                String currChildPackageName = disabledPs.childPackageNames.get(j);
4211                if (currChildPackageName.equals(childPackageName)) {
4212                    return true;
4213                }
4214            }
4215        }
4216        return false;
4217    }
4218
4219    public PackageSetting getDisabledSystemPkgLPr(String name) {
4220        PackageSetting ps = mDisabledSysPackages.get(name);
4221        return ps;
4222    }
4223
4224    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
4225        final PackageSetting ps = mPackages.get(componentInfo.packageName);
4226        if (ps == null) return false;
4227
4228        final PackageUserState userState = ps.readUserState(userId);
4229        return userState.isMatch(componentInfo, flags);
4230    }
4231
4232    String getInstallerPackageNameLPr(String packageName) {
4233        final PackageSetting pkg = mPackages.get(packageName);
4234        if (pkg == null) {
4235            throw new IllegalArgumentException("Unknown package: " + packageName);
4236        }
4237        return pkg.installerPackageName;
4238    }
4239
4240    boolean isOrphaned(String packageName) {
4241        final PackageSetting pkg = mPackages.get(packageName);
4242        if (pkg == null) {
4243            throw new IllegalArgumentException("Unknown package: " + packageName);
4244        }
4245        return pkg.isOrphaned;
4246    }
4247
4248    int getApplicationEnabledSettingLPr(String packageName, int userId) {
4249        final PackageSetting pkg = mPackages.get(packageName);
4250        if (pkg == null) {
4251            throw new IllegalArgumentException("Unknown package: " + packageName);
4252        }
4253        return pkg.getEnabled(userId);
4254    }
4255
4256    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
4257        final String packageName = componentName.getPackageName();
4258        final PackageSetting pkg = mPackages.get(packageName);
4259        if (pkg == null) {
4260            throw new IllegalArgumentException("Unknown component: " + componentName);
4261        }
4262        final String classNameStr = componentName.getClassName();
4263        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
4264    }
4265
4266    boolean wasPackageEverLaunchedLPr(String packageName, int userId) {
4267        final PackageSetting pkgSetting = mPackages.get(packageName);
4268        if (pkgSetting == null) {
4269            throw new IllegalArgumentException("Unknown package: " + packageName);
4270        }
4271        return !pkgSetting.getNotLaunched(userId);
4272    }
4273
4274    boolean setPackageStoppedStateLPw(PackageManagerService pm, String packageName,
4275            boolean stopped, boolean allowedByPermission, int uid, int userId) {
4276        int appId = UserHandle.getAppId(uid);
4277        final PackageSetting pkgSetting = mPackages.get(packageName);
4278        if (pkgSetting == null) {
4279            throw new IllegalArgumentException("Unknown package: " + packageName);
4280        }
4281        if (!allowedByPermission && (appId != pkgSetting.appId)) {
4282            throw new SecurityException(
4283                    "Permission Denial: attempt to change stopped state from pid="
4284                    + Binder.getCallingPid()
4285                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
4286        }
4287        if (DEBUG_STOPPED) {
4288            if (stopped) {
4289                RuntimeException e = new RuntimeException("here");
4290                e.fillInStackTrace();
4291                Slog.i(TAG, "Stopping package " + packageName, e);
4292            }
4293        }
4294        if (pkgSetting.getStopped(userId) != stopped) {
4295            pkgSetting.setStopped(stopped, userId);
4296            // pkgSetting.pkg.mSetStopped = stopped;
4297            if (pkgSetting.getNotLaunched(userId)) {
4298                if (pkgSetting.installerPackageName != null) {
4299                    pm.notifyFirstLaunch(pkgSetting.name, pkgSetting.installerPackageName, userId);
4300                }
4301                pkgSetting.setNotLaunched(false, userId);
4302            }
4303            return true;
4304        }
4305        return false;
4306    }
4307
4308    void setHarmfulAppWarningLPw(String packageName, CharSequence warning, int userId) {
4309        final PackageSetting pkgSetting = mPackages.get(packageName);
4310        if (pkgSetting == null) {
4311            throw new IllegalArgumentException("Unknown package: " + packageName);
4312        }
4313        pkgSetting.setHarmfulAppWarning(userId, warning == null ? null : warning.toString());
4314    }
4315
4316    String getHarmfulAppWarningLPr(String packageName, int userId) {
4317        final PackageSetting pkgSetting = mPackages.get(packageName);
4318        if (pkgSetting == null) {
4319            throw new IllegalArgumentException("Unknown package: " + packageName);
4320        }
4321        return pkgSetting.getHarmfulAppWarning(userId);
4322    }
4323
4324    private static List<UserInfo> getAllUsers(UserManagerService userManager) {
4325        long id = Binder.clearCallingIdentity();
4326        try {
4327            return userManager.getUsers(false);
4328        } catch (NullPointerException npe) {
4329            // packagemanager not yet initialized
4330        } finally {
4331            Binder.restoreCallingIdentity(id);
4332        }
4333        return null;
4334    }
4335
4336    /**
4337     * Return all {@link PackageSetting} that are actively installed on the
4338     * given {@link VolumeInfo#fsUuid}.
4339     */
4340    List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
4341        ArrayList<PackageSetting> res = new ArrayList<>();
4342        for (int i = 0; i < mPackages.size(); i++) {
4343            final PackageSetting setting = mPackages.valueAt(i);
4344            if (Objects.equals(volumeUuid, setting.volumeUuid)) {
4345                res.add(setting);
4346            }
4347        }
4348        return res;
4349    }
4350
4351    static void printFlags(PrintWriter pw, int val, Object[] spec) {
4352        pw.print("[ ");
4353        for (int i=0; i<spec.length; i+=2) {
4354            int mask = (Integer)spec[i];
4355            if ((val & mask) != 0) {
4356                pw.print(spec[i+1]);
4357                pw.print(" ");
4358            }
4359        }
4360        pw.print("]");
4361    }
4362
4363    static final Object[] FLAG_DUMP_SPEC = new Object[] {
4364        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4365        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4366        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4367        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4368        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4369        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4370        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4371        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4372        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4373        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4374        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4375        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4376        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4377        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4378        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4379    };
4380
4381    private static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4382            ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE",
4383            ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION",
4384            ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE",
4385            ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
4386            ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4387            ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
4388            ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
4389            ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK",
4390            ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
4391            ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN",
4392            ApplicationInfo.PRIVATE_FLAG_INSTANT, "EPHEMERAL",
4393            ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, "ISOLATED_SPLIT_LOADING",
4394            ApplicationInfo.PRIVATE_FLAG_OEM, "OEM",
4395            ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
4396            ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4397            ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
4398            ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
4399            ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
4400            ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
4401    };
4402
4403    void dumpVersionLPr(IndentingPrintWriter pw) {
4404        pw.increaseIndent();
4405        for (int i= 0; i < mVersion.size(); i++) {
4406            final String volumeUuid = mVersion.keyAt(i);
4407            final VersionInfo ver = mVersion.valueAt(i);
4408            if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4409                pw.println("Internal:");
4410            } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4411                pw.println("External:");
4412            } else {
4413                pw.println("UUID " + volumeUuid + ":");
4414            }
4415            pw.increaseIndent();
4416            pw.printPair("sdkVersion", ver.sdkVersion);
4417            pw.printPair("databaseVersion", ver.databaseVersion);
4418            pw.println();
4419            pw.printPair("fingerprint", ver.fingerprint);
4420            pw.println();
4421            pw.decreaseIndent();
4422        }
4423        pw.decreaseIndent();
4424    }
4425
4426    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4427            ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4428            Date date, List<UserInfo> users, boolean dumpAll) {
4429        if (checkinTag != null) {
4430            pw.print(checkinTag);
4431            pw.print(",");
4432            pw.print(ps.realName != null ? ps.realName : ps.name);
4433            pw.print(",");
4434            pw.print(ps.appId);
4435            pw.print(",");
4436            pw.print(ps.versionCode);
4437            pw.print(",");
4438            pw.print(ps.firstInstallTime);
4439            pw.print(",");
4440            pw.print(ps.lastUpdateTime);
4441            pw.print(",");
4442            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4443            pw.println();
4444            if (ps.pkg != null) {
4445                pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4446                pw.print("base,");
4447                pw.println(ps.pkg.baseRevisionCode);
4448                if (ps.pkg.splitNames != null) {
4449                    for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4450                        pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4451                        pw.print(ps.pkg.splitNames[i]); pw.print(",");
4452                        pw.println(ps.pkg.splitRevisionCodes[i]);
4453                    }
4454                }
4455            }
4456            for (UserInfo user : users) {
4457                pw.print(checkinTag);
4458                pw.print("-");
4459                pw.print("usr");
4460                pw.print(",");
4461                pw.print(user.id);
4462                pw.print(",");
4463                pw.print(ps.getInstalled(user.id) ? "I" : "i");
4464                pw.print(ps.getHidden(user.id) ? "B" : "b");
4465                pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4466                pw.print(ps.getStopped(user.id) ? "S" : "s");
4467                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4468                pw.print(ps.getInstantApp(user.id) ? "IA" : "ia");
4469                pw.print(ps.getVirtulalPreload(user.id) ? "VPI" : "vpi");
4470                String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4471                pw.print(harmfulAppWarning != null ? "HA" : "ha");
4472                pw.print(",");
4473                pw.print(ps.getEnabled(user.id));
4474                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4475                pw.print(",");
4476                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4477                pw.print(",");
4478                pw.println();
4479            }
4480            return;
4481        }
4482
4483        pw.print(prefix); pw.print("Package [");
4484            pw.print(ps.realName != null ? ps.realName : ps.name);
4485            pw.print("] (");
4486            pw.print(Integer.toHexString(System.identityHashCode(ps)));
4487            pw.println("):");
4488
4489        if (ps.realName != null) {
4490            pw.print(prefix); pw.print("  compat name=");
4491            pw.println(ps.name);
4492        }
4493
4494        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4495
4496        if (ps.sharedUser != null) {
4497            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4498        }
4499        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4500        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4501        if (permissionNames == null) {
4502            pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4503            pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4504            pw.println(ps.legacyNativeLibraryPathString);
4505            pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4506            pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4507        }
4508        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4509        if (ps.pkg != null) {
4510            pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion);
4511            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4512        }
4513        pw.println();
4514        if (ps.pkg != null) {
4515            if (ps.pkg.parentPackage != null) {
4516                PackageParser.Package parentPkg = ps.pkg.parentPackage;
4517                PackageSetting pps = mPackages.get(parentPkg.packageName);
4518                if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
4519                    pps = mDisabledSysPackages.get(parentPkg.packageName);
4520                }
4521                if (pps != null) {
4522                    pw.print(prefix); pw.print("  parentPackage=");
4523                    pw.println(pps.realName != null ? pps.realName : pps.name);
4524                }
4525            } else if (ps.pkg.childPackages != null) {
4526                pw.print(prefix); pw.print("  childPackages=[");
4527                final int childCount = ps.pkg.childPackages.size();
4528                for (int i = 0; i < childCount; i++) {
4529                    PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
4530                    PackageSetting cps = mPackages.get(childPkg.packageName);
4531                    if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
4532                        cps = mDisabledSysPackages.get(childPkg.packageName);
4533                    }
4534                    if (cps != null) {
4535                        if (i > 0) {
4536                            pw.print(", ");
4537                        }
4538                        pw.print(cps.realName != null ? cps.realName : cps.name);
4539                    }
4540                }
4541                pw.println("]");
4542            }
4543            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4544            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4545            final int apkSigningVersion = ps.pkg.mSigningDetails.signatureSchemeVersion;
4546            pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
4547            pw.print(prefix); pw.print("  applicationInfo=");
4548                pw.println(ps.pkg.applicationInfo.toString());
4549            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4550                    FLAG_DUMP_SPEC); pw.println();
4551            if (ps.pkg.applicationInfo.privateFlags != 0) {
4552                pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4553                        ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4554            }
4555            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4556            pw.print(prefix); pw.print("  supportsScreens=[");
4557            boolean first = true;
4558            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4559                if (!first)
4560                    pw.print(", ");
4561                first = false;
4562                pw.print("small");
4563            }
4564            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4565                if (!first)
4566                    pw.print(", ");
4567                first = false;
4568                pw.print("medium");
4569            }
4570            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4571                if (!first)
4572                    pw.print(", ");
4573                first = false;
4574                pw.print("large");
4575            }
4576            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4577                if (!first)
4578                    pw.print(", ");
4579                first = false;
4580                pw.print("xlarge");
4581            }
4582            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4583                if (!first)
4584                    pw.print(", ");
4585                first = false;
4586                pw.print("resizeable");
4587            }
4588            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4589                if (!first)
4590                    pw.print(", ");
4591                first = false;
4592                pw.print("anyDensity");
4593            }
4594            pw.println("]");
4595            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4596                pw.print(prefix); pw.println("  dynamic libraries:");
4597                for (int i = 0; i<ps.pkg.libraryNames.size(); i++) {
4598                    pw.print(prefix); pw.print("    ");
4599                            pw.println(ps.pkg.libraryNames.get(i));
4600                }
4601            }
4602            if (ps.pkg.staticSharedLibName != null) {
4603                pw.print(prefix); pw.println("  static library:");
4604                pw.print(prefix); pw.print("    ");
4605                pw.print("name:"); pw.print(ps.pkg.staticSharedLibName);
4606                pw.print(" version:"); pw.println(ps.pkg.staticSharedLibVersion);
4607            }
4608            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4609                pw.print(prefix); pw.println("  usesLibraries:");
4610                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4611                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4612                }
4613            }
4614            if (ps.pkg.usesStaticLibraries != null
4615                    && ps.pkg.usesStaticLibraries.size() > 0) {
4616                pw.print(prefix); pw.println("  usesStaticLibraries:");
4617                for (int i=0; i<ps.pkg.usesStaticLibraries.size(); i++) {
4618                    pw.print(prefix); pw.print("    ");
4619                    pw.print(ps.pkg.usesStaticLibraries.get(i)); pw.print(" version:");
4620                            pw.println(ps.pkg.usesStaticLibrariesVersions[i]);
4621                }
4622            }
4623            if (ps.pkg.usesOptionalLibraries != null
4624                    && ps.pkg.usesOptionalLibraries.size() > 0) {
4625                pw.print(prefix); pw.println("  usesOptionalLibraries:");
4626                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4627                    pw.print(prefix); pw.print("    ");
4628                    pw.println(ps.pkg.usesOptionalLibraries.get(i));
4629                }
4630            }
4631            if (ps.pkg.usesLibraryFiles != null
4632                    && ps.pkg.usesLibraryFiles.length > 0) {
4633                pw.print(prefix); pw.println("  usesLibraryFiles:");
4634                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4635                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4636                }
4637            }
4638        }
4639        pw.print(prefix); pw.print("  timeStamp=");
4640            date.setTime(ps.timeStamp);
4641            pw.println(sdf.format(date));
4642        pw.print(prefix); pw.print("  firstInstallTime=");
4643            date.setTime(ps.firstInstallTime);
4644            pw.println(sdf.format(date));
4645        pw.print(prefix); pw.print("  lastUpdateTime=");
4646            date.setTime(ps.lastUpdateTime);
4647            pw.println(sdf.format(date));
4648        if (ps.installerPackageName != null) {
4649            pw.print(prefix); pw.print("  installerPackageName=");
4650                    pw.println(ps.installerPackageName);
4651        }
4652        if (ps.volumeUuid != null) {
4653            pw.print(prefix); pw.print("  volumeUuid=");
4654                    pw.println(ps.volumeUuid);
4655        }
4656        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4657        pw.print(prefix); pw.print("  installPermissionsFixed=");
4658                pw.print(ps.installPermissionsFixed);
4659                pw.print(" installStatus="); pw.println(ps.installStatus);
4660        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4661                pw.println();
4662
4663        if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4664            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4665            pw.print(prefix); pw.println("  declared permissions:");
4666            for (int i=0; i<perms.size(); i++) {
4667                PackageParser.Permission perm = perms.get(i);
4668                if (permissionNames != null
4669                        && !permissionNames.contains(perm.info.name)) {
4670                    continue;
4671                }
4672                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4673                pw.print(": prot=");
4674                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4675                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4676                    pw.print(", COSTS_MONEY");
4677                }
4678                if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4679                    pw.print(", HIDDEN");
4680                }
4681                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4682                    pw.print(", INSTALLED");
4683                }
4684                pw.println();
4685            }
4686        }
4687
4688        if ((permissionNames != null || dumpAll) && ps.pkg != null
4689                && ps.pkg.requestedPermissions != null
4690                && ps.pkg.requestedPermissions.size() > 0) {
4691            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4692            pw.print(prefix); pw.println("  requested permissions:");
4693            for (int i=0; i<perms.size(); i++) {
4694                String perm = perms.get(i);
4695                if (permissionNames != null
4696                        && !permissionNames.contains(perm)) {
4697                    continue;
4698                }
4699                pw.print(prefix); pw.print("    "); pw.println(perm);
4700            }
4701        }
4702
4703        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4704            PermissionsState permissionsState = ps.getPermissionsState();
4705            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4706        }
4707
4708        for (UserInfo user : users) {
4709            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4710            pw.print("ceDataInode=");
4711            pw.print(ps.getCeDataInode(user.id));
4712            pw.print(" installed=");
4713            pw.print(ps.getInstalled(user.id));
4714            pw.print(" hidden=");
4715            pw.print(ps.getHidden(user.id));
4716            pw.print(" suspended=");
4717            pw.print(ps.getSuspended(user.id));
4718            pw.print(" stopped=");
4719            pw.print(ps.getStopped(user.id));
4720            pw.print(" notLaunched=");
4721            pw.print(ps.getNotLaunched(user.id));
4722            pw.print(" enabled=");
4723            pw.print(ps.getEnabled(user.id));
4724            pw.print(" instant=");
4725            pw.print(ps.getInstantApp(user.id));
4726            pw.print(" virtual=");
4727            pw.println(ps.getVirtulalPreload(user.id));
4728
4729            String[] overlayPaths = ps.getOverlayPaths(user.id);
4730            if (overlayPaths != null && overlayPaths.length > 0) {
4731                pw.print(prefix); pw.println("  overlay paths:");
4732                for (String path : overlayPaths) {
4733                    pw.print(prefix); pw.print("    "); pw.println(path);
4734                }
4735            }
4736
4737            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4738            if (lastDisabledAppCaller != null) {
4739                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4740                        pw.println(lastDisabledAppCaller);
4741            }
4742
4743            if (ps.sharedUser == null) {
4744                PermissionsState permissionsState = ps.getPermissionsState();
4745                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4746                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4747                        .getRuntimePermissionStates(user.id), dumpAll);
4748            }
4749
4750            String harmfulAppWarning = ps.getHarmfulAppWarning(user.id);
4751            if (harmfulAppWarning != null) {
4752                pw.print(prefix); pw.print("      harmfulAppWarning: ");
4753                pw.println(harmfulAppWarning);
4754            }
4755
4756            if (permissionNames == null) {
4757                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4758                if (cmp != null && cmp.size() > 0) {
4759                    pw.print(prefix); pw.println("    disabledComponents:");
4760                    for (String s : cmp) {
4761                        pw.print(prefix); pw.print("      "); pw.println(s);
4762                    }
4763                }
4764                cmp = ps.getEnabledComponents(user.id);
4765                if (cmp != null && cmp.size() > 0) {
4766                    pw.print(prefix); pw.println("    enabledComponents:");
4767                    for (String s : cmp) {
4768                        pw.print(prefix); pw.print("      "); pw.println(s);
4769                    }
4770                }
4771            }
4772        }
4773    }
4774
4775    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4776            DumpState dumpState, boolean checkin) {
4777        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4778        final Date date = new Date();
4779        boolean printedSomething = false;
4780        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4781        for (final PackageSetting ps : mPackages.values()) {
4782            if (packageName != null && !packageName.equals(ps.realName)
4783                    && !packageName.equals(ps.name)) {
4784                continue;
4785            }
4786            if (permissionNames != null
4787                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4788                continue;
4789            }
4790
4791            if (!checkin && packageName != null) {
4792                dumpState.setSharedUser(ps.sharedUser);
4793            }
4794
4795            if (!checkin && !printedSomething) {
4796                if (dumpState.onTitlePrinted())
4797                    pw.println();
4798                pw.println("Packages:");
4799                printedSomething = true;
4800            }
4801            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4802                    packageName != null);
4803        }
4804
4805        printedSomething = false;
4806        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4807            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4808                if (packageName != null && !packageName.equals(e.getKey())
4809                        && !packageName.equals(e.getValue())) {
4810                    continue;
4811                }
4812                if (!checkin) {
4813                    if (!printedSomething) {
4814                        if (dumpState.onTitlePrinted())
4815                            pw.println();
4816                        pw.println("Renamed packages:");
4817                        printedSomething = true;
4818                    }
4819                    pw.print("  ");
4820                } else {
4821                    pw.print("ren,");
4822                }
4823                pw.print(e.getKey());
4824                pw.print(checkin ? " -> " : ",");
4825                pw.println(e.getValue());
4826            }
4827        }
4828
4829        printedSomething = false;
4830        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4831            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4832                if (packageName != null && !packageName.equals(ps.realName)
4833                        && !packageName.equals(ps.name)) {
4834                    continue;
4835                }
4836                if (!checkin && !printedSomething) {
4837                    if (dumpState.onTitlePrinted())
4838                        pw.println();
4839                    pw.println("Hidden system packages:");
4840                    printedSomething = true;
4841                }
4842                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4843                        users, packageName != null);
4844            }
4845        }
4846    }
4847
4848    void dumpPackagesProto(ProtoOutputStream proto) {
4849        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4850
4851        final int count = mPackages.size();
4852        for (int i = 0; i < count; i++) {
4853            final PackageSetting ps = mPackages.valueAt(i);
4854            ps.writeToProto(proto, PackageServiceDumpProto.PACKAGES, users);
4855        }
4856    }
4857
4858    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4859            DumpState dumpState) {
4860        mPermissions.dumpPermissions(pw, packageName, permissionNames,
4861                (mReadExternalStorageEnforced == Boolean.TRUE), dumpState);
4862    }
4863
4864    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4865            DumpState dumpState, boolean checkin) {
4866        boolean printedSomething = false;
4867        for (SharedUserSetting su : mSharedUsers.values()) {
4868            if (packageName != null && su != dumpState.getSharedUser()) {
4869                continue;
4870            }
4871            if (permissionNames != null
4872                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4873                continue;
4874            }
4875            if (!checkin) {
4876                if (!printedSomething) {
4877                    if (dumpState.onTitlePrinted())
4878                        pw.println();
4879                    pw.println("Shared users:");
4880                    printedSomething = true;
4881                }
4882                pw.print("  SharedUser [");
4883                pw.print(su.name);
4884                pw.print("] (");
4885                pw.print(Integer.toHexString(System.identityHashCode(su)));
4886                        pw.println("):");
4887
4888                String prefix = "    ";
4889                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4890
4891                PermissionsState permissionsState = su.getPermissionsState();
4892                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4893
4894                for (int userId : UserManagerService.getInstance().getUserIds()) {
4895                    final int[] gids = permissionsState.computeGids(userId);
4896                    List<PermissionState> permissions = permissionsState
4897                            .getRuntimePermissionStates(userId);
4898                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4899                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4900                        dumpGidsLPr(pw, prefix + "  ", gids);
4901                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4902                                packageName != null);
4903                    }
4904                }
4905            } else {
4906                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4907            }
4908        }
4909    }
4910
4911    void dumpSharedUsersProto(ProtoOutputStream proto) {
4912        final int count = mSharedUsers.size();
4913        for (int i = 0; i < count; i++) {
4914            mSharedUsers.valueAt(i).writeToProto(proto, PackageServiceDumpProto.SHARED_USERS);
4915        }
4916    }
4917
4918    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4919        pw.println("Settings parse messages:");
4920        pw.print(mReadMessages.toString());
4921    }
4922
4923    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4924        if (mRestoredUserGrants.size() > 0) {
4925            pw.println();
4926            pw.println("Restored (pending) permission grants:");
4927            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4928                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4929                        mRestoredUserGrants.valueAt(userIndex);
4930                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4931                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4932                    pw.print("  User "); pw.println(userId);
4933
4934                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4935                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4936                        if (grants != null && grants.size() > 0) {
4937                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4938                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4939
4940                            for (RestoredPermissionGrant g : grants) {
4941                                pw.print("      ");
4942                                pw.print(g.permissionName);
4943                                if (g.granted) {
4944                                    pw.print(" GRANTED");
4945                                }
4946                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4947                                    pw.print(" user_set");
4948                                }
4949                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4950                                    pw.print(" user_fixed");
4951                                }
4952                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4953                                    pw.print(" revoke_on_upgrade");
4954                                }
4955                                pw.println();
4956                            }
4957                        }
4958                    }
4959                }
4960            }
4961            pw.println();
4962        }
4963    }
4964
4965    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4966        if (pkg == null) {
4967            pw.print("unknown");
4968        } else {
4969            // [base:10, config.mdpi, config.xhdpi:12]
4970            pw.print("[");
4971            pw.print("base");
4972            if (pkg.baseRevisionCode != 0) {
4973                pw.print(":"); pw.print(pkg.baseRevisionCode);
4974            }
4975            if (pkg.splitNames != null) {
4976                for (int i = 0; i < pkg.splitNames.length; i++) {
4977                    pw.print(", ");
4978                    pw.print(pkg.splitNames[i]);
4979                    if (pkg.splitRevisionCodes[i] != 0) {
4980                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4981                    }
4982                }
4983            }
4984            pw.print("]");
4985        }
4986    }
4987
4988    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4989        if (!ArrayUtils.isEmpty(gids)) {
4990            pw.print(prefix);
4991            pw.print("gids="); pw.println(
4992                    PackageManagerService.arrayToString(gids));
4993        }
4994    }
4995
4996    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4997            List<PermissionState> permissionStates, boolean dumpAll) {
4998        if (!permissionStates.isEmpty() || dumpAll) {
4999            pw.print(prefix); pw.println("runtime permissions:");
5000            for (PermissionState permissionState : permissionStates) {
5001                if (permissionNames != null
5002                        && !permissionNames.contains(permissionState.getName())) {
5003                    continue;
5004                }
5005                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5006                pw.print(": granted="); pw.print(permissionState.isGranted());
5007                    pw.println(permissionFlagsToString(", flags=",
5008                            permissionState.getFlags()));
5009            }
5010        }
5011    }
5012
5013    private static String permissionFlagsToString(String prefix, int flags) {
5014        StringBuilder flagsString = null;
5015        while (flags != 0) {
5016            if (flagsString == null) {
5017                flagsString = new StringBuilder();
5018                flagsString.append(prefix);
5019                flagsString.append("[ ");
5020            }
5021            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5022            flags &= ~flag;
5023            flagsString.append(PackageManager.permissionFlagToString(flag));
5024            flagsString.append(' ');
5025        }
5026        if (flagsString != null) {
5027            flagsString.append(']');
5028            return flagsString.toString();
5029        } else {
5030            return "";
5031        }
5032    }
5033
5034    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
5035            PermissionsState permissionsState) {
5036        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
5037        if (!permissionStates.isEmpty()) {
5038            pw.print(prefix); pw.println("install permissions:");
5039            for (PermissionState permissionState : permissionStates) {
5040                if (permissionNames != null
5041                        && !permissionNames.contains(permissionState.getName())) {
5042                    continue;
5043                }
5044                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
5045                    pw.print(": granted="); pw.print(permissionState.isGranted());
5046                    pw.println(permissionFlagsToString(", flags=",
5047                        permissionState.getFlags()));
5048            }
5049        }
5050    }
5051
5052    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
5053        if (sync) {
5054            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
5055        } else {
5056            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
5057        }
5058    }
5059
5060    private final class RuntimePermissionPersistence {
5061        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
5062        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
5063
5064        private final Handler mHandler = new MyHandler();
5065
5066        private final Object mPersistenceLock;
5067
5068        @GuardedBy("mLock")
5069        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
5070
5071        @GuardedBy("mLock")
5072        // The mapping keys are user ids.
5073        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
5074
5075        @GuardedBy("mLock")
5076        // The mapping keys are user ids.
5077        private final SparseArray<String> mFingerprints = new SparseArray<>();
5078
5079        @GuardedBy("mLock")
5080        // The mapping keys are user ids.
5081        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
5082
5083        public RuntimePermissionPersistence(Object persistenceLock) {
5084            mPersistenceLock = persistenceLock;
5085        }
5086
5087        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
5088            return mDefaultPermissionsGranted.get(userId);
5089        }
5090
5091        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
5092            mFingerprints.put(userId, Build.FINGERPRINT);
5093            writePermissionsForUserAsyncLPr(userId);
5094        }
5095
5096        public void writePermissionsForUserSyncLPr(int userId) {
5097            mHandler.removeMessages(userId);
5098            writePermissionsSync(userId);
5099        }
5100
5101        public void writePermissionsForUserAsyncLPr(int userId) {
5102            final long currentTimeMillis = SystemClock.uptimeMillis();
5103
5104            if (mWriteScheduled.get(userId)) {
5105                mHandler.removeMessages(userId);
5106
5107                // If enough time passed, write without holding off anymore.
5108                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
5109                        .get(userId);
5110                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
5111                        - lastNotWrittenMutationTimeMillis;
5112                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
5113                    mHandler.obtainMessage(userId).sendToTarget();
5114                    return;
5115                }
5116
5117                // Hold off a bit more as settings are frequently changing.
5118                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
5119                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
5120                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
5121                        maxDelayMillis);
5122
5123                Message message = mHandler.obtainMessage(userId);
5124                mHandler.sendMessageDelayed(message, writeDelayMillis);
5125            } else {
5126                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
5127                Message message = mHandler.obtainMessage(userId);
5128                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
5129                mWriteScheduled.put(userId, true);
5130            }
5131        }
5132
5133        private void writePermissionsSync(int userId) {
5134            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
5135
5136            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
5137            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
5138
5139            synchronized (mPersistenceLock) {
5140                mWriteScheduled.delete(userId);
5141
5142                final int packageCount = mPackages.size();
5143                for (int i = 0; i < packageCount; i++) {
5144                    String packageName = mPackages.keyAt(i);
5145                    PackageSetting packageSetting = mPackages.valueAt(i);
5146                    if (packageSetting.sharedUser == null) {
5147                        PermissionsState permissionsState = packageSetting.getPermissionsState();
5148                        List<PermissionState> permissionsStates = permissionsState
5149                                .getRuntimePermissionStates(userId);
5150                        if (!permissionsStates.isEmpty()) {
5151                            permissionsForPackage.put(packageName, permissionsStates);
5152                        }
5153                    }
5154                }
5155
5156                final int sharedUserCount = mSharedUsers.size();
5157                for (int i = 0; i < sharedUserCount; i++) {
5158                    String sharedUserName = mSharedUsers.keyAt(i);
5159                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
5160                    PermissionsState permissionsState = sharedUser.getPermissionsState();
5161                    List<PermissionState> permissionsStates = permissionsState
5162                            .getRuntimePermissionStates(userId);
5163                    if (!permissionsStates.isEmpty()) {
5164                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
5165                    }
5166                }
5167            }
5168
5169            FileOutputStream out = null;
5170            try {
5171                out = destination.startWrite();
5172
5173                XmlSerializer serializer = Xml.newSerializer();
5174                serializer.setOutput(out, StandardCharsets.UTF_8.name());
5175                serializer.setFeature(
5176                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
5177                serializer.startDocument(null, true);
5178
5179                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
5180
5181                String fingerprint = mFingerprints.get(userId);
5182                if (fingerprint != null) {
5183                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
5184                }
5185
5186                final int packageCount = permissionsForPackage.size();
5187                for (int i = 0; i < packageCount; i++) {
5188                    String packageName = permissionsForPackage.keyAt(i);
5189                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
5190                    serializer.startTag(null, TAG_PACKAGE);
5191                    serializer.attribute(null, ATTR_NAME, packageName);
5192                    writePermissions(serializer, permissionStates);
5193                    serializer.endTag(null, TAG_PACKAGE);
5194                }
5195
5196                final int sharedUserCount = permissionsForSharedUser.size();
5197                for (int i = 0; i < sharedUserCount; i++) {
5198                    String packageName = permissionsForSharedUser.keyAt(i);
5199                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
5200                    serializer.startTag(null, TAG_SHARED_USER);
5201                    serializer.attribute(null, ATTR_NAME, packageName);
5202                    writePermissions(serializer, permissionStates);
5203                    serializer.endTag(null, TAG_SHARED_USER);
5204                }
5205
5206                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
5207
5208                // Now any restored permission grants that are waiting for the apps
5209                // in question to be installed.  These are stored as per-package
5210                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
5211                // number of individual permission grant entities.
5212                if (mRestoredUserGrants.get(userId) != null) {
5213                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
5214                            mRestoredUserGrants.get(userId);
5215                    if (restoredGrants != null) {
5216                        final int pkgCount = restoredGrants.size();
5217                        for (int i = 0; i < pkgCount; i++) {
5218                            final ArraySet<RestoredPermissionGrant> pkgGrants =
5219                                    restoredGrants.valueAt(i);
5220                            if (pkgGrants != null && pkgGrants.size() > 0) {
5221                                final String pkgName = restoredGrants.keyAt(i);
5222                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5223                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
5224
5225                                final int N = pkgGrants.size();
5226                                for (int z = 0; z < N; z++) {
5227                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
5228                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
5229                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
5230
5231                                    if (g.granted) {
5232                                        serializer.attribute(null, ATTR_GRANTED, "true");
5233                                    }
5234
5235                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
5236                                        serializer.attribute(null, ATTR_USER_SET, "true");
5237                                    }
5238                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
5239                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
5240                                    }
5241                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
5242                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
5243                                    }
5244                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
5245                                }
5246                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5247                            }
5248                        }
5249                    }
5250                }
5251
5252                serializer.endDocument();
5253                destination.finishWrite(out);
5254
5255                if (Build.FINGERPRINT.equals(fingerprint)) {
5256                    mDefaultPermissionsGranted.put(userId, true);
5257                }
5258            // Any error while writing is fatal.
5259            } catch (Throwable t) {
5260                Slog.wtf(PackageManagerService.TAG,
5261                        "Failed to write settings, restoring backup", t);
5262                destination.failWrite(out);
5263            } finally {
5264                IoUtils.closeQuietly(out);
5265            }
5266        }
5267
5268        private void onUserRemovedLPw(int userId) {
5269            // Make sure we do not
5270            mHandler.removeMessages(userId);
5271
5272            for (SettingBase sb : mPackages.values()) {
5273                revokeRuntimePermissionsAndClearFlags(sb, userId);
5274            }
5275
5276            for (SettingBase sb : mSharedUsers.values()) {
5277                revokeRuntimePermissionsAndClearFlags(sb, userId);
5278            }
5279
5280            mDefaultPermissionsGranted.delete(userId);
5281            mFingerprints.remove(userId);
5282        }
5283
5284        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5285            PermissionsState permissionsState = sb.getPermissionsState();
5286            for (PermissionState permissionState
5287                    : permissionsState.getRuntimePermissionStates(userId)) {
5288                BasePermission bp = mPermissions.getPermission(permissionState.getName());
5289                if (bp != null) {
5290                    permissionsState.revokeRuntimePermission(bp, userId);
5291                    permissionsState.updatePermissionFlags(bp, userId,
5292                            PackageManager.MASK_PERMISSION_FLAGS, 0);
5293                }
5294            }
5295        }
5296
5297        public void deleteUserRuntimePermissionsFile(int userId) {
5298            getUserRuntimePermissionsFile(userId).delete();
5299        }
5300
5301        public void readStateForUserSyncLPr(int userId) {
5302            File permissionsFile = getUserRuntimePermissionsFile(userId);
5303            if (!permissionsFile.exists()) {
5304                return;
5305            }
5306
5307            FileInputStream in;
5308            try {
5309                in = new AtomicFile(permissionsFile).openRead();
5310            } catch (FileNotFoundException fnfe) {
5311                Slog.i(PackageManagerService.TAG, "No permissions state");
5312                return;
5313            }
5314
5315            try {
5316                XmlPullParser parser = Xml.newPullParser();
5317                parser.setInput(in, null);
5318                parseRuntimePermissionsLPr(parser, userId);
5319
5320            } catch (XmlPullParserException | IOException e) {
5321                throw new IllegalStateException("Failed parsing permissions file: "
5322                        + permissionsFile , e);
5323            } finally {
5324                IoUtils.closeQuietly(in);
5325            }
5326        }
5327
5328        // Backup/restore support
5329
5330        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
5331                boolean isGranted, int restoredFlagSet, int userId) {
5332            // This change will be remembered at write-settings time
5333            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
5334                    mRestoredUserGrants.get(userId);
5335            if (grantsByPackage == null) {
5336                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
5337                mRestoredUserGrants.put(userId, grantsByPackage);
5338            }
5339
5340            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
5341            if (grants == null) {
5342                grants = new ArraySet<RestoredPermissionGrant>();
5343                grantsByPackage.put(pkgName, grants);
5344            }
5345
5346            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
5347                    isGranted, restoredFlagSet);
5348            grants.add(grant);
5349        }
5350
5351        // Private internals
5352
5353        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5354                throws IOException, XmlPullParserException {
5355            final int outerDepth = parser.getDepth();
5356            int type;
5357            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5358                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5359                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5360                    continue;
5361                }
5362
5363                switch (parser.getName()) {
5364                    case TAG_RUNTIME_PERMISSIONS: {
5365                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5366                        mFingerprints.put(userId, fingerprint);
5367                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5368                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
5369                    } break;
5370
5371                    case TAG_PACKAGE: {
5372                        String name = parser.getAttributeValue(null, ATTR_NAME);
5373                        PackageSetting ps = mPackages.get(name);
5374                        if (ps == null) {
5375                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5376                            XmlUtils.skipCurrentTag(parser);
5377                            continue;
5378                        }
5379                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5380                    } break;
5381
5382                    case TAG_SHARED_USER: {
5383                        String name = parser.getAttributeValue(null, ATTR_NAME);
5384                        SharedUserSetting sus = mSharedUsers.get(name);
5385                        if (sus == null) {
5386                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5387                            XmlUtils.skipCurrentTag(parser);
5388                            continue;
5389                        }
5390                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5391                    } break;
5392
5393                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
5394                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
5395                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
5396                    } break;
5397                }
5398            }
5399        }
5400
5401        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
5402                final String pkgName, final int userId) throws IOException, XmlPullParserException {
5403            final int outerDepth = parser.getDepth();
5404            int type;
5405            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5406                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5407                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5408                    continue;
5409                }
5410
5411                switch (parser.getName()) {
5412                    case TAG_PERMISSION_ENTRY: {
5413                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
5414                        final boolean isGranted = "true".equals(
5415                                parser.getAttributeValue(null, ATTR_GRANTED));
5416
5417                        int permBits = 0;
5418                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
5419                            permBits |= FLAG_PERMISSION_USER_SET;
5420                        }
5421                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
5422                            permBits |= FLAG_PERMISSION_USER_FIXED;
5423                        }
5424                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
5425                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
5426                        }
5427
5428                        if (isGranted || permBits != 0) {
5429                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5430                        }
5431                    } break;
5432                }
5433            }
5434        }
5435
5436        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5437                int userId) throws IOException, XmlPullParserException {
5438            final int outerDepth = parser.getDepth();
5439            int type;
5440            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5441                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5442                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5443                    continue;
5444                }
5445
5446                switch (parser.getName()) {
5447                    case TAG_ITEM: {
5448                        String name = parser.getAttributeValue(null, ATTR_NAME);
5449                        BasePermission bp = mPermissions.getPermission(name);
5450                        if (bp == null) {
5451                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5452                            XmlUtils.skipCurrentTag(parser);
5453                            continue;
5454                        }
5455
5456                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5457                        final boolean granted = grantedStr == null
5458                                || Boolean.parseBoolean(grantedStr);
5459
5460                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5461                        final int flags = (flagsStr != null)
5462                                ? Integer.parseInt(flagsStr, 16) : 0;
5463
5464                        if (granted) {
5465                            permissionsState.grantRuntimePermission(bp, userId);
5466                            permissionsState.updatePermissionFlags(bp, userId,
5467                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5468                        } else {
5469                            permissionsState.updatePermissionFlags(bp, userId,
5470                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5471                        }
5472
5473                    } break;
5474                }
5475            }
5476        }
5477
5478        private void writePermissions(XmlSerializer serializer,
5479                List<PermissionState> permissionStates) throws IOException {
5480            for (PermissionState permissionState : permissionStates) {
5481                serializer.startTag(null, TAG_ITEM);
5482                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5483                serializer.attribute(null, ATTR_GRANTED,
5484                        String.valueOf(permissionState.isGranted()));
5485                serializer.attribute(null, ATTR_FLAGS,
5486                        Integer.toHexString(permissionState.getFlags()));
5487                serializer.endTag(null, TAG_ITEM);
5488            }
5489        }
5490
5491        private final class MyHandler extends Handler {
5492            public MyHandler() {
5493                super(BackgroundThread.getHandler().getLooper());
5494            }
5495
5496            @Override
5497            public void handleMessage(Message message) {
5498                final int userId = message.what;
5499                Runnable callback = (Runnable) message.obj;
5500                writePermissionsSync(userId);
5501                if (callback != null) {
5502                    callback.run();
5503                }
5504            }
5505        }
5506    }
5507}
5508