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