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