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