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