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