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