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