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