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