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