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