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