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