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