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