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