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