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