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