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