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