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