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