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