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