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