Settings.java revision 8a372a0a280127743ce9a7ce4b6198c7a02d2a4f
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            new File(mKernelMappingFilename, name).delete();
2391        }
2392    }
2393
2394    void writeKernelMappingLPr(PackageSetting ps) {
2395        if (mKernelMappingFilename == null) return;
2396
2397        final Integer cur = mKernelMapping.get(ps.name);
2398        if (cur != null && cur.intValue() == ps.appId) {
2399            // Ignore when mapping already matches
2400            return;
2401        }
2402
2403        if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + ps.name + " to " + ps.appId);
2404
2405        final File dir = new File(mKernelMappingFilename, ps.name);
2406        dir.mkdir();
2407
2408        final File file = new File(dir, "appid");
2409        try {
2410            FileUtils.stringToFile(file, Integer.toString(ps.appId));
2411            mKernelMapping.put(ps.name, ps.appId);
2412        } catch (IOException ignored) {
2413        }
2414    }
2415
2416    void writePackageListLPr() {
2417        writePackageListLPr(-1);
2418    }
2419
2420    void writePackageListLPr(int creatingUserId) {
2421        // Only derive GIDs for active users (not dying)
2422        final List<UserInfo> users = UserManagerService.getInstance().getUsers(true);
2423        int[] userIds = new int[users.size()];
2424        for (int i = 0; i < userIds.length; i++) {
2425            userIds[i] = users.get(i).id;
2426        }
2427        if (creatingUserId != -1) {
2428            userIds = ArrayUtils.appendInt(userIds, creatingUserId);
2429        }
2430
2431        // Write package list file now, use a JournaledFile.
2432        File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
2433        JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
2434
2435        final File writeTarget = journal.chooseForWrite();
2436        FileOutputStream fstr;
2437        BufferedWriter writer = null;
2438        try {
2439            fstr = new FileOutputStream(writeTarget);
2440            writer = new BufferedWriter(new OutputStreamWriter(fstr, Charset.defaultCharset()));
2441            FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
2442
2443            StringBuilder sb = new StringBuilder();
2444            for (final PackageSetting pkg : mPackages.values()) {
2445                if (pkg.pkg == null || pkg.pkg.applicationInfo == null
2446                        || pkg.pkg.applicationInfo.dataDir == null) {
2447                    if (!"android".equals(pkg.name)) {
2448                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
2449                    }
2450                    continue;
2451                }
2452
2453                final ApplicationInfo ai = pkg.pkg.applicationInfo;
2454                final String dataPath = ai.dataDir;
2455                final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
2456                final int[] gids = pkg.getPermissionsState().computeGids(userIds);
2457
2458                // Avoid any application that has a space in its path.
2459                if (dataPath.indexOf(' ') >= 0)
2460                    continue;
2461
2462                // we store on each line the following information for now:
2463                //
2464                // pkgName    - package name
2465                // userId     - application-specific user id
2466                // debugFlag  - 0 or 1 if the package is debuggable.
2467                // dataPath   - path to package's data path
2468                // seinfo     - seinfo label for the app (assigned at install time)
2469                // gids       - supplementary gids this app launches with
2470                //
2471                // NOTE: We prefer not to expose all ApplicationInfo flags for now.
2472                //
2473                // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
2474                // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
2475                //   frameworks/base/libs/packagelistparser
2476                //   system/core/run-as/run-as.c
2477                //
2478                sb.setLength(0);
2479                sb.append(ai.packageName);
2480                sb.append(" ");
2481                sb.append(ai.uid);
2482                sb.append(isDebug ? " 1 " : " 0 ");
2483                sb.append(dataPath);
2484                sb.append(" ");
2485                sb.append(ai.seinfo);
2486                sb.append(" ");
2487                if (gids != null && gids.length > 0) {
2488                    sb.append(gids[0]);
2489                    for (int i = 1; i < gids.length; i++) {
2490                        sb.append(",");
2491                        sb.append(gids[i]);
2492                    }
2493                } else {
2494                    sb.append("none");
2495                }
2496                sb.append("\n");
2497                writer.append(sb);
2498            }
2499            writer.flush();
2500            FileUtils.sync(fstr);
2501            writer.close();
2502            journal.commit();
2503        } catch (Exception e) {
2504            Slog.wtf(TAG, "Failed to write packages.list", e);
2505            IoUtils.closeQuietly(writer);
2506            journal.rollback();
2507        }
2508    }
2509
2510    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2511            throws java.io.IOException {
2512        serializer.startTag(null, "updated-package");
2513        serializer.attribute(null, ATTR_NAME, pkg.name);
2514        if (pkg.realName != null) {
2515            serializer.attribute(null, "realName", pkg.realName);
2516        }
2517        serializer.attribute(null, "codePath", pkg.codePathString);
2518        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2519        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2520        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2521        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2522        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2523            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2524        }
2525        if (pkg.legacyNativeLibraryPathString != null) {
2526            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2527        }
2528        if (pkg.primaryCpuAbiString != null) {
2529           serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2530        }
2531        if (pkg.secondaryCpuAbiString != null) {
2532            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2533        }
2534        if (pkg.cpuAbiOverrideString != null) {
2535            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2536        }
2537
2538        if (pkg.sharedUser == null) {
2539            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2540        } else {
2541            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2542        }
2543
2544        if (pkg.parentPackageName != null) {
2545            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2546        }
2547
2548        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2549
2550        // If this is a shared user, the permissions will be written there.
2551        if (pkg.sharedUser == null) {
2552            writePermissionsLPr(serializer, pkg.getPermissionsState()
2553                    .getInstallPermissionStates());
2554        }
2555
2556        serializer.endTag(null, "updated-package");
2557    }
2558
2559    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2560            throws java.io.IOException {
2561        serializer.startTag(null, "package");
2562        serializer.attribute(null, ATTR_NAME, pkg.name);
2563        if (pkg.realName != null) {
2564            serializer.attribute(null, "realName", pkg.realName);
2565        }
2566        serializer.attribute(null, "codePath", pkg.codePathString);
2567        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2568            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2569        }
2570
2571        if (pkg.legacyNativeLibraryPathString != null) {
2572            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2573        }
2574        if (pkg.primaryCpuAbiString != null) {
2575            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2576        }
2577        if (pkg.secondaryCpuAbiString != null) {
2578            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2579        }
2580        if (pkg.cpuAbiOverrideString != null) {
2581            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2582        }
2583
2584        serializer.attribute(null, "publicFlags", Integer.toString(pkg.pkgFlags));
2585        serializer.attribute(null, "privateFlags", Integer.toString(pkg.pkgPrivateFlags));
2586        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2587        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2588        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2589        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2590        if (pkg.sharedUser == null) {
2591            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2592        } else {
2593            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2594        }
2595        if (pkg.uidError) {
2596            serializer.attribute(null, "uidError", "true");
2597        }
2598        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2599            serializer.attribute(null, "installStatus", "false");
2600        }
2601        if (pkg.installerPackageName != null) {
2602            serializer.attribute(null, "installer", pkg.installerPackageName);
2603        }
2604        if (pkg.volumeUuid != null) {
2605            serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
2606        }
2607        if (pkg.parentPackageName != null) {
2608            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2609        }
2610
2611        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2612
2613        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
2614
2615        writePermissionsLPr(serializer, pkg.getPermissionsState()
2616                    .getInstallPermissionStates());
2617
2618        writeSigningKeySetLPr(serializer, pkg.keySetData);
2619        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
2620        writeKeySetAliasesLPr(serializer, pkg.keySetData);
2621        writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
2622
2623        serializer.endTag(null, "package");
2624    }
2625
2626    void writeSigningKeySetLPr(XmlSerializer serializer,
2627            PackageKeySetData data) throws IOException {
2628        serializer.startTag(null, "proper-signing-keyset");
2629        serializer.attribute(null, "identifier",
2630                Long.toString(data.getProperSigningKeySet()));
2631        serializer.endTag(null, "proper-signing-keyset");
2632    }
2633
2634    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2635            PackageKeySetData data) throws IOException {
2636        long properSigning = data.getProperSigningKeySet();
2637        if (data.isUsingUpgradeKeySets()) {
2638            for (long id : data.getUpgradeKeySets()) {
2639                serializer.startTag(null, "upgrade-keyset");
2640                serializer.attribute(null, "identifier", Long.toString(id));
2641                serializer.endTag(null, "upgrade-keyset");
2642            }
2643        }
2644    }
2645
2646    void writeKeySetAliasesLPr(XmlSerializer serializer,
2647            PackageKeySetData data) throws IOException {
2648        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2649            serializer.startTag(null, "defined-keyset");
2650            serializer.attribute(null, "alias", e.getKey());
2651            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2652            serializer.endTag(null, "defined-keyset");
2653        }
2654    }
2655
2656    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
2657            throws XmlPullParserException, java.io.IOException {
2658        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
2659            serializer.startTag(null, TAG_ITEM);
2660            serializer.attribute(null, ATTR_NAME, bp.name);
2661            serializer.attribute(null, "package", bp.sourcePackage);
2662            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
2663                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
2664            }
2665            if (PackageManagerService.DEBUG_SETTINGS)
2666                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
2667                        + bp.type);
2668            if (bp.type == BasePermission.TYPE_DYNAMIC) {
2669                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
2670                if (pi != null) {
2671                    serializer.attribute(null, "type", "dynamic");
2672                    if (pi.icon != 0) {
2673                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
2674                    }
2675                    if (pi.nonLocalizedLabel != null) {
2676                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
2677                    }
2678                }
2679            }
2680            serializer.endTag(null, TAG_ITEM);
2681        }
2682    }
2683
2684    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
2685        final ArraySet<String> kList = new ArraySet<String>(mPackages.keySet());
2686        final Iterator<String> its = kList.iterator();
2687        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
2688        while (its.hasNext()) {
2689            final String key = its.next();
2690            final PackageSetting ps = mPackages.get(key);
2691            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2692                ret.add(ps);
2693            }
2694        }
2695        return ret;
2696    }
2697
2698    void addPackageToCleanLPw(PackageCleanItem pkg) {
2699        if (!mPackagesToBeCleaned.contains(pkg)) {
2700            mPackagesToBeCleaned.add(pkg);
2701        }
2702    }
2703
2704    boolean readLPw(@NonNull List<UserInfo> users) {
2705        FileInputStream str = null;
2706        if (mBackupSettingsFilename.exists()) {
2707            try {
2708                str = new FileInputStream(mBackupSettingsFilename);
2709                mReadMessages.append("Reading from backup settings file\n");
2710                PackageManagerService.reportSettingsProblem(Log.INFO,
2711                        "Need to read from backup settings file");
2712                if (mSettingsFilename.exists()) {
2713                    // If both the backup and settings file exist, we
2714                    // ignore the settings since it might have been
2715                    // corrupted.
2716                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2717                            + mSettingsFilename);
2718                    mSettingsFilename.delete();
2719                }
2720            } catch (java.io.IOException e) {
2721                // We'll try for the normal settings file.
2722            }
2723        }
2724
2725        mPendingPackages.clear();
2726        mPastSignatures.clear();
2727        mKeySetRefs.clear();
2728
2729        try {
2730            if (str == null) {
2731                if (!mSettingsFilename.exists()) {
2732                    mReadMessages.append("No settings file found\n");
2733                    PackageManagerService.reportSettingsProblem(Log.INFO,
2734                            "No settings file; creating initial state");
2735                    // It's enough to just touch version details to create them
2736                    // with default values
2737                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL);
2738                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL);
2739                    return false;
2740                }
2741                str = new FileInputStream(mSettingsFilename);
2742            }
2743            XmlPullParser parser = Xml.newPullParser();
2744            parser.setInput(str, StandardCharsets.UTF_8.name());
2745
2746            int type;
2747            while ((type = parser.next()) != XmlPullParser.START_TAG
2748                    && type != XmlPullParser.END_DOCUMENT) {
2749                ;
2750            }
2751
2752            if (type != XmlPullParser.START_TAG) {
2753                mReadMessages.append("No start tag found in settings file\n");
2754                PackageManagerService.reportSettingsProblem(Log.WARN,
2755                        "No start tag found in package manager settings");
2756                Slog.wtf(PackageManagerService.TAG,
2757                        "No start tag found in package manager settings");
2758                return false;
2759            }
2760
2761            int outerDepth = parser.getDepth();
2762            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2763                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2764                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2765                    continue;
2766                }
2767
2768                String tagName = parser.getName();
2769                if (tagName.equals("package")) {
2770                    readPackageLPw(parser);
2771                } else if (tagName.equals("permissions")) {
2772                    readPermissionsLPw(mPermissions, parser);
2773                } else if (tagName.equals("permission-trees")) {
2774                    readPermissionsLPw(mPermissionTrees, parser);
2775                } else if (tagName.equals("shared-user")) {
2776                    readSharedUserLPw(parser);
2777                } else if (tagName.equals("preferred-packages")) {
2778                    // no longer used.
2779                } else if (tagName.equals("preferred-activities")) {
2780                    // Upgrading from old single-user implementation;
2781                    // these are the preferred activities for user 0.
2782                    readPreferredActivitiesLPw(parser, 0);
2783                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2784                    // TODO: check whether this is okay! as it is very
2785                    // similar to how preferred-activities are treated
2786                    readPersistentPreferredActivitiesLPw(parser, 0);
2787                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2788                    // TODO: check whether this is okay! as it is very
2789                    // similar to how preferred-activities are treated
2790                    readCrossProfileIntentFiltersLPw(parser, 0);
2791                } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
2792                    readDefaultAppsLPw(parser, 0);
2793                } else if (tagName.equals("updated-package")) {
2794                    readDisabledSysPackageLPw(parser);
2795                } else if (tagName.equals("cleaning-package")) {
2796                    String name = parser.getAttributeValue(null, ATTR_NAME);
2797                    String userStr = parser.getAttributeValue(null, ATTR_USER);
2798                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
2799                    if (name != null) {
2800                        int userId = UserHandle.USER_SYSTEM;
2801                        boolean andCode = true;
2802                        try {
2803                            if (userStr != null) {
2804                                userId = Integer.parseInt(userStr);
2805                            }
2806                        } catch (NumberFormatException e) {
2807                        }
2808                        if (codeStr != null) {
2809                            andCode = Boolean.parseBoolean(codeStr);
2810                        }
2811                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
2812                    }
2813                } else if (tagName.equals("renamed-package")) {
2814                    String nname = parser.getAttributeValue(null, "new");
2815                    String oname = parser.getAttributeValue(null, "old");
2816                    if (nname != null && oname != null) {
2817                        mRenamedPackages.put(nname, oname);
2818                    }
2819                } else if (tagName.equals("restored-ivi")) {
2820                    readRestoredIntentFilterVerifications(parser);
2821                } else if (tagName.equals("last-platform-version")) {
2822                    // Upgrade from older XML schema
2823                    final VersionInfo internal = findOrCreateVersion(
2824                            StorageManager.UUID_PRIVATE_INTERNAL);
2825                    final VersionInfo external = findOrCreateVersion(
2826                            StorageManager.UUID_PRIMARY_PHYSICAL);
2827
2828                    internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
2829                    external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
2830                    internal.fingerprint = external.fingerprint =
2831                            XmlUtils.readStringAttribute(parser, "fingerprint");
2832
2833                } else if (tagName.equals("database-version")) {
2834                    // Upgrade from older XML schema
2835                    final VersionInfo internal = findOrCreateVersion(
2836                            StorageManager.UUID_PRIVATE_INTERNAL);
2837                    final VersionInfo external = findOrCreateVersion(
2838                            StorageManager.UUID_PRIMARY_PHYSICAL);
2839
2840                    internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
2841                    external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);
2842
2843                } else if (tagName.equals("verifier")) {
2844                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2845                    try {
2846                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2847                    } catch (IllegalArgumentException e) {
2848                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2849                                + e.getMessage());
2850                    }
2851                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2852                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2853                    mReadExternalStorageEnforced = "1".equals(enforcement);
2854                } else if (tagName.equals("keyset-settings")) {
2855                    mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
2856                } else if (TAG_VERSION.equals(tagName)) {
2857                    final String volumeUuid = XmlUtils.readStringAttribute(parser,
2858                            ATTR_VOLUME_UUID);
2859                    final VersionInfo ver = findOrCreateVersion(volumeUuid);
2860                    ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
2861                    ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
2862                    ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
2863
2864                } else {
2865                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2866                            + parser.getName());
2867                    XmlUtils.skipCurrentTag(parser);
2868                }
2869            }
2870
2871            str.close();
2872
2873        } catch (XmlPullParserException e) {
2874            mReadMessages.append("Error reading: " + e.toString());
2875            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2876            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2877
2878        } catch (java.io.IOException e) {
2879            mReadMessages.append("Error reading: " + e.toString());
2880            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2881            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2882        }
2883
2884        // If the build is setup to drop runtime permissions
2885        // on update drop the files before loading them.
2886        if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
2887            final VersionInfo internal = getInternalVersion();
2888            if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
2889                for (UserInfo user : users) {
2890                    mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
2891                }
2892            }
2893        }
2894
2895        final int N = mPendingPackages.size();
2896
2897        for (int i = 0; i < N; i++) {
2898            final PendingPackage pp = mPendingPackages.get(i);
2899            Object idObj = getUserIdLPr(pp.sharedId);
2900            if (idObj != null && idObj instanceof SharedUserSetting) {
2901                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
2902                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
2903                        pp.legacyNativeLibraryPathString, pp.primaryCpuAbiString,
2904                        pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags, pp.pkgPrivateFlags,
2905                        null, true /* add */, false /* allowInstall */, pp.parentPackageName,
2906                        pp.childPackageNames);
2907                if (p == null) {
2908                    PackageManagerService.reportSettingsProblem(Log.WARN,
2909                            "Unable to create application package for " + pp.name);
2910                    continue;
2911                }
2912                p.copyFrom(pp);
2913            } else if (idObj != null) {
2914                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2915                        + pp.sharedId + " that is not a shared uid\n";
2916                mReadMessages.append(msg);
2917                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2918            } else {
2919                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2920                        + pp.sharedId + " that is not defined\n";
2921                mReadMessages.append(msg);
2922                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2923            }
2924        }
2925        mPendingPackages.clear();
2926
2927        if (mBackupStoppedPackagesFilename.exists()
2928                || mStoppedPackagesFilename.exists()) {
2929            // Read old file
2930            readStoppedLPw();
2931            mBackupStoppedPackagesFilename.delete();
2932            mStoppedPackagesFilename.delete();
2933            // Migrate to new file format
2934            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
2935        } else {
2936            for (UserInfo user : users) {
2937                readPackageRestrictionsLPr(user.id);
2938            }
2939        }
2940
2941        for (UserInfo user : users) {
2942            mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
2943        }
2944
2945        /*
2946         * Make sure all the updated system packages have their shared users
2947         * associated with them.
2948         */
2949        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
2950        while (disabledIt.hasNext()) {
2951            final PackageSetting disabledPs = disabledIt.next();
2952            final Object id = getUserIdLPr(disabledPs.appId);
2953            if (id != null && id instanceof SharedUserSetting) {
2954                disabledPs.sharedUser = (SharedUserSetting) id;
2955            }
2956        }
2957
2958        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
2959                + mSharedUsers.size() + " shared uids\n");
2960
2961        writeKernelMappingLPr();
2962
2963        return true;
2964    }
2965
2966    void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
2967        // First pull data from any pre-installed apps.
2968        for (PackageSetting ps : mPackages.values()) {
2969            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
2970                    && ps.pkg.preferredActivityFilters != null) {
2971                ArrayList<PackageParser.ActivityIntentInfo> intents
2972                        = ps.pkg.preferredActivityFilters;
2973                for (int i=0; i<intents.size(); i++) {
2974                    PackageParser.ActivityIntentInfo aii = intents.get(i);
2975                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
2976                            ps.name, aii.activity.className), userId);
2977                }
2978            }
2979        }
2980
2981        // Read preferred apps from .../etc/preferred-apps directory.
2982        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
2983        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
2984            return;
2985        }
2986        if (!preferredDir.canRead()) {
2987            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
2988            return;
2989        }
2990
2991        // Iterate over the files in the directory and scan .xml files
2992        for (File f : preferredDir.listFiles()) {
2993            if (!f.getPath().endsWith(".xml")) {
2994                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
2995                continue;
2996            }
2997            if (!f.canRead()) {
2998                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
2999                continue;
3000            }
3001
3002            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
3003            InputStream str = null;
3004            try {
3005                str = new BufferedInputStream(new FileInputStream(f));
3006                XmlPullParser parser = Xml.newPullParser();
3007                parser.setInput(str, null);
3008
3009                int type;
3010                while ((type = parser.next()) != XmlPullParser.START_TAG
3011                        && type != XmlPullParser.END_DOCUMENT) {
3012                    ;
3013                }
3014
3015                if (type != XmlPullParser.START_TAG) {
3016                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
3017                    continue;
3018                }
3019                if (!"preferred-activities".equals(parser.getName())) {
3020                    Slog.w(TAG, "Preferred apps file " + f
3021                            + " does not start with 'preferred-activities'");
3022                    continue;
3023                }
3024                readDefaultPreferredActivitiesLPw(service, parser, userId);
3025            } catch (XmlPullParserException e) {
3026                Slog.w(TAG, "Error reading apps file " + f, e);
3027            } catch (IOException e) {
3028                Slog.w(TAG, "Error reading apps file " + f, e);
3029            } finally {
3030                if (str != null) {
3031                    try {
3032                        str.close();
3033                    } catch (IOException e) {
3034                    }
3035                }
3036            }
3037        }
3038    }
3039
3040    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3041            IntentFilter tmpPa, ComponentName cn, int userId) {
3042        // The initial preferences only specify the target activity
3043        // component and intent-filter, not the set of matches.  So we
3044        // now need to query for the matches to build the correct
3045        // preferred activity entry.
3046        if (PackageManagerService.DEBUG_PREFERRED) {
3047            Log.d(TAG, "Processing preferred:");
3048            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
3049        }
3050        Intent intent = new Intent();
3051        int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE
3052                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
3053        intent.setAction(tmpPa.getAction(0));
3054        for (int i=0; i<tmpPa.countCategories(); i++) {
3055            String cat = tmpPa.getCategory(i);
3056            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
3057                flags |= MATCH_DEFAULT_ONLY;
3058            } else {
3059                intent.addCategory(cat);
3060            }
3061        }
3062
3063        boolean doNonData = true;
3064        boolean hasSchemes = false;
3065
3066        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3067            boolean doScheme = true;
3068            String scheme = tmpPa.getDataScheme(ischeme);
3069            if (scheme != null && !scheme.isEmpty()) {
3070                hasSchemes = true;
3071            }
3072            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
3073                Uri.Builder builder = new Uri.Builder();
3074                builder.scheme(scheme);
3075                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
3076                builder.opaquePart(ssp.getPath());
3077                Intent finalIntent = new Intent(intent);
3078                finalIntent.setData(builder.build());
3079                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3080                        scheme, ssp, null, null, userId);
3081                doScheme = false;
3082            }
3083            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
3084                boolean doAuth = true;
3085                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
3086                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
3087                    Uri.Builder builder = new Uri.Builder();
3088                    builder.scheme(scheme);
3089                    if (auth.getHost() != null) {
3090                        builder.authority(auth.getHost());
3091                    }
3092                    PatternMatcher path = tmpPa.getDataPath(ipath);
3093                    builder.path(path.getPath());
3094                    Intent finalIntent = new Intent(intent);
3095                    finalIntent.setData(builder.build());
3096                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3097                            scheme, null, auth, path, userId);
3098                    doAuth = doScheme = false;
3099                }
3100                if (doAuth) {
3101                    Uri.Builder builder = new Uri.Builder();
3102                    builder.scheme(scheme);
3103                    if (auth.getHost() != null) {
3104                        builder.authority(auth.getHost());
3105                    }
3106                    Intent finalIntent = new Intent(intent);
3107                    finalIntent.setData(builder.build());
3108                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3109                            scheme, null, auth, null, userId);
3110                    doScheme = false;
3111                }
3112            }
3113            if (doScheme) {
3114                Uri.Builder builder = new Uri.Builder();
3115                builder.scheme(scheme);
3116                Intent finalIntent = new Intent(intent);
3117                finalIntent.setData(builder.build());
3118                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3119                        scheme, null, null, null, userId);
3120            }
3121            doNonData = false;
3122        }
3123
3124        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
3125            String mimeType = tmpPa.getDataType(idata);
3126            if (hasSchemes) {
3127                Uri.Builder builder = new Uri.Builder();
3128                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3129                    String scheme = tmpPa.getDataScheme(ischeme);
3130                    if (scheme != null && !scheme.isEmpty()) {
3131                        Intent finalIntent = new Intent(intent);
3132                        builder.scheme(scheme);
3133                        finalIntent.setDataAndType(builder.build(), mimeType);
3134                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3135                                scheme, null, null, null, userId);
3136                    }
3137                }
3138            } else {
3139                Intent finalIntent = new Intent(intent);
3140                finalIntent.setType(mimeType);
3141                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3142                        null, null, null, null, userId);
3143            }
3144            doNonData = false;
3145        }
3146
3147        if (doNonData) {
3148            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
3149                    null, null, null, null, userId);
3150        }
3151    }
3152
3153    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3154            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
3155            IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
3156        flags = service.updateFlagsForResolve(flags, userId, intent);
3157        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
3158                intent.getType(), flags, 0);
3159        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
3160                + " results: " + ri);
3161        int systemMatch = 0;
3162        int thirdPartyMatch = 0;
3163        if (ri != null && ri.size() > 1) {
3164            boolean haveAct = false;
3165            ComponentName haveNonSys = null;
3166            ComponentName[] set = new ComponentName[ri.size()];
3167            for (int i=0; i<ri.size(); i++) {
3168                ActivityInfo ai = ri.get(i).activityInfo;
3169                set[i] = new ComponentName(ai.packageName, ai.name);
3170                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3171                    if (ri.get(i).match >= thirdPartyMatch) {
3172                        // Keep track of the best match we find of all third
3173                        // party apps, for use later to determine if we actually
3174                        // want to set a preferred app for this intent.
3175                        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3176                                + ai.packageName + "/" + ai.name + ": non-system!");
3177                        haveNonSys = set[i];
3178                        break;
3179                    }
3180                } else if (cn.getPackageName().equals(ai.packageName)
3181                        && cn.getClassName().equals(ai.name)) {
3182                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3183                            + ai.packageName + "/" + ai.name + ": default!");
3184                    haveAct = true;
3185                    systemMatch = ri.get(i).match;
3186                } else {
3187                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3188                            + ai.packageName + "/" + ai.name + ": skipped");
3189                }
3190            }
3191            if (haveNonSys != null && thirdPartyMatch < systemMatch) {
3192                // If we have a matching third party app, but its match is not as
3193                // good as the built-in system app, then we don't want to actually
3194                // consider it a match because presumably the built-in app is still
3195                // the thing we want users to see by default.
3196                haveNonSys = null;
3197            }
3198            if (haveAct && haveNonSys == null) {
3199                IntentFilter filter = new IntentFilter();
3200                if (intent.getAction() != null) {
3201                    filter.addAction(intent.getAction());
3202                }
3203                if (intent.getCategories() != null) {
3204                    for (String cat : intent.getCategories()) {
3205                        filter.addCategory(cat);
3206                    }
3207                }
3208                if ((flags & MATCH_DEFAULT_ONLY) != 0) {
3209                    filter.addCategory(Intent.CATEGORY_DEFAULT);
3210                }
3211                if (scheme != null) {
3212                    filter.addDataScheme(scheme);
3213                }
3214                if (ssp != null) {
3215                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
3216                }
3217                if (auth != null) {
3218                    filter.addDataAuthority(auth);
3219                }
3220                if (path != null) {
3221                    filter.addDataPath(path);
3222                }
3223                if (intent.getType() != null) {
3224                    try {
3225                        filter.addDataType(intent.getType());
3226                    } catch (IntentFilter.MalformedMimeTypeException ex) {
3227                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
3228                    }
3229                }
3230                PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
3231                editPreferredActivitiesLPw(userId).addFilter(pa);
3232            } else if (haveNonSys == null) {
3233                StringBuilder sb = new StringBuilder();
3234                sb.append("No component ");
3235                sb.append(cn.flattenToShortString());
3236                sb.append(" found setting preferred ");
3237                sb.append(intent);
3238                sb.append("; possible matches are ");
3239                for (int i=0; i<set.length; i++) {
3240                    if (i > 0) sb.append(", ");
3241                    sb.append(set[i].flattenToShortString());
3242                }
3243                Slog.w(TAG, sb.toString());
3244            } else {
3245                Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
3246                        + haveNonSys.flattenToShortString());
3247            }
3248        } else {
3249            Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
3250                    + cn.flattenToShortString());
3251        }
3252    }
3253
3254    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
3255            XmlPullParser parser, int userId)
3256            throws XmlPullParserException, IOException {
3257        int outerDepth = parser.getDepth();
3258        int type;
3259        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3260                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3261            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3262                continue;
3263            }
3264
3265            String tagName = parser.getName();
3266            if (tagName.equals(TAG_ITEM)) {
3267                PreferredActivity tmpPa = new PreferredActivity(parser);
3268                if (tmpPa.mPref.getParseError() == null) {
3269                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
3270                            userId);
3271                } else {
3272                    PackageManagerService.reportSettingsProblem(Log.WARN,
3273                            "Error in package manager settings: <preferred-activity> "
3274                                    + tmpPa.mPref.getParseError() + " at "
3275                                    + parser.getPositionDescription());
3276                }
3277            } else {
3278                PackageManagerService.reportSettingsProblem(Log.WARN,
3279                        "Unknown element under <preferred-activities>: " + parser.getName());
3280                XmlUtils.skipCurrentTag(parser);
3281            }
3282        }
3283    }
3284
3285    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
3286        String v = parser.getAttributeValue(ns, name);
3287        try {
3288            if (v == null) {
3289                return defValue;
3290            }
3291            return Integer.parseInt(v);
3292        } catch (NumberFormatException e) {
3293            PackageManagerService.reportSettingsProblem(Log.WARN,
3294                    "Error in package manager settings: attribute " + name
3295                            + " has bad integer value " + v + " at "
3296                            + parser.getPositionDescription());
3297        }
3298        return defValue;
3299    }
3300
3301    private void readPermissionsLPw(ArrayMap<String, BasePermission> out, XmlPullParser parser)
3302            throws IOException, XmlPullParserException {
3303        int outerDepth = parser.getDepth();
3304        int type;
3305        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3306                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3307            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3308                continue;
3309            }
3310
3311            final String tagName = parser.getName();
3312            if (tagName.equals(TAG_ITEM)) {
3313                final String name = parser.getAttributeValue(null, ATTR_NAME);
3314                final String sourcePackage = parser.getAttributeValue(null, "package");
3315                final String ptype = parser.getAttributeValue(null, "type");
3316                if (name != null && sourcePackage != null) {
3317                    final boolean dynamic = "dynamic".equals(ptype);
3318                    final BasePermission bp = new BasePermission(name.intern(), sourcePackage,
3319                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
3320                    bp.protectionLevel = readInt(parser, null, "protection",
3321                            PermissionInfo.PROTECTION_NORMAL);
3322                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
3323                    if (dynamic) {
3324                        PermissionInfo pi = new PermissionInfo();
3325                        pi.packageName = sourcePackage.intern();
3326                        pi.name = name.intern();
3327                        pi.icon = readInt(parser, null, "icon", 0);
3328                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
3329                        pi.protectionLevel = bp.protectionLevel;
3330                        bp.pendingInfo = pi;
3331                    }
3332                    out.put(bp.name, bp);
3333                } else {
3334                    PackageManagerService.reportSettingsProblem(Log.WARN,
3335                            "Error in package manager settings: permissions has" + " no name at "
3336                                    + parser.getPositionDescription());
3337                }
3338            } else {
3339                PackageManagerService.reportSettingsProblem(Log.WARN,
3340                        "Unknown element reading permissions: " + parser.getName() + " at "
3341                                + parser.getPositionDescription());
3342            }
3343            XmlUtils.skipCurrentTag(parser);
3344        }
3345    }
3346
3347    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
3348            IOException {
3349        String name = parser.getAttributeValue(null, ATTR_NAME);
3350        String realName = parser.getAttributeValue(null, "realName");
3351        String codePathStr = parser.getAttributeValue(null, "codePath");
3352        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3353
3354        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
3355        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3356
3357        String parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3358
3359        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
3360        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
3361        String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
3362
3363        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
3364            primaryCpuAbiStr = legacyCpuAbiStr;
3365        }
3366
3367        if (resourcePathStr == null) {
3368            resourcePathStr = codePathStr;
3369        }
3370        String version = parser.getAttributeValue(null, "version");
3371        int versionCode = 0;
3372        if (version != null) {
3373            try {
3374                versionCode = Integer.parseInt(version);
3375            } catch (NumberFormatException e) {
3376            }
3377        }
3378
3379        int pkgFlags = 0;
3380        int pkgPrivateFlags = 0;
3381        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3382        final File codePathFile = new File(codePathStr);
3383        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
3384            pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3385        }
3386        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
3387                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
3388                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
3389                parentPackageName, null);
3390        String timeStampStr = parser.getAttributeValue(null, "ft");
3391        if (timeStampStr != null) {
3392            try {
3393                long timeStamp = Long.parseLong(timeStampStr, 16);
3394                ps.setTimeStamp(timeStamp);
3395            } catch (NumberFormatException e) {
3396            }
3397        } else {
3398            timeStampStr = parser.getAttributeValue(null, "ts");
3399            if (timeStampStr != null) {
3400                try {
3401                    long timeStamp = Long.parseLong(timeStampStr);
3402                    ps.setTimeStamp(timeStamp);
3403                } catch (NumberFormatException e) {
3404                }
3405            }
3406        }
3407        timeStampStr = parser.getAttributeValue(null, "it");
3408        if (timeStampStr != null) {
3409            try {
3410                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
3411            } catch (NumberFormatException e) {
3412            }
3413        }
3414        timeStampStr = parser.getAttributeValue(null, "ut");
3415        if (timeStampStr != null) {
3416            try {
3417                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
3418            } catch (NumberFormatException e) {
3419            }
3420        }
3421        String idStr = parser.getAttributeValue(null, "userId");
3422        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
3423        if (ps.appId <= 0) {
3424            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3425            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3426        }
3427
3428        int outerDepth = parser.getDepth();
3429        int type;
3430        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3431                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3432            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3433                continue;
3434            }
3435
3436            if (parser.getName().equals(TAG_PERMISSIONS)) {
3437                readInstallPermissionsLPr(parser, ps.getPermissionsState());
3438            } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) {
3439                String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3440                if (ps.childPackageNames == null) {
3441                    ps.childPackageNames = new ArrayList<>();
3442                }
3443                ps.childPackageNames.add(childPackageName);
3444            } else {
3445                PackageManagerService.reportSettingsProblem(Log.WARN,
3446                        "Unknown element under <updated-package>: " + parser.getName());
3447                XmlUtils.skipCurrentTag(parser);
3448            }
3449        }
3450
3451        mDisabledSysPackages.put(name, ps);
3452    }
3453
3454    private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27;
3455    private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
3456    private static int PRE_M_APP_INFO_FLAG_FORWARD_LOCK = 1<<29;
3457    private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
3458
3459    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
3460        String name = null;
3461        String realName = null;
3462        String idStr = null;
3463        String sharedIdStr = null;
3464        String codePathStr = null;
3465        String resourcePathStr = null;
3466        String legacyCpuAbiString = null;
3467        String legacyNativeLibraryPathStr = null;
3468        String primaryCpuAbiString = null;
3469        String secondaryCpuAbiString = null;
3470        String cpuAbiOverrideString = null;
3471        String systemStr = null;
3472        String installerPackageName = null;
3473        String volumeUuid = null;
3474        String uidError = null;
3475        int pkgFlags = 0;
3476        int pkgPrivateFlags = 0;
3477        long timeStamp = 0;
3478        long firstInstallTime = 0;
3479        long lastUpdateTime = 0;
3480        PackageSettingBase packageSetting = null;
3481        String version = null;
3482        int versionCode = 0;
3483        String parentPackageName;
3484        try {
3485            name = parser.getAttributeValue(null, ATTR_NAME);
3486            realName = parser.getAttributeValue(null, "realName");
3487            idStr = parser.getAttributeValue(null, "userId");
3488            uidError = parser.getAttributeValue(null, "uidError");
3489            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3490            codePathStr = parser.getAttributeValue(null, "codePath");
3491            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3492
3493            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
3494
3495            parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3496
3497            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3498            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
3499            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
3500            cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
3501
3502            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
3503                primaryCpuAbiString = legacyCpuAbiString;
3504            }
3505
3506            version = parser.getAttributeValue(null, "version");
3507            if (version != null) {
3508                try {
3509                    versionCode = Integer.parseInt(version);
3510                } catch (NumberFormatException e) {
3511                }
3512            }
3513            installerPackageName = parser.getAttributeValue(null, "installer");
3514            volumeUuid = parser.getAttributeValue(null, "volumeUuid");
3515
3516            systemStr = parser.getAttributeValue(null, "publicFlags");
3517            if (systemStr != null) {
3518                try {
3519                    pkgFlags = Integer.parseInt(systemStr);
3520                } catch (NumberFormatException e) {
3521                }
3522                systemStr = parser.getAttributeValue(null, "privateFlags");
3523                if (systemStr != null) {
3524                    try {
3525                        pkgPrivateFlags = Integer.parseInt(systemStr);
3526                    } catch (NumberFormatException e) {
3527                    }
3528                }
3529            } else {
3530                // Pre-M -- both public and private flags were stored in one "flags" field.
3531                systemStr = parser.getAttributeValue(null, "flags");
3532                if (systemStr != null) {
3533                    try {
3534                        pkgFlags = Integer.parseInt(systemStr);
3535                    } catch (NumberFormatException e) {
3536                    }
3537                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) {
3538                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
3539                    }
3540                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) {
3541                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
3542                    }
3543                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_FORWARD_LOCK) != 0) {
3544                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK;
3545                    }
3546                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) {
3547                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3548                    }
3549                    pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN
3550                            | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE
3551                            | PRE_M_APP_INFO_FLAG_FORWARD_LOCK
3552                            | PRE_M_APP_INFO_FLAG_PRIVILEGED);
3553                } else {
3554                    // For backward compatibility
3555                    systemStr = parser.getAttributeValue(null, "system");
3556                    if (systemStr != null) {
3557                        pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
3558                                : 0;
3559                    } else {
3560                        // Old settings that don't specify system... just treat
3561                        // them as system, good enough.
3562                        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3563                    }
3564                }
3565            }
3566            String timeStampStr = parser.getAttributeValue(null, "ft");
3567            if (timeStampStr != null) {
3568                try {
3569                    timeStamp = Long.parseLong(timeStampStr, 16);
3570                } catch (NumberFormatException e) {
3571                }
3572            } else {
3573                timeStampStr = parser.getAttributeValue(null, "ts");
3574                if (timeStampStr != null) {
3575                    try {
3576                        timeStamp = Long.parseLong(timeStampStr);
3577                    } catch (NumberFormatException e) {
3578                    }
3579                }
3580            }
3581            timeStampStr = parser.getAttributeValue(null, "it");
3582            if (timeStampStr != null) {
3583                try {
3584                    firstInstallTime = Long.parseLong(timeStampStr, 16);
3585                } catch (NumberFormatException e) {
3586                }
3587            }
3588            timeStampStr = parser.getAttributeValue(null, "ut");
3589            if (timeStampStr != null) {
3590                try {
3591                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
3592                } catch (NumberFormatException e) {
3593                }
3594            }
3595            if (PackageManagerService.DEBUG_SETTINGS)
3596                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
3597                        + " sharedUserId=" + sharedIdStr);
3598            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3599            if (resourcePathStr == null) {
3600                resourcePathStr = codePathStr;
3601            }
3602            if (realName != null) {
3603                realName = realName.intern();
3604            }
3605            if (name == null) {
3606                PackageManagerService.reportSettingsProblem(Log.WARN,
3607                        "Error in package manager settings: <package> has no name at "
3608                                + parser.getPositionDescription());
3609            } else if (codePathStr == null) {
3610                PackageManagerService.reportSettingsProblem(Log.WARN,
3611                        "Error in package manager settings: <package> has no codePath at "
3612                                + parser.getPositionDescription());
3613            } else if (userId > 0) {
3614                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
3615                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
3616                        secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
3617                        pkgPrivateFlags, parentPackageName, null);
3618                if (PackageManagerService.DEBUG_SETTINGS)
3619                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
3620                            + userId + " pkg=" + packageSetting);
3621                if (packageSetting == null) {
3622                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
3623                            + userId + " while parsing settings at "
3624                            + parser.getPositionDescription());
3625                } else {
3626                    packageSetting.setTimeStamp(timeStamp);
3627                    packageSetting.firstInstallTime = firstInstallTime;
3628                    packageSetting.lastUpdateTime = lastUpdateTime;
3629                }
3630            } else if (sharedIdStr != null) {
3631                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3632                if (userId > 0) {
3633                    packageSetting = new PendingPackage(name.intern(), realName, new File(
3634                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
3635                            primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
3636                            userId, versionCode, pkgFlags, pkgPrivateFlags, parentPackageName,
3637                            null);
3638                    packageSetting.setTimeStamp(timeStamp);
3639                    packageSetting.firstInstallTime = firstInstallTime;
3640                    packageSetting.lastUpdateTime = lastUpdateTime;
3641                    mPendingPackages.add((PendingPackage) packageSetting);
3642                    if (PackageManagerService.DEBUG_SETTINGS)
3643                        Log.i(PackageManagerService.TAG, "Reading package " + name
3644                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
3645                } else {
3646                    PackageManagerService.reportSettingsProblem(Log.WARN,
3647                            "Error in package manager settings: package " + name
3648                                    + " has bad sharedId " + sharedIdStr + " at "
3649                                    + parser.getPositionDescription());
3650                }
3651            } else {
3652                PackageManagerService.reportSettingsProblem(Log.WARN,
3653                        "Error in package manager settings: package " + name + " has bad userId "
3654                                + idStr + " at " + parser.getPositionDescription());
3655            }
3656        } catch (NumberFormatException e) {
3657            PackageManagerService.reportSettingsProblem(Log.WARN,
3658                    "Error in package manager settings: package " + name + " has bad userId "
3659                            + idStr + " at " + parser.getPositionDescription());
3660        }
3661        if (packageSetting != null) {
3662            packageSetting.uidError = "true".equals(uidError);
3663            packageSetting.installerPackageName = installerPackageName;
3664            packageSetting.volumeUuid = volumeUuid;
3665            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
3666            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
3667            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
3668            // Handle legacy string here for single-user mode
3669            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
3670            if (enabledStr != null) {
3671                try {
3672                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
3673                } catch (NumberFormatException e) {
3674                    if (enabledStr.equalsIgnoreCase("true")) {
3675                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
3676                    } else if (enabledStr.equalsIgnoreCase("false")) {
3677                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
3678                    } else if (enabledStr.equalsIgnoreCase("default")) {
3679                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3680                    } else {
3681                        PackageManagerService.reportSettingsProblem(Log.WARN,
3682                                "Error in package manager settings: package " + name
3683                                        + " has bad enabled value: " + idStr + " at "
3684                                        + parser.getPositionDescription());
3685                    }
3686                }
3687            } else {
3688                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3689            }
3690
3691            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
3692            if (installStatusStr != null) {
3693                if (installStatusStr.equalsIgnoreCase("false")) {
3694                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
3695                } else {
3696                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
3697                }
3698            }
3699
3700            int outerDepth = parser.getDepth();
3701            int type;
3702            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3703                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3704                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3705                    continue;
3706                }
3707
3708                String tagName = parser.getName();
3709                // Legacy
3710                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
3711                    readDisabledComponentsLPw(packageSetting, parser, 0);
3712                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
3713                    readEnabledComponentsLPw(packageSetting, parser, 0);
3714                } else if (tagName.equals("sigs")) {
3715                    packageSetting.signatures.readXml(parser, mPastSignatures);
3716                } else if (tagName.equals(TAG_PERMISSIONS)) {
3717                    readInstallPermissionsLPr(parser,
3718                            packageSetting.getPermissionsState());
3719                    packageSetting.installPermissionsFixed = true;
3720                } else if (tagName.equals("proper-signing-keyset")) {
3721                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3722                    Integer refCt = mKeySetRefs.get(id);
3723                    if (refCt != null) {
3724                        mKeySetRefs.put(id, refCt + 1);
3725                    } else {
3726                        mKeySetRefs.put(id, 1);
3727                    }
3728                    packageSetting.keySetData.setProperSigningKeySet(id);
3729                } else if (tagName.equals("signing-keyset")) {
3730                    // from v1 of keysetmanagerservice - no longer used
3731                } else if (tagName.equals("upgrade-keyset")) {
3732                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3733                    packageSetting.keySetData.addUpgradeKeySetById(id);
3734                } else if (tagName.equals("defined-keyset")) {
3735                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3736                    String alias = parser.getAttributeValue(null, "alias");
3737                    Integer refCt = mKeySetRefs.get(id);
3738                    if (refCt != null) {
3739                        mKeySetRefs.put(id, refCt + 1);
3740                    } else {
3741                        mKeySetRefs.put(id, 1);
3742                    }
3743                    packageSetting.keySetData.addDefinedKeySet(id, alias);
3744                } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
3745                    readDomainVerificationLPw(parser, packageSetting);
3746                } else if (tagName.equals(TAG_CHILD_PACKAGE)) {
3747                    String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3748                    if (packageSetting.childPackageNames == null) {
3749                        packageSetting.childPackageNames = new ArrayList<>();
3750                    }
3751                    packageSetting.childPackageNames.add(childPackageName);
3752                } else {
3753                    PackageManagerService.reportSettingsProblem(Log.WARN,
3754                            "Unknown element under <package>: " + parser.getName());
3755                    XmlUtils.skipCurrentTag(parser);
3756                }
3757            }
3758        } else {
3759            XmlUtils.skipCurrentTag(parser);
3760        }
3761    }
3762
3763    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3764            int userId) throws IOException, XmlPullParserException {
3765        int outerDepth = parser.getDepth();
3766        int type;
3767        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3768                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3769            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3770                continue;
3771            }
3772
3773            String tagName = parser.getName();
3774            if (tagName.equals(TAG_ITEM)) {
3775                String name = parser.getAttributeValue(null, ATTR_NAME);
3776                if (name != null) {
3777                    packageSetting.addDisabledComponent(name.intern(), userId);
3778                } else {
3779                    PackageManagerService.reportSettingsProblem(Log.WARN,
3780                            "Error in package manager settings: <disabled-components> has"
3781                                    + " no name at " + parser.getPositionDescription());
3782                }
3783            } else {
3784                PackageManagerService.reportSettingsProblem(Log.WARN,
3785                        "Unknown element under <disabled-components>: " + parser.getName());
3786            }
3787            XmlUtils.skipCurrentTag(parser);
3788        }
3789    }
3790
3791    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3792            int userId) throws IOException, XmlPullParserException {
3793        int outerDepth = parser.getDepth();
3794        int type;
3795        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3796                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3797            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3798                continue;
3799            }
3800
3801            String tagName = parser.getName();
3802            if (tagName.equals(TAG_ITEM)) {
3803                String name = parser.getAttributeValue(null, ATTR_NAME);
3804                if (name != null) {
3805                    packageSetting.addEnabledComponent(name.intern(), userId);
3806                } else {
3807                    PackageManagerService.reportSettingsProblem(Log.WARN,
3808                            "Error in package manager settings: <enabled-components> has"
3809                                    + " no name at " + parser.getPositionDescription());
3810                }
3811            } else {
3812                PackageManagerService.reportSettingsProblem(Log.WARN,
3813                        "Unknown element under <enabled-components>: " + parser.getName());
3814            }
3815            XmlUtils.skipCurrentTag(parser);
3816        }
3817    }
3818
3819    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
3820        String name = null;
3821        String idStr = null;
3822        int pkgFlags = 0;
3823        int pkgPrivateFlags = 0;
3824        SharedUserSetting su = null;
3825        try {
3826            name = parser.getAttributeValue(null, ATTR_NAME);
3827            idStr = parser.getAttributeValue(null, "userId");
3828            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3829            if ("true".equals(parser.getAttributeValue(null, "system"))) {
3830                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3831            }
3832            if (name == null) {
3833                PackageManagerService.reportSettingsProblem(Log.WARN,
3834                        "Error in package manager settings: <shared-user> has no name at "
3835                                + parser.getPositionDescription());
3836            } else if (userId == 0) {
3837                PackageManagerService.reportSettingsProblem(Log.WARN,
3838                        "Error in package manager settings: shared-user " + name
3839                                + " has bad userId " + idStr + " at "
3840                                + parser.getPositionDescription());
3841            } else {
3842                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
3843                        == null) {
3844                    PackageManagerService
3845                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
3846                                    + parser.getPositionDescription());
3847                }
3848            }
3849        } catch (NumberFormatException e) {
3850            PackageManagerService.reportSettingsProblem(Log.WARN,
3851                    "Error in package manager settings: package " + name + " has bad userId "
3852                            + idStr + " at " + parser.getPositionDescription());
3853        }
3854
3855        if (su != null) {
3856            int outerDepth = parser.getDepth();
3857            int type;
3858            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3859                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3860                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3861                    continue;
3862                }
3863
3864                String tagName = parser.getName();
3865                if (tagName.equals("sigs")) {
3866                    su.signatures.readXml(parser, mPastSignatures);
3867                } else if (tagName.equals("perms")) {
3868                    readInstallPermissionsLPr(parser, su.getPermissionsState());
3869                } else {
3870                    PackageManagerService.reportSettingsProblem(Log.WARN,
3871                            "Unknown element under <shared-user>: " + parser.getName());
3872                    XmlUtils.skipCurrentTag(parser);
3873                }
3874            }
3875        } else {
3876            XmlUtils.skipCurrentTag(parser);
3877        }
3878    }
3879
3880    void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
3881            int userHandle) {
3882        String[] volumeUuids;
3883        String[] names;
3884        int[] appIds;
3885        String[] seinfos;
3886        int[] targetSdkVersions;
3887        int packagesCount;
3888        synchronized (mPackages) {
3889            Collection<PackageSetting> packages = mPackages.values();
3890            packagesCount = packages.size();
3891            volumeUuids = new String[packagesCount];
3892            names = new String[packagesCount];
3893            appIds = new int[packagesCount];
3894            seinfos = new String[packagesCount];
3895            targetSdkVersions = new int[packagesCount];
3896            Iterator<PackageSetting> packagesIterator = packages.iterator();
3897            for (int i = 0; i < packagesCount; i++) {
3898                PackageSetting ps = packagesIterator.next();
3899                if (ps.pkg == null || ps.pkg.applicationInfo == null) {
3900                    continue;
3901                }
3902                // Only system apps are initially installed.
3903                ps.setInstalled(ps.isSystem(), userHandle);
3904                // Need to create a data directory for all apps under this user. Accumulate all
3905                // required args and call the installer after mPackages lock has been released
3906                volumeUuids[i] = ps.volumeUuid;
3907                names[i] = ps.name;
3908                appIds[i] = ps.appId;
3909                seinfos[i] = ps.pkg.applicationInfo.seinfo;
3910                targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
3911            }
3912        }
3913        for (int i = 0; i < packagesCount; i++) {
3914            if (names[i] == null) {
3915                continue;
3916            }
3917            // TODO: triage flags!
3918            final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
3919            try {
3920                installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
3921                        seinfos[i], targetSdkVersions[i]);
3922            } catch (InstallerException e) {
3923                Slog.w(TAG, "Failed to prepare app data", e);
3924            }
3925        }
3926        synchronized (mPackages) {
3927            applyDefaultPreferredAppsLPw(service, userHandle);
3928            writePackageRestrictionsLPr(userHandle);
3929            writePackageListLPr(userHandle);
3930        }
3931    }
3932
3933    void removeUserLPw(int userId) {
3934        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
3935        for (Entry<String, PackageSetting> entry : entries) {
3936            entry.getValue().removeUser(userId);
3937        }
3938        mPreferredActivities.remove(userId);
3939        File file = getUserPackagesStateFile(userId);
3940        file.delete();
3941        file = getUserPackagesStateBackupFile(userId);
3942        file.delete();
3943        removeCrossProfileIntentFiltersLPw(userId);
3944
3945        mRuntimePermissionsPersistence.onUserRemoved(userId);
3946
3947        writePackageListLPr();
3948    }
3949
3950    void removeCrossProfileIntentFiltersLPw(int userId) {
3951        synchronized (mCrossProfileIntentResolvers) {
3952            // userId is the source user
3953            if (mCrossProfileIntentResolvers.get(userId) != null) {
3954                mCrossProfileIntentResolvers.remove(userId);
3955                writePackageRestrictionsLPr(userId);
3956            }
3957            // userId is the target user
3958            int count = mCrossProfileIntentResolvers.size();
3959            for (int i = 0; i < count; i++) {
3960                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
3961                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
3962                boolean needsWriting = false;
3963                ArraySet<CrossProfileIntentFilter> cpifs =
3964                        new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
3965                for (CrossProfileIntentFilter cpif : cpifs) {
3966                    if (cpif.getTargetUserId() == userId) {
3967                        needsWriting = true;
3968                        cpir.removeFilter(cpif);
3969                    }
3970                }
3971                if (needsWriting) {
3972                    writePackageRestrictionsLPr(sourceUserId);
3973                }
3974            }
3975        }
3976    }
3977
3978    // This should be called (at least) whenever an application is removed
3979    private void setFirstAvailableUid(int uid) {
3980        if (uid > mFirstAvailableUid) {
3981            mFirstAvailableUid = uid;
3982        }
3983    }
3984
3985    // Returns -1 if we could not find an available UserId to assign
3986    private int newUserIdLPw(Object obj) {
3987        // Let's be stupidly inefficient for now...
3988        final int N = mUserIds.size();
3989        for (int i = mFirstAvailableUid; i < N; i++) {
3990            if (mUserIds.get(i) == null) {
3991                mUserIds.set(i, obj);
3992                return Process.FIRST_APPLICATION_UID + i;
3993            }
3994        }
3995
3996        // None left?
3997        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
3998            return -1;
3999        }
4000
4001        mUserIds.add(obj);
4002        return Process.FIRST_APPLICATION_UID + N;
4003    }
4004
4005    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
4006        if (mVerifierDeviceIdentity == null) {
4007            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
4008
4009            writeLPr();
4010        }
4011
4012        return mVerifierDeviceIdentity;
4013    }
4014
4015    public boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
4016            String childPackageName) {
4017        final int packageCount = mDisabledSysPackages.size();
4018        for (int i = 0; i < packageCount; i++) {
4019            PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
4020            if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
4021                continue;
4022            }
4023            if (disabledPs.name.equals(parentPackageName)) {
4024                continue;
4025            }
4026            final int childCount = disabledPs.childPackageNames.size();
4027            for (int j = 0; j < childCount; j++) {
4028                String currChildPackageName = disabledPs.childPackageNames.get(j);
4029                if (currChildPackageName.equals(childPackageName)) {
4030                    return true;
4031                }
4032            }
4033        }
4034        return false;
4035    }
4036
4037    public PackageSetting getDisabledSystemPkgLPr(String name) {
4038        PackageSetting ps = mDisabledSysPackages.get(name);
4039        return ps;
4040    }
4041
4042    private String compToString(ArraySet<String> cmp) {
4043        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
4044    }
4045
4046    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
4047        final PackageSetting ps = mPackages.get(componentInfo.packageName);
4048        if (ps == null) return false;
4049
4050        final PackageUserState userState = ps.readUserState(userId);
4051        return userState.isMatch(componentInfo, flags);
4052    }
4053
4054    String getInstallerPackageNameLPr(String packageName) {
4055        final PackageSetting pkg = mPackages.get(packageName);
4056        if (pkg == null) {
4057            throw new IllegalArgumentException("Unknown package: " + packageName);
4058        }
4059        return pkg.installerPackageName;
4060    }
4061
4062    int getApplicationEnabledSettingLPr(String packageName, int userId) {
4063        final PackageSetting pkg = mPackages.get(packageName);
4064        if (pkg == null) {
4065            throw new IllegalArgumentException("Unknown package: " + packageName);
4066        }
4067        return pkg.getEnabled(userId);
4068    }
4069
4070    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
4071        final String packageName = componentName.getPackageName();
4072        final PackageSetting pkg = mPackages.get(packageName);
4073        if (pkg == null) {
4074            throw new IllegalArgumentException("Unknown component: " + componentName);
4075        }
4076        final String classNameStr = componentName.getClassName();
4077        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
4078    }
4079
4080    boolean setPackageStoppedStateLPw(PackageManagerService yucky, String packageName,
4081            boolean stopped, boolean allowedByPermission, int uid, int userId) {
4082        int appId = UserHandle.getAppId(uid);
4083        final PackageSetting pkgSetting = mPackages.get(packageName);
4084        if (pkgSetting == null) {
4085            throw new IllegalArgumentException("Unknown package: " + packageName);
4086        }
4087        if (!allowedByPermission && (appId != pkgSetting.appId)) {
4088            throw new SecurityException(
4089                    "Permission Denial: attempt to change stopped state from pid="
4090                    + Binder.getCallingPid()
4091                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
4092        }
4093        if (DEBUG_STOPPED) {
4094            if (stopped) {
4095                RuntimeException e = new RuntimeException("here");
4096                e.fillInStackTrace();
4097                Slog.i(TAG, "Stopping package " + packageName, e);
4098            }
4099        }
4100        if (pkgSetting.getStopped(userId) != stopped) {
4101            pkgSetting.setStopped(stopped, userId);
4102            // pkgSetting.pkg.mSetStopped = stopped;
4103            if (pkgSetting.getNotLaunched(userId)) {
4104                if (pkgSetting.installerPackageName != null) {
4105                    yucky.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
4106                            pkgSetting.name, null, 0,
4107                            pkgSetting.installerPackageName, null, new int[] {userId});
4108                }
4109                pkgSetting.setNotLaunched(false, userId);
4110            }
4111            return true;
4112        }
4113        return false;
4114    }
4115
4116    List<UserInfo> getAllUsers() {
4117        long id = Binder.clearCallingIdentity();
4118        try {
4119            return UserManagerService.getInstance().getUsers(false);
4120        } catch (NullPointerException npe) {
4121            // packagemanager not yet initialized
4122        } finally {
4123            Binder.restoreCallingIdentity(id);
4124        }
4125        return null;
4126    }
4127
4128    /**
4129     * Return all {@link PackageSetting} that are actively installed on the
4130     * given {@link VolumeInfo#fsUuid}.
4131     */
4132    List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
4133        ArrayList<PackageSetting> res = new ArrayList<>();
4134        for (int i = 0; i < mPackages.size(); i++) {
4135            final PackageSetting setting = mPackages.valueAt(i);
4136            if (Objects.equals(volumeUuid, setting.volumeUuid)) {
4137                res.add(setting);
4138            }
4139        }
4140        return res;
4141    }
4142
4143    static void printFlags(PrintWriter pw, int val, Object[] spec) {
4144        pw.print("[ ");
4145        for (int i=0; i<spec.length; i+=2) {
4146            int mask = (Integer)spec[i];
4147            if ((val & mask) != 0) {
4148                pw.print(spec[i+1]);
4149                pw.print(" ");
4150            }
4151        }
4152        pw.print("]");
4153    }
4154
4155    static final Object[] FLAG_DUMP_SPEC = new Object[] {
4156        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4157        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4158        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4159        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4160        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4161        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4162        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4163        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4164        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4165        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4166        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4167        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4168        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4169        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4170        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4171    };
4172
4173    static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4174        ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN",
4175        ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4176        ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK",
4177        ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4178        ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
4179        ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
4180        ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
4181        ApplicationInfo.PRIVATE_FLAG_AUTOPLAY, "AUTOPLAY",
4182        ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
4183        ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL",
4184        ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
4185        ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES, "RESIZEABLE_ACTIVITIES",
4186        ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
4187    };
4188
4189    void dumpVersionLPr(IndentingPrintWriter pw) {
4190        pw.increaseIndent();
4191        for (int i= 0; i < mVersion.size(); i++) {
4192            final String volumeUuid = mVersion.keyAt(i);
4193            final VersionInfo ver = mVersion.valueAt(i);
4194            if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4195                pw.println("Internal:");
4196            } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4197                pw.println("External:");
4198            } else {
4199                pw.println("UUID " + volumeUuid + ":");
4200            }
4201            pw.increaseIndent();
4202            pw.printPair("sdkVersion", ver.sdkVersion);
4203            pw.printPair("databaseVersion", ver.databaseVersion);
4204            pw.println();
4205            pw.printPair("fingerprint", ver.fingerprint);
4206            pw.println();
4207            pw.decreaseIndent();
4208        }
4209        pw.decreaseIndent();
4210    }
4211
4212    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4213            ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4214            Date date, List<UserInfo> users, boolean dumpAll) {
4215        if (checkinTag != null) {
4216            pw.print(checkinTag);
4217            pw.print(",");
4218            pw.print(ps.realName != null ? ps.realName : ps.name);
4219            pw.print(",");
4220            pw.print(ps.appId);
4221            pw.print(",");
4222            pw.print(ps.versionCode);
4223            pw.print(",");
4224            pw.print(ps.firstInstallTime);
4225            pw.print(",");
4226            pw.print(ps.lastUpdateTime);
4227            pw.print(",");
4228            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4229            pw.println();
4230            if (ps.pkg != null) {
4231                pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4232                pw.print("base,");
4233                pw.println(ps.pkg.baseRevisionCode);
4234                if (ps.pkg.splitNames != null) {
4235                    for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4236                        pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4237                        pw.print(ps.pkg.splitNames[i]); pw.print(",");
4238                        pw.println(ps.pkg.splitRevisionCodes[i]);
4239                    }
4240                }
4241            }
4242            for (UserInfo user : users) {
4243                pw.print(checkinTag);
4244                pw.print("-");
4245                pw.print("usr");
4246                pw.print(",");
4247                pw.print(user.id);
4248                pw.print(",");
4249                pw.print(ps.getInstalled(user.id) ? "I" : "i");
4250                pw.print(ps.getHidden(user.id) ? "B" : "b");
4251                pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4252                pw.print(ps.getStopped(user.id) ? "S" : "s");
4253                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4254                pw.print(",");
4255                pw.print(ps.getEnabled(user.id));
4256                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4257                pw.print(",");
4258                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4259                pw.println();
4260            }
4261            return;
4262        }
4263
4264        pw.print(prefix); pw.print("Package [");
4265            pw.print(ps.realName != null ? ps.realName : ps.name);
4266            pw.print("] (");
4267            pw.print(Integer.toHexString(System.identityHashCode(ps)));
4268            pw.println("):");
4269
4270        if (ps.frozen) {
4271            pw.print(prefix); pw.println("  FROZEN!");
4272        }
4273
4274        if (ps.realName != null) {
4275            pw.print(prefix); pw.print("  compat name=");
4276            pw.println(ps.name);
4277        }
4278
4279        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4280
4281        if (ps.sharedUser != null) {
4282            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4283        }
4284        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4285        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4286        if (permissionNames == null) {
4287            pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4288            pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4289            pw.println(ps.legacyNativeLibraryPathString);
4290            pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4291            pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4292        }
4293        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4294        if (ps.pkg != null) {
4295            pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion);
4296            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4297        }
4298        pw.println();
4299        if (ps.pkg != null) {
4300            if (ps.pkg.parentPackage != null) {
4301                PackageParser.Package parentPkg = ps.pkg.parentPackage;
4302                PackageSetting pps = mPackages.get(parentPkg.packageName);
4303                if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
4304                    pps = mDisabledSysPackages.get(parentPkg.packageName);
4305                }
4306                if (pps != null) {
4307                    pw.print(prefix); pw.print("  parentPackage=");
4308                    pw.println(pps.realName != null ? pps.realName : pps.name);
4309                }
4310            } else if (ps.pkg.childPackages != null) {
4311                pw.print(prefix); pw.print("  childPackages=[");
4312                final int childCount = ps.pkg.childPackages.size();
4313                for (int i = 0; i < childCount; i++) {
4314                    PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
4315                    PackageSetting cps = mPackages.get(childPkg.packageName);
4316                    if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
4317                        cps = mDisabledSysPackages.get(childPkg.packageName);
4318                    }
4319                    if (cps != null) {
4320                        if (i > 0) {
4321                            pw.print(", ");
4322                        }
4323                        pw.print(cps.realName != null ? cps.realName : cps.name);
4324                    }
4325                }
4326                pw.println("]");
4327            }
4328            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4329            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4330            final int apkSigningVersion = PackageParser.getApkSigningVersion(ps.pkg);
4331            if (apkSigningVersion != PackageParser.APK_SIGNING_UNKNOWN) {
4332                pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
4333            }
4334            pw.print(prefix); pw.print("  applicationInfo=");
4335                pw.println(ps.pkg.applicationInfo.toString());
4336            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4337                    FLAG_DUMP_SPEC); pw.println();
4338            if (ps.pkg.applicationInfo.privateFlags != 0) {
4339                pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4340                        ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4341            }
4342            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4343            pw.print(prefix); pw.print("  supportsScreens=[");
4344            boolean first = true;
4345            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4346                if (!first)
4347                    pw.print(", ");
4348                first = false;
4349                pw.print("small");
4350            }
4351            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4352                if (!first)
4353                    pw.print(", ");
4354                first = false;
4355                pw.print("medium");
4356            }
4357            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4358                if (!first)
4359                    pw.print(", ");
4360                first = false;
4361                pw.print("large");
4362            }
4363            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4364                if (!first)
4365                    pw.print(", ");
4366                first = false;
4367                pw.print("xlarge");
4368            }
4369            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4370                if (!first)
4371                    pw.print(", ");
4372                first = false;
4373                pw.print("resizeable");
4374            }
4375            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4376                if (!first)
4377                    pw.print(", ");
4378                first = false;
4379                pw.print("anyDensity");
4380            }
4381            pw.println("]");
4382            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4383                pw.print(prefix); pw.println("  libraries:");
4384                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
4385                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
4386                }
4387            }
4388            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4389                pw.print(prefix); pw.println("  usesLibraries:");
4390                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4391                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4392                }
4393            }
4394            if (ps.pkg.usesOptionalLibraries != null
4395                    && ps.pkg.usesOptionalLibraries.size() > 0) {
4396                pw.print(prefix); pw.println("  usesOptionalLibraries:");
4397                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4398                    pw.print(prefix); pw.print("    ");
4399                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
4400                }
4401            }
4402            if (ps.pkg.usesLibraryFiles != null
4403                    && ps.pkg.usesLibraryFiles.length > 0) {
4404                pw.print(prefix); pw.println("  usesLibraryFiles:");
4405                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4406                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4407                }
4408            }
4409        }
4410        pw.print(prefix); pw.print("  timeStamp=");
4411            date.setTime(ps.timeStamp);
4412            pw.println(sdf.format(date));
4413        pw.print(prefix); pw.print("  firstInstallTime=");
4414            date.setTime(ps.firstInstallTime);
4415            pw.println(sdf.format(date));
4416        pw.print(prefix); pw.print("  lastUpdateTime=");
4417            date.setTime(ps.lastUpdateTime);
4418            pw.println(sdf.format(date));
4419        if (ps.installerPackageName != null) {
4420            pw.print(prefix); pw.print("  installerPackageName=");
4421                    pw.println(ps.installerPackageName);
4422        }
4423        if (ps.volumeUuid != null) {
4424            pw.print(prefix); pw.print("  volumeUuid=");
4425                    pw.println(ps.volumeUuid);
4426        }
4427        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4428        pw.print(prefix); pw.print("  installPermissionsFixed=");
4429                pw.print(ps.installPermissionsFixed);
4430                pw.print(" installStatus="); pw.println(ps.installStatus);
4431        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4432                pw.println();
4433
4434        if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4435            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4436            pw.print(prefix); pw.println("  declared permissions:");
4437            for (int i=0; i<perms.size(); i++) {
4438                PackageParser.Permission perm = perms.get(i);
4439                if (permissionNames != null
4440                        && !permissionNames.contains(perm.info.name)) {
4441                    continue;
4442                }
4443                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4444                pw.print(": prot=");
4445                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4446                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4447                    pw.print(", COSTS_MONEY");
4448                }
4449                if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4450                    pw.print(", HIDDEN");
4451                }
4452                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4453                    pw.print(", INSTALLED");
4454                }
4455                pw.println();
4456            }
4457        }
4458
4459        if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null
4460                && ps.pkg.requestedPermissions.size() > 0) {
4461            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4462            pw.print(prefix); pw.println("  requested permissions:");
4463            for (int i=0; i<perms.size(); i++) {
4464                String perm = perms.get(i);
4465                if (permissionNames != null
4466                        && !permissionNames.contains(perm)) {
4467                    continue;
4468                }
4469                pw.print(prefix); pw.print("    "); pw.println(perm);
4470            }
4471        }
4472
4473        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4474            PermissionsState permissionsState = ps.getPermissionsState();
4475            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4476        }
4477
4478        for (UserInfo user : users) {
4479            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4480            pw.print(" installed=");
4481            pw.print(ps.getInstalled(user.id));
4482            pw.print(" hidden=");
4483            pw.print(ps.getHidden(user.id));
4484            pw.print(" suspended=");
4485            pw.print(ps.getSuspended(user.id));
4486            pw.print(" stopped=");
4487            pw.print(ps.getStopped(user.id));
4488            pw.print(" notLaunched=");
4489            pw.print(ps.getNotLaunched(user.id));
4490            pw.print(" enabled=");
4491            pw.println(ps.getEnabled(user.id));
4492            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4493            if (lastDisabledAppCaller != null) {
4494                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4495                        pw.println(lastDisabledAppCaller);
4496            }
4497
4498            if (ps.sharedUser == null) {
4499                PermissionsState permissionsState = ps.getPermissionsState();
4500                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4501                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4502                        .getRuntimePermissionStates(user.id), dumpAll);
4503            }
4504
4505            if (permissionNames == null) {
4506                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4507                if (cmp != null && cmp.size() > 0) {
4508                    pw.print(prefix); pw.println("    disabledComponents:");
4509                    for (String s : cmp) {
4510                        pw.print(prefix); pw.print("      "); pw.println(s);
4511                    }
4512                }
4513                cmp = ps.getEnabledComponents(user.id);
4514                if (cmp != null && cmp.size() > 0) {
4515                    pw.print(prefix); pw.println("    enabledComponents:");
4516                    for (String s : cmp) {
4517                        pw.print(prefix); pw.print("      "); pw.println(s);
4518                    }
4519                }
4520            }
4521        }
4522    }
4523
4524    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4525            DumpState dumpState, boolean checkin) {
4526        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4527        final Date date = new Date();
4528        boolean printedSomething = false;
4529        List<UserInfo> users = getAllUsers();
4530        for (final PackageSetting ps : mPackages.values()) {
4531            if (packageName != null && !packageName.equals(ps.realName)
4532                    && !packageName.equals(ps.name)) {
4533                continue;
4534            }
4535            if (permissionNames != null
4536                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4537                continue;
4538            }
4539
4540            if (!checkin && packageName != null) {
4541                dumpState.setSharedUser(ps.sharedUser);
4542            }
4543
4544            if (!checkin && !printedSomething) {
4545                if (dumpState.onTitlePrinted())
4546                    pw.println();
4547                pw.println("Packages:");
4548                printedSomething = true;
4549            }
4550            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4551                    packageName != null);
4552        }
4553
4554        printedSomething = false;
4555        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4556            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4557                if (packageName != null && !packageName.equals(e.getKey())
4558                        && !packageName.equals(e.getValue())) {
4559                    continue;
4560                }
4561                if (!checkin) {
4562                    if (!printedSomething) {
4563                        if (dumpState.onTitlePrinted())
4564                            pw.println();
4565                        pw.println("Renamed packages:");
4566                        printedSomething = true;
4567                    }
4568                    pw.print("  ");
4569                } else {
4570                    pw.print("ren,");
4571                }
4572                pw.print(e.getKey());
4573                pw.print(checkin ? " -> " : ",");
4574                pw.println(e.getValue());
4575            }
4576        }
4577
4578        printedSomething = false;
4579        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4580            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4581                if (packageName != null && !packageName.equals(ps.realName)
4582                        && !packageName.equals(ps.name)) {
4583                    continue;
4584                }
4585                if (!checkin && !printedSomething) {
4586                    if (dumpState.onTitlePrinted())
4587                        pw.println();
4588                    pw.println("Hidden system packages:");
4589                    printedSomething = true;
4590                }
4591                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4592                        users, packageName != null);
4593            }
4594        }
4595    }
4596
4597    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4598            DumpState dumpState) {
4599        boolean printedSomething = false;
4600        for (BasePermission p : mPermissions.values()) {
4601            if (packageName != null && !packageName.equals(p.sourcePackage)) {
4602                continue;
4603            }
4604            if (permissionNames != null && !permissionNames.contains(p.name)) {
4605                continue;
4606            }
4607            if (!printedSomething) {
4608                if (dumpState.onTitlePrinted())
4609                    pw.println();
4610                pw.println("Permissions:");
4611                printedSomething = true;
4612            }
4613            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
4614                    pw.print(Integer.toHexString(System.identityHashCode(p)));
4615                    pw.println("):");
4616            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
4617            pw.print("    uid="); pw.print(p.uid);
4618                    pw.print(" gids="); pw.print(Arrays.toString(
4619                            p.computeGids(UserHandle.USER_SYSTEM)));
4620                    pw.print(" type="); pw.print(p.type);
4621                    pw.print(" prot=");
4622                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
4623            if (p.perm != null) {
4624                pw.print("    perm="); pw.println(p.perm);
4625                if ((p.perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0
4626                        || (p.perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0) {
4627                    pw.print("    flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags));
4628                }
4629            }
4630            if (p.packageSetting != null) {
4631                pw.print("    packageSetting="); pw.println(p.packageSetting);
4632            }
4633            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
4634                pw.print("    enforced=");
4635                pw.println(mReadExternalStorageEnforced);
4636            }
4637        }
4638    }
4639
4640    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4641            DumpState dumpState, boolean checkin) {
4642        boolean printedSomething = false;
4643        for (SharedUserSetting su : mSharedUsers.values()) {
4644            if (packageName != null && su != dumpState.getSharedUser()) {
4645                continue;
4646            }
4647            if (permissionNames != null
4648                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4649                continue;
4650            }
4651            if (!checkin) {
4652                if (!printedSomething) {
4653                    if (dumpState.onTitlePrinted())
4654                        pw.println();
4655                    pw.println("Shared users:");
4656                    printedSomething = true;
4657                }
4658                pw.print("  SharedUser [");
4659                pw.print(su.name);
4660                pw.print("] (");
4661                pw.print(Integer.toHexString(System.identityHashCode(su)));
4662                        pw.println("):");
4663
4664                String prefix = "    ";
4665                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4666
4667                PermissionsState permissionsState = su.getPermissionsState();
4668                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4669
4670                for (int userId : UserManagerService.getInstance().getUserIds()) {
4671                    final int[] gids = permissionsState.computeGids(userId);
4672                    List<PermissionState> permissions = permissionsState
4673                            .getRuntimePermissionStates(userId);
4674                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4675                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4676                        dumpGidsLPr(pw, prefix + "  ", gids);
4677                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4678                                packageName != null);
4679                    }
4680                }
4681            } else {
4682                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4683            }
4684        }
4685    }
4686
4687    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4688        pw.println("Settings parse messages:");
4689        pw.print(mReadMessages.toString());
4690    }
4691
4692    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4693        if (mRestoredUserGrants.size() > 0) {
4694            pw.println();
4695            pw.println("Restored (pending) permission grants:");
4696            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4697                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4698                        mRestoredUserGrants.valueAt(userIndex);
4699                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4700                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4701                    pw.print("  User "); pw.println(userId);
4702
4703                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4704                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4705                        if (grants != null && grants.size() > 0) {
4706                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4707                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4708
4709                            for (RestoredPermissionGrant g : grants) {
4710                                pw.print("      ");
4711                                pw.print(g.permissionName);
4712                                if (g.granted) {
4713                                    pw.print(" GRANTED");
4714                                }
4715                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4716                                    pw.print(" user_set");
4717                                }
4718                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4719                                    pw.print(" user_fixed");
4720                                }
4721                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4722                                    pw.print(" revoke_on_upgrade");
4723                                }
4724                                pw.println();
4725                            }
4726                        }
4727                    }
4728                }
4729            }
4730            pw.println();
4731        }
4732    }
4733
4734    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4735        if (pkg == null) {
4736            pw.print("unknown");
4737        } else {
4738            // [base:10, config.mdpi, config.xhdpi:12]
4739            pw.print("[");
4740            pw.print("base");
4741            if (pkg.baseRevisionCode != 0) {
4742                pw.print(":"); pw.print(pkg.baseRevisionCode);
4743            }
4744            if (pkg.splitNames != null) {
4745                for (int i = 0; i < pkg.splitNames.length; i++) {
4746                    pw.print(", ");
4747                    pw.print(pkg.splitNames[i]);
4748                    if (pkg.splitRevisionCodes[i] != 0) {
4749                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4750                    }
4751                }
4752            }
4753            pw.print("]");
4754        }
4755    }
4756
4757    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4758        if (!ArrayUtils.isEmpty(gids)) {
4759            pw.print(prefix);
4760            pw.print("gids="); pw.println(
4761                    PackageManagerService.arrayToString(gids));
4762        }
4763    }
4764
4765    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4766            List<PermissionState> permissionStates, boolean dumpAll) {
4767        if (!permissionStates.isEmpty() || dumpAll) {
4768            pw.print(prefix); pw.println("runtime permissions:");
4769            for (PermissionState permissionState : permissionStates) {
4770                if (permissionNames != null
4771                        && !permissionNames.contains(permissionState.getName())) {
4772                    continue;
4773                }
4774                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4775                pw.print(": granted="); pw.print(permissionState.isGranted());
4776                    pw.println(permissionFlagsToString(", flags=",
4777                            permissionState.getFlags()));
4778            }
4779        }
4780    }
4781
4782    private static String permissionFlagsToString(String prefix, int flags) {
4783        StringBuilder flagsString = null;
4784        while (flags != 0) {
4785            if (flagsString == null) {
4786                flagsString = new StringBuilder();
4787                flagsString.append(prefix);
4788                flagsString.append("[ ");
4789            }
4790            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4791            flags &= ~flag;
4792            flagsString.append(PackageManager.permissionFlagToString(flag));
4793            flagsString.append(' ');
4794        }
4795        if (flagsString != null) {
4796            flagsString.append(']');
4797            return flagsString.toString();
4798        } else {
4799            return "";
4800        }
4801    }
4802
4803    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4804            PermissionsState permissionsState) {
4805        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
4806        if (!permissionStates.isEmpty()) {
4807            pw.print(prefix); pw.println("install permissions:");
4808            for (PermissionState permissionState : permissionStates) {
4809                if (permissionNames != null
4810                        && !permissionNames.contains(permissionState.getName())) {
4811                    continue;
4812                }
4813                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4814                    pw.print(": granted="); pw.print(permissionState.isGranted());
4815                    pw.println(permissionFlagsToString(", flags=",
4816                        permissionState.getFlags()));
4817            }
4818        }
4819    }
4820
4821    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
4822        if (sync) {
4823            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
4824        } else {
4825            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
4826        }
4827    }
4828
4829    private final class RuntimePermissionPersistence {
4830        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
4831        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
4832
4833        private final Handler mHandler = new MyHandler();
4834
4835        private final Object mLock;
4836
4837        @GuardedBy("mLock")
4838        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
4839
4840        @GuardedBy("mLock")
4841        // The mapping keys are user ids.
4842        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
4843
4844        @GuardedBy("mLock")
4845        // The mapping keys are user ids.
4846        private final SparseArray<String> mFingerprints = new SparseArray<>();
4847
4848        @GuardedBy("mLock")
4849        // The mapping keys are user ids.
4850        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
4851
4852        public RuntimePermissionPersistence(Object lock) {
4853            mLock = lock;
4854        }
4855
4856        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
4857            return mDefaultPermissionsGranted.get(userId);
4858        }
4859
4860        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
4861            mFingerprints.put(userId, Build.FINGERPRINT);
4862            writePermissionsForUserAsyncLPr(userId);
4863        }
4864
4865        public void writePermissionsForUserSyncLPr(int userId) {
4866            mHandler.removeMessages(userId);
4867            writePermissionsSync(userId);
4868        }
4869
4870        public void writePermissionsForUserAsyncLPr(int userId) {
4871            final long currentTimeMillis = SystemClock.uptimeMillis();
4872
4873            if (mWriteScheduled.get(userId)) {
4874                mHandler.removeMessages(userId);
4875
4876                // If enough time passed, write without holding off anymore.
4877                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
4878                        .get(userId);
4879                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
4880                        - lastNotWrittenMutationTimeMillis;
4881                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
4882                    mHandler.obtainMessage(userId).sendToTarget();
4883                    return;
4884                }
4885
4886                // Hold off a bit more as settings are frequently changing.
4887                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
4888                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
4889                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
4890                        maxDelayMillis);
4891
4892                Message message = mHandler.obtainMessage(userId);
4893                mHandler.sendMessageDelayed(message, writeDelayMillis);
4894            } else {
4895                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
4896                Message message = mHandler.obtainMessage(userId);
4897                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
4898                mWriteScheduled.put(userId, true);
4899            }
4900        }
4901
4902        private void writePermissionsSync(int userId) {
4903            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
4904
4905            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
4906            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
4907
4908            synchronized (mLock) {
4909                mWriteScheduled.delete(userId);
4910
4911                final int packageCount = mPackages.size();
4912                for (int i = 0; i < packageCount; i++) {
4913                    String packageName = mPackages.keyAt(i);
4914                    PackageSetting packageSetting = mPackages.valueAt(i);
4915                    if (packageSetting.sharedUser == null) {
4916                        PermissionsState permissionsState = packageSetting.getPermissionsState();
4917                        List<PermissionState> permissionsStates = permissionsState
4918                                .getRuntimePermissionStates(userId);
4919                        if (!permissionsStates.isEmpty()) {
4920                            permissionsForPackage.put(packageName, permissionsStates);
4921                        }
4922                    }
4923                }
4924
4925                final int sharedUserCount = mSharedUsers.size();
4926                for (int i = 0; i < sharedUserCount; i++) {
4927                    String sharedUserName = mSharedUsers.keyAt(i);
4928                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
4929                    PermissionsState permissionsState = sharedUser.getPermissionsState();
4930                    List<PermissionState> permissionsStates = permissionsState
4931                            .getRuntimePermissionStates(userId);
4932                    if (!permissionsStates.isEmpty()) {
4933                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
4934                    }
4935                }
4936            }
4937
4938            FileOutputStream out = null;
4939            try {
4940                out = destination.startWrite();
4941
4942                XmlSerializer serializer = Xml.newSerializer();
4943                serializer.setOutput(out, StandardCharsets.UTF_8.name());
4944                serializer.setFeature(
4945                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
4946                serializer.startDocument(null, true);
4947
4948                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
4949
4950                String fingerprint = mFingerprints.get(userId);
4951                if (fingerprint != null) {
4952                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
4953                }
4954
4955                final int packageCount = permissionsForPackage.size();
4956                for (int i = 0; i < packageCount; i++) {
4957                    String packageName = permissionsForPackage.keyAt(i);
4958                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
4959                    serializer.startTag(null, TAG_PACKAGE);
4960                    serializer.attribute(null, ATTR_NAME, packageName);
4961                    writePermissions(serializer, permissionStates);
4962                    serializer.endTag(null, TAG_PACKAGE);
4963                }
4964
4965                final int sharedUserCount = permissionsForSharedUser.size();
4966                for (int i = 0; i < sharedUserCount; i++) {
4967                    String packageName = permissionsForSharedUser.keyAt(i);
4968                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
4969                    serializer.startTag(null, TAG_SHARED_USER);
4970                    serializer.attribute(null, ATTR_NAME, packageName);
4971                    writePermissions(serializer, permissionStates);
4972                    serializer.endTag(null, TAG_SHARED_USER);
4973                }
4974
4975                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
4976
4977                // Now any restored permission grants that are waiting for the apps
4978                // in question to be installed.  These are stored as per-package
4979                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
4980                // number of individual permission grant entities.
4981                if (mRestoredUserGrants.get(userId) != null) {
4982                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
4983                            mRestoredUserGrants.get(userId);
4984                    if (restoredGrants != null) {
4985                        final int pkgCount = restoredGrants.size();
4986                        for (int i = 0; i < pkgCount; i++) {
4987                            final ArraySet<RestoredPermissionGrant> pkgGrants =
4988                                    restoredGrants.valueAt(i);
4989                            if (pkgGrants != null && pkgGrants.size() > 0) {
4990                                final String pkgName = restoredGrants.keyAt(i);
4991                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
4992                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
4993
4994                                final int N = pkgGrants.size();
4995                                for (int z = 0; z < N; z++) {
4996                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
4997                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
4998                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
4999
5000                                    if (g.granted) {
5001                                        serializer.attribute(null, ATTR_GRANTED, "true");
5002                                    }
5003
5004                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
5005                                        serializer.attribute(null, ATTR_USER_SET, "true");
5006                                    }
5007                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
5008                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
5009                                    }
5010                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
5011                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
5012                                    }
5013                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
5014                                }
5015                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5016                            }
5017                        }
5018                    }
5019                }
5020
5021                serializer.endDocument();
5022                destination.finishWrite(out);
5023
5024                if (Build.FINGERPRINT.equals(fingerprint)) {
5025                    mDefaultPermissionsGranted.put(userId, true);
5026                }
5027            // Any error while writing is fatal.
5028            } catch (Throwable t) {
5029                Slog.wtf(PackageManagerService.TAG,
5030                        "Failed to write settings, restoring backup", t);
5031                destination.failWrite(out);
5032            } finally {
5033                IoUtils.closeQuietly(out);
5034            }
5035        }
5036
5037        private void onUserRemoved(int userId) {
5038            // Make sure we do not
5039            mHandler.removeMessages(userId);
5040
5041            for (SettingBase sb : mPackages.values()) {
5042                revokeRuntimePermissionsAndClearFlags(sb, userId);
5043            }
5044
5045            for (SettingBase sb : mSharedUsers.values()) {
5046                revokeRuntimePermissionsAndClearFlags(sb, userId);
5047            }
5048        }
5049
5050        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5051            PermissionsState permissionsState = sb.getPermissionsState();
5052            for (PermissionState permissionState
5053                    : permissionsState.getRuntimePermissionStates(userId)) {
5054                BasePermission bp = mPermissions.get(permissionState.getName());
5055                if (bp != null) {
5056                    permissionsState.revokeRuntimePermission(bp, userId);
5057                    permissionsState.updatePermissionFlags(bp, userId,
5058                            PackageManager.MASK_PERMISSION_FLAGS, 0);
5059                }
5060            }
5061        }
5062
5063        public void deleteUserRuntimePermissionsFile(int userId) {
5064            getUserRuntimePermissionsFile(userId).delete();
5065        }
5066
5067        public void readStateForUserSyncLPr(int userId) {
5068            File permissionsFile = getUserRuntimePermissionsFile(userId);
5069            if (!permissionsFile.exists()) {
5070                return;
5071            }
5072
5073            FileInputStream in;
5074            try {
5075                in = new AtomicFile(permissionsFile).openRead();
5076            } catch (FileNotFoundException fnfe) {
5077                Slog.i(PackageManagerService.TAG, "No permissions state");
5078                return;
5079            }
5080
5081            try {
5082                XmlPullParser parser = Xml.newPullParser();
5083                parser.setInput(in, null);
5084                parseRuntimePermissionsLPr(parser, userId);
5085
5086            } catch (XmlPullParserException | IOException e) {
5087                throw new IllegalStateException("Failed parsing permissions file: "
5088                        + permissionsFile , e);
5089            } finally {
5090                IoUtils.closeQuietly(in);
5091            }
5092        }
5093
5094        // Backup/restore support
5095
5096        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
5097                boolean isGranted, int restoredFlagSet, int userId) {
5098            // This change will be remembered at write-settings time
5099            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
5100                    mRestoredUserGrants.get(userId);
5101            if (grantsByPackage == null) {
5102                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
5103                mRestoredUserGrants.put(userId, grantsByPackage);
5104            }
5105
5106            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
5107            if (grants == null) {
5108                grants = new ArraySet<RestoredPermissionGrant>();
5109                grantsByPackage.put(pkgName, grants);
5110            }
5111
5112            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
5113                    isGranted, restoredFlagSet);
5114            grants.add(grant);
5115        }
5116
5117        // Private internals
5118
5119        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5120                throws IOException, XmlPullParserException {
5121            final int outerDepth = parser.getDepth();
5122            int type;
5123            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5124                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5125                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5126                    continue;
5127                }
5128
5129                switch (parser.getName()) {
5130                    case TAG_RUNTIME_PERMISSIONS: {
5131                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5132                        mFingerprints.put(userId, fingerprint);
5133                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5134                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
5135                    } break;
5136
5137                    case TAG_PACKAGE: {
5138                        String name = parser.getAttributeValue(null, ATTR_NAME);
5139                        PackageSetting ps = mPackages.get(name);
5140                        if (ps == null) {
5141                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5142                            XmlUtils.skipCurrentTag(parser);
5143                            continue;
5144                        }
5145                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5146                    } break;
5147
5148                    case TAG_SHARED_USER: {
5149                        String name = parser.getAttributeValue(null, ATTR_NAME);
5150                        SharedUserSetting sus = mSharedUsers.get(name);
5151                        if (sus == null) {
5152                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5153                            XmlUtils.skipCurrentTag(parser);
5154                            continue;
5155                        }
5156                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5157                    } break;
5158
5159                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
5160                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
5161                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
5162                    } break;
5163                }
5164            }
5165        }
5166
5167        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
5168                final String pkgName, final int userId) throws IOException, XmlPullParserException {
5169            final int outerDepth = parser.getDepth();
5170            int type;
5171            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5172                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5173                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5174                    continue;
5175                }
5176
5177                switch (parser.getName()) {
5178                    case TAG_PERMISSION_ENTRY: {
5179                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
5180                        final boolean isGranted = "true".equals(
5181                                parser.getAttributeValue(null, ATTR_GRANTED));
5182
5183                        int permBits = 0;
5184                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
5185                            permBits |= FLAG_PERMISSION_USER_SET;
5186                        }
5187                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
5188                            permBits |= FLAG_PERMISSION_USER_FIXED;
5189                        }
5190                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
5191                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
5192                        }
5193
5194                        if (isGranted || permBits != 0) {
5195                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5196                        }
5197                    } break;
5198                }
5199            }
5200        }
5201
5202        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5203                int userId) throws IOException, XmlPullParserException {
5204            final int outerDepth = parser.getDepth();
5205            int type;
5206            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5207                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5208                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5209                    continue;
5210                }
5211
5212                switch (parser.getName()) {
5213                    case TAG_ITEM: {
5214                        String name = parser.getAttributeValue(null, ATTR_NAME);
5215                        BasePermission bp = mPermissions.get(name);
5216                        if (bp == null) {
5217                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5218                            XmlUtils.skipCurrentTag(parser);
5219                            continue;
5220                        }
5221
5222                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5223                        final boolean granted = grantedStr == null
5224                                || Boolean.parseBoolean(grantedStr);
5225
5226                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5227                        final int flags = (flagsStr != null)
5228                                ? Integer.parseInt(flagsStr, 16) : 0;
5229
5230                        if (granted) {
5231                            permissionsState.grantRuntimePermission(bp, userId);
5232                            permissionsState.updatePermissionFlags(bp, userId,
5233                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5234                        } else {
5235                            permissionsState.updatePermissionFlags(bp, userId,
5236                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5237                        }
5238
5239                    } break;
5240                }
5241            }
5242        }
5243
5244        private void writePermissions(XmlSerializer serializer,
5245                List<PermissionState> permissionStates) throws IOException {
5246            for (PermissionState permissionState : permissionStates) {
5247                serializer.startTag(null, TAG_ITEM);
5248                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5249                serializer.attribute(null, ATTR_GRANTED,
5250                        String.valueOf(permissionState.isGranted()));
5251                serializer.attribute(null, ATTR_FLAGS,
5252                        Integer.toHexString(permissionState.getFlags()));
5253                serializer.endTag(null, TAG_ITEM);
5254            }
5255        }
5256
5257        private final class MyHandler extends Handler {
5258            public MyHandler() {
5259                super(BackgroundThread.getHandler().getLooper());
5260            }
5261
5262            @Override
5263            public void handleMessage(Message message) {
5264                final int userId = message.what;
5265                Runnable callback = (Runnable) message.obj;
5266                writePermissionsSync(userId);
5267                if (callback != null) {
5268                    callback.run();
5269                }
5270            }
5271        }
5272    }
5273}
5274