Settings.java revision 800efcc7f533ddce66c0c7b34c837d3323512d2a
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
2608        if (pkg.parentPackageName != null) {
2609            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2610        }
2611
2612        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2613
2614        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
2615
2616        writePermissionsLPr(serializer, pkg.getPermissionsState()
2617                    .getInstallPermissionStates());
2618
2619        writeSigningKeySetLPr(serializer, pkg.keySetData);
2620        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
2621        writeKeySetAliasesLPr(serializer, pkg.keySetData);
2622        writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
2623
2624        serializer.endTag(null, "package");
2625    }
2626
2627    void writeSigningKeySetLPr(XmlSerializer serializer,
2628            PackageKeySetData data) throws IOException {
2629        serializer.startTag(null, "proper-signing-keyset");
2630        serializer.attribute(null, "identifier",
2631                Long.toString(data.getProperSigningKeySet()));
2632        serializer.endTag(null, "proper-signing-keyset");
2633    }
2634
2635    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2636            PackageKeySetData data) throws IOException {
2637        long properSigning = data.getProperSigningKeySet();
2638        if (data.isUsingUpgradeKeySets()) {
2639            for (long id : data.getUpgradeKeySets()) {
2640                serializer.startTag(null, "upgrade-keyset");
2641                serializer.attribute(null, "identifier", Long.toString(id));
2642                serializer.endTag(null, "upgrade-keyset");
2643            }
2644        }
2645    }
2646
2647    void writeKeySetAliasesLPr(XmlSerializer serializer,
2648            PackageKeySetData data) throws IOException {
2649        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2650            serializer.startTag(null, "defined-keyset");
2651            serializer.attribute(null, "alias", e.getKey());
2652            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2653            serializer.endTag(null, "defined-keyset");
2654        }
2655    }
2656
2657    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
2658            throws XmlPullParserException, java.io.IOException {
2659        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
2660            serializer.startTag(null, TAG_ITEM);
2661            serializer.attribute(null, ATTR_NAME, bp.name);
2662            serializer.attribute(null, "package", bp.sourcePackage);
2663            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
2664                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
2665            }
2666            if (PackageManagerService.DEBUG_SETTINGS)
2667                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
2668                        + bp.type);
2669            if (bp.type == BasePermission.TYPE_DYNAMIC) {
2670                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
2671                if (pi != null) {
2672                    serializer.attribute(null, "type", "dynamic");
2673                    if (pi.icon != 0) {
2674                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
2675                    }
2676                    if (pi.nonLocalizedLabel != null) {
2677                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
2678                    }
2679                }
2680            }
2681            serializer.endTag(null, TAG_ITEM);
2682        }
2683    }
2684
2685    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
2686        final ArraySet<String> kList = new ArraySet<String>(mPackages.keySet());
2687        final Iterator<String> its = kList.iterator();
2688        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
2689        while (its.hasNext()) {
2690            final String key = its.next();
2691            final PackageSetting ps = mPackages.get(key);
2692            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2693                ret.add(ps);
2694            }
2695        }
2696        return ret;
2697    }
2698
2699    void addPackageToCleanLPw(PackageCleanItem pkg) {
2700        if (!mPackagesToBeCleaned.contains(pkg)) {
2701            mPackagesToBeCleaned.add(pkg);
2702        }
2703    }
2704
2705    boolean readLPw(@NonNull List<UserInfo> users) {
2706        FileInputStream str = null;
2707        if (mBackupSettingsFilename.exists()) {
2708            try {
2709                str = new FileInputStream(mBackupSettingsFilename);
2710                mReadMessages.append("Reading from backup settings file\n");
2711                PackageManagerService.reportSettingsProblem(Log.INFO,
2712                        "Need to read from backup settings file");
2713                if (mSettingsFilename.exists()) {
2714                    // If both the backup and settings file exist, we
2715                    // ignore the settings since it might have been
2716                    // corrupted.
2717                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2718                            + mSettingsFilename);
2719                    mSettingsFilename.delete();
2720                }
2721            } catch (java.io.IOException e) {
2722                // We'll try for the normal settings file.
2723            }
2724        }
2725
2726        mPendingPackages.clear();
2727        mPastSignatures.clear();
2728        mKeySetRefs.clear();
2729
2730        try {
2731            if (str == null) {
2732                if (!mSettingsFilename.exists()) {
2733                    mReadMessages.append("No settings file found\n");
2734                    PackageManagerService.reportSettingsProblem(Log.INFO,
2735                            "No settings file; creating initial state");
2736                    // It's enough to just touch version details to create them
2737                    // with default values
2738                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL);
2739                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL);
2740                    return false;
2741                }
2742                str = new FileInputStream(mSettingsFilename);
2743            }
2744            XmlPullParser parser = Xml.newPullParser();
2745            parser.setInput(str, StandardCharsets.UTF_8.name());
2746
2747            int type;
2748            while ((type = parser.next()) != XmlPullParser.START_TAG
2749                    && type != XmlPullParser.END_DOCUMENT) {
2750                ;
2751            }
2752
2753            if (type != XmlPullParser.START_TAG) {
2754                mReadMessages.append("No start tag found in settings file\n");
2755                PackageManagerService.reportSettingsProblem(Log.WARN,
2756                        "No start tag found in package manager settings");
2757                Slog.wtf(PackageManagerService.TAG,
2758                        "No start tag found in package manager settings");
2759                return false;
2760            }
2761
2762            int outerDepth = parser.getDepth();
2763            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2764                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2765                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2766                    continue;
2767                }
2768
2769                String tagName = parser.getName();
2770                if (tagName.equals("package")) {
2771                    readPackageLPw(parser);
2772                } else if (tagName.equals("permissions")) {
2773                    readPermissionsLPw(mPermissions, parser);
2774                } else if (tagName.equals("permission-trees")) {
2775                    readPermissionsLPw(mPermissionTrees, parser);
2776                } else if (tagName.equals("shared-user")) {
2777                    readSharedUserLPw(parser);
2778                } else if (tagName.equals("preferred-packages")) {
2779                    // no longer used.
2780                } else if (tagName.equals("preferred-activities")) {
2781                    // Upgrading from old single-user implementation;
2782                    // these are the preferred activities for user 0.
2783                    readPreferredActivitiesLPw(parser, 0);
2784                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2785                    // TODO: check whether this is okay! as it is very
2786                    // similar to how preferred-activities are treated
2787                    readPersistentPreferredActivitiesLPw(parser, 0);
2788                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2789                    // TODO: check whether this is okay! as it is very
2790                    // similar to how preferred-activities are treated
2791                    readCrossProfileIntentFiltersLPw(parser, 0);
2792                } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
2793                    readDefaultAppsLPw(parser, 0);
2794                } else if (tagName.equals("updated-package")) {
2795                    readDisabledSysPackageLPw(parser);
2796                } else if (tagName.equals("cleaning-package")) {
2797                    String name = parser.getAttributeValue(null, ATTR_NAME);
2798                    String userStr = parser.getAttributeValue(null, ATTR_USER);
2799                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
2800                    if (name != null) {
2801                        int userId = UserHandle.USER_SYSTEM;
2802                        boolean andCode = true;
2803                        try {
2804                            if (userStr != null) {
2805                                userId = Integer.parseInt(userStr);
2806                            }
2807                        } catch (NumberFormatException e) {
2808                        }
2809                        if (codeStr != null) {
2810                            andCode = Boolean.parseBoolean(codeStr);
2811                        }
2812                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
2813                    }
2814                } else if (tagName.equals("renamed-package")) {
2815                    String nname = parser.getAttributeValue(null, "new");
2816                    String oname = parser.getAttributeValue(null, "old");
2817                    if (nname != null && oname != null) {
2818                        mRenamedPackages.put(nname, oname);
2819                    }
2820                } else if (tagName.equals("restored-ivi")) {
2821                    readRestoredIntentFilterVerifications(parser);
2822                } else if (tagName.equals("last-platform-version")) {
2823                    // Upgrade from older XML schema
2824                    final VersionInfo internal = findOrCreateVersion(
2825                            StorageManager.UUID_PRIVATE_INTERNAL);
2826                    final VersionInfo external = findOrCreateVersion(
2827                            StorageManager.UUID_PRIMARY_PHYSICAL);
2828
2829                    internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
2830                    external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
2831                    internal.fingerprint = external.fingerprint =
2832                            XmlUtils.readStringAttribute(parser, "fingerprint");
2833
2834                } else if (tagName.equals("database-version")) {
2835                    // Upgrade from older XML schema
2836                    final VersionInfo internal = findOrCreateVersion(
2837                            StorageManager.UUID_PRIVATE_INTERNAL);
2838                    final VersionInfo external = findOrCreateVersion(
2839                            StorageManager.UUID_PRIMARY_PHYSICAL);
2840
2841                    internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
2842                    external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);
2843
2844                } else if (tagName.equals("verifier")) {
2845                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2846                    try {
2847                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2848                    } catch (IllegalArgumentException e) {
2849                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2850                                + e.getMessage());
2851                    }
2852                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2853                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2854                    mReadExternalStorageEnforced = "1".equals(enforcement);
2855                } else if (tagName.equals("keyset-settings")) {
2856                    mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
2857                } else if (TAG_VERSION.equals(tagName)) {
2858                    final String volumeUuid = XmlUtils.readStringAttribute(parser,
2859                            ATTR_VOLUME_UUID);
2860                    final VersionInfo ver = findOrCreateVersion(volumeUuid);
2861                    ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
2862                    ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
2863                    ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
2864
2865                } else {
2866                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2867                            + parser.getName());
2868                    XmlUtils.skipCurrentTag(parser);
2869                }
2870            }
2871
2872            str.close();
2873
2874        } catch (XmlPullParserException e) {
2875            mReadMessages.append("Error reading: " + e.toString());
2876            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2877            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2878
2879        } catch (java.io.IOException e) {
2880            mReadMessages.append("Error reading: " + e.toString());
2881            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2882            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2883        }
2884
2885        // If the build is setup to drop runtime permissions
2886        // on update drop the files before loading them.
2887        if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
2888            final VersionInfo internal = getInternalVersion();
2889            if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
2890                for (UserInfo user : users) {
2891                    mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
2892                }
2893            }
2894        }
2895
2896        final int N = mPendingPackages.size();
2897
2898        for (int i = 0; i < N; i++) {
2899            final PendingPackage pp = mPendingPackages.get(i);
2900            Object idObj = getUserIdLPr(pp.sharedId);
2901            if (idObj != null && idObj instanceof SharedUserSetting) {
2902                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
2903                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
2904                        pp.legacyNativeLibraryPathString, pp.primaryCpuAbiString,
2905                        pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags, pp.pkgPrivateFlags,
2906                        null, true /* add */, false /* allowInstall */, pp.parentPackageName,
2907                        pp.childPackageNames);
2908                if (p == null) {
2909                    PackageManagerService.reportSettingsProblem(Log.WARN,
2910                            "Unable to create application package for " + pp.name);
2911                    continue;
2912                }
2913                p.copyFrom(pp);
2914            } else if (idObj != null) {
2915                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2916                        + pp.sharedId + " that is not a shared uid\n";
2917                mReadMessages.append(msg);
2918                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2919            } else {
2920                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2921                        + pp.sharedId + " that is not defined\n";
2922                mReadMessages.append(msg);
2923                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2924            }
2925        }
2926        mPendingPackages.clear();
2927
2928        if (mBackupStoppedPackagesFilename.exists()
2929                || mStoppedPackagesFilename.exists()) {
2930            // Read old file
2931            readStoppedLPw();
2932            mBackupStoppedPackagesFilename.delete();
2933            mStoppedPackagesFilename.delete();
2934            // Migrate to new file format
2935            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
2936        } else {
2937            for (UserInfo user : users) {
2938                readPackageRestrictionsLPr(user.id);
2939            }
2940        }
2941
2942        for (UserInfo user : users) {
2943            mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
2944        }
2945
2946        /*
2947         * Make sure all the updated system packages have their shared users
2948         * associated with them.
2949         */
2950        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
2951        while (disabledIt.hasNext()) {
2952            final PackageSetting disabledPs = disabledIt.next();
2953            final Object id = getUserIdLPr(disabledPs.appId);
2954            if (id != null && id instanceof SharedUserSetting) {
2955                disabledPs.sharedUser = (SharedUserSetting) id;
2956            }
2957        }
2958
2959        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
2960                + mSharedUsers.size() + " shared uids\n");
2961
2962        writeKernelMappingLPr();
2963
2964        return true;
2965    }
2966
2967    void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
2968        // First pull data from any pre-installed apps.
2969        for (PackageSetting ps : mPackages.values()) {
2970            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
2971                    && ps.pkg.preferredActivityFilters != null) {
2972                ArrayList<PackageParser.ActivityIntentInfo> intents
2973                        = ps.pkg.preferredActivityFilters;
2974                for (int i=0; i<intents.size(); i++) {
2975                    PackageParser.ActivityIntentInfo aii = intents.get(i);
2976                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
2977                            ps.name, aii.activity.className), userId);
2978                }
2979            }
2980        }
2981
2982        // Read preferred apps from .../etc/preferred-apps directory.
2983        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
2984        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
2985            return;
2986        }
2987        if (!preferredDir.canRead()) {
2988            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
2989            return;
2990        }
2991
2992        // Iterate over the files in the directory and scan .xml files
2993        for (File f : preferredDir.listFiles()) {
2994            if (!f.getPath().endsWith(".xml")) {
2995                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
2996                continue;
2997            }
2998            if (!f.canRead()) {
2999                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
3000                continue;
3001            }
3002
3003            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
3004            InputStream str = null;
3005            try {
3006                str = new BufferedInputStream(new FileInputStream(f));
3007                XmlPullParser parser = Xml.newPullParser();
3008                parser.setInput(str, null);
3009
3010                int type;
3011                while ((type = parser.next()) != XmlPullParser.START_TAG
3012                        && type != XmlPullParser.END_DOCUMENT) {
3013                    ;
3014                }
3015
3016                if (type != XmlPullParser.START_TAG) {
3017                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
3018                    continue;
3019                }
3020                if (!"preferred-activities".equals(parser.getName())) {
3021                    Slog.w(TAG, "Preferred apps file " + f
3022                            + " does not start with 'preferred-activities'");
3023                    continue;
3024                }
3025                readDefaultPreferredActivitiesLPw(service, parser, userId);
3026            } catch (XmlPullParserException e) {
3027                Slog.w(TAG, "Error reading apps file " + f, e);
3028            } catch (IOException e) {
3029                Slog.w(TAG, "Error reading apps file " + f, e);
3030            } finally {
3031                if (str != null) {
3032                    try {
3033                        str.close();
3034                    } catch (IOException e) {
3035                    }
3036                }
3037            }
3038        }
3039    }
3040
3041    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3042            IntentFilter tmpPa, ComponentName cn, int userId) {
3043        // The initial preferences only specify the target activity
3044        // component and intent-filter, not the set of matches.  So we
3045        // now need to query for the matches to build the correct
3046        // preferred activity entry.
3047        if (PackageManagerService.DEBUG_PREFERRED) {
3048            Log.d(TAG, "Processing preferred:");
3049            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
3050        }
3051        Intent intent = new Intent();
3052        int flags = 0;
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_PRIVILEGED, "PRIVILEGED",
4175        ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK",
4176        ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4177    };
4178
4179    void dumpVersionLPr(IndentingPrintWriter pw) {
4180        pw.increaseIndent();
4181        for (int i= 0; i < mVersion.size(); i++) {
4182            final String volumeUuid = mVersion.keyAt(i);
4183            final VersionInfo ver = mVersion.valueAt(i);
4184            if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4185                pw.println("Internal:");
4186            } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4187                pw.println("External:");
4188            } else {
4189                pw.println("UUID " + volumeUuid + ":");
4190            }
4191            pw.increaseIndent();
4192            pw.printPair("sdkVersion", ver.sdkVersion);
4193            pw.printPair("databaseVersion", ver.databaseVersion);
4194            pw.println();
4195            pw.printPair("fingerprint", ver.fingerprint);
4196            pw.println();
4197            pw.decreaseIndent();
4198        }
4199        pw.decreaseIndent();
4200    }
4201
4202    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4203            ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4204            Date date, List<UserInfo> users, boolean dumpAll) {
4205        if (checkinTag != null) {
4206            pw.print(checkinTag);
4207            pw.print(",");
4208            pw.print(ps.realName != null ? ps.realName : ps.name);
4209            pw.print(",");
4210            pw.print(ps.appId);
4211            pw.print(",");
4212            pw.print(ps.versionCode);
4213            pw.print(",");
4214            pw.print(ps.firstInstallTime);
4215            pw.print(",");
4216            pw.print(ps.lastUpdateTime);
4217            pw.print(",");
4218            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4219            pw.println();
4220            if (ps.pkg != null) {
4221                pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4222                pw.print("base,");
4223                pw.println(ps.pkg.baseRevisionCode);
4224                if (ps.pkg.splitNames != null) {
4225                    for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4226                        pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4227                        pw.print(ps.pkg.splitNames[i]); pw.print(",");
4228                        pw.println(ps.pkg.splitRevisionCodes[i]);
4229                    }
4230                }
4231            }
4232            for (UserInfo user : users) {
4233                pw.print(checkinTag);
4234                pw.print("-");
4235                pw.print("usr");
4236                pw.print(",");
4237                pw.print(user.id);
4238                pw.print(",");
4239                pw.print(ps.getInstalled(user.id) ? "I" : "i");
4240                pw.print(ps.getHidden(user.id) ? "B" : "b");
4241                pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4242                pw.print(ps.getStopped(user.id) ? "S" : "s");
4243                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4244                pw.print(",");
4245                pw.print(ps.getEnabled(user.id));
4246                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4247                pw.print(",");
4248                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4249                pw.println();
4250            }
4251            return;
4252        }
4253
4254        pw.print(prefix); pw.print("Package [");
4255            pw.print(ps.realName != null ? ps.realName : ps.name);
4256            pw.print("] (");
4257            pw.print(Integer.toHexString(System.identityHashCode(ps)));
4258            pw.println("):");
4259
4260        if (ps.frozen) {
4261            pw.print(prefix); pw.println("  FROZEN!");
4262        }
4263
4264        if (ps.realName != null) {
4265            pw.print(prefix); pw.print("  compat name=");
4266            pw.println(ps.name);
4267        }
4268
4269        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4270
4271        if (ps.sharedUser != null) {
4272            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4273        }
4274        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4275        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4276        if (permissionNames == null) {
4277            pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4278            pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4279            pw.println(ps.legacyNativeLibraryPathString);
4280            pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4281            pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4282        }
4283        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4284        if (ps.pkg != null) {
4285            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4286        }
4287        pw.println();
4288        if (ps.pkg != null) {
4289            if (ps.pkg.parentPackage != null) {
4290                PackageParser.Package parentPkg = ps.pkg.parentPackage;
4291                PackageSetting pps = mPackages.get(parentPkg.packageName);
4292                if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
4293                    pps = mDisabledSysPackages.get(parentPkg.packageName);
4294                }
4295                if (pps != null) {
4296                    pw.print(prefix); pw.print("  parentPackage=");
4297                    pw.println(pps.realName != null ? pps.realName : pps.name);
4298                }
4299            } else if (ps.pkg.childPackages != null) {
4300                pw.print(prefix); pw.print("  childPackages=[");
4301                final int childCount = ps.pkg.childPackages.size();
4302                for (int i = 0; i < childCount; i++) {
4303                    PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
4304                    PackageSetting cps = mPackages.get(childPkg.packageName);
4305                    if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
4306                        cps = mDisabledSysPackages.get(childPkg.packageName);
4307                    }
4308                    if (cps != null) {
4309                        if (i > 0) {
4310                            pw.print(", ");
4311                        }
4312                        pw.print(cps.realName != null ? cps.realName : cps.name);
4313                    }
4314                }
4315                pw.println("]");
4316            }
4317            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4318            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4319            pw.print(prefix); pw.print("  applicationInfo=");
4320                pw.println(ps.pkg.applicationInfo.toString());
4321            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4322                    FLAG_DUMP_SPEC); pw.println();
4323            if (ps.pkg.applicationInfo.privateFlags != 0) {
4324                pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4325                        ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4326            }
4327            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4328            pw.print(prefix); pw.print("  supportsScreens=[");
4329            boolean first = true;
4330            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4331                if (!first)
4332                    pw.print(", ");
4333                first = false;
4334                pw.print("small");
4335            }
4336            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4337                if (!first)
4338                    pw.print(", ");
4339                first = false;
4340                pw.print("medium");
4341            }
4342            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4343                if (!first)
4344                    pw.print(", ");
4345                first = false;
4346                pw.print("large");
4347            }
4348            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4349                if (!first)
4350                    pw.print(", ");
4351                first = false;
4352                pw.print("xlarge");
4353            }
4354            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4355                if (!first)
4356                    pw.print(", ");
4357                first = false;
4358                pw.print("resizeable");
4359            }
4360            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4361                if (!first)
4362                    pw.print(", ");
4363                first = false;
4364                pw.print("anyDensity");
4365            }
4366            pw.println("]");
4367            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4368                pw.print(prefix); pw.println("  libraries:");
4369                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
4370                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
4371                }
4372            }
4373            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4374                pw.print(prefix); pw.println("  usesLibraries:");
4375                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4376                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4377                }
4378            }
4379            if (ps.pkg.usesOptionalLibraries != null
4380                    && ps.pkg.usesOptionalLibraries.size() > 0) {
4381                pw.print(prefix); pw.println("  usesOptionalLibraries:");
4382                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4383                    pw.print(prefix); pw.print("    ");
4384                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
4385                }
4386            }
4387            if (ps.pkg.usesLibraryFiles != null
4388                    && ps.pkg.usesLibraryFiles.length > 0) {
4389                pw.print(prefix); pw.println("  usesLibraryFiles:");
4390                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4391                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4392                }
4393            }
4394        }
4395        pw.print(prefix); pw.print("  timeStamp=");
4396            date.setTime(ps.timeStamp);
4397            pw.println(sdf.format(date));
4398        pw.print(prefix); pw.print("  firstInstallTime=");
4399            date.setTime(ps.firstInstallTime);
4400            pw.println(sdf.format(date));
4401        pw.print(prefix); pw.print("  lastUpdateTime=");
4402            date.setTime(ps.lastUpdateTime);
4403            pw.println(sdf.format(date));
4404        if (ps.installerPackageName != null) {
4405            pw.print(prefix); pw.print("  installerPackageName=");
4406                    pw.println(ps.installerPackageName);
4407        }
4408        if (ps.volumeUuid != null) {
4409            pw.print(prefix); pw.print("  volumeUuid=");
4410                    pw.println(ps.volumeUuid);
4411        }
4412        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4413        pw.print(prefix); pw.print("  installPermissionsFixed=");
4414                pw.print(ps.installPermissionsFixed);
4415                pw.print(" installStatus="); pw.println(ps.installStatus);
4416        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4417                pw.println();
4418
4419        if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4420            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4421            pw.print(prefix); pw.println("  declared permissions:");
4422            for (int i=0; i<perms.size(); i++) {
4423                PackageParser.Permission perm = perms.get(i);
4424                if (permissionNames != null
4425                        && !permissionNames.contains(perm.info.name)) {
4426                    continue;
4427                }
4428                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4429                pw.print(": prot=");
4430                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4431                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4432                    pw.print(", COSTS_MONEY");
4433                }
4434                if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4435                    pw.print(", HIDDEN");
4436                }
4437                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4438                    pw.print(", INSTALLED");
4439                }
4440                pw.println();
4441            }
4442        }
4443
4444        if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null
4445                && ps.pkg.requestedPermissions.size() > 0) {
4446            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4447            pw.print(prefix); pw.println("  requested permissions:");
4448            for (int i=0; i<perms.size(); i++) {
4449                String perm = perms.get(i);
4450                if (permissionNames != null
4451                        && !permissionNames.contains(perm)) {
4452                    continue;
4453                }
4454                pw.print(prefix); pw.print("    "); pw.println(perm);
4455            }
4456        }
4457
4458        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4459            PermissionsState permissionsState = ps.getPermissionsState();
4460            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4461        }
4462
4463        for (UserInfo user : users) {
4464            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4465            pw.print(" installed=");
4466            pw.print(ps.getInstalled(user.id));
4467            pw.print(" hidden=");
4468            pw.print(ps.getHidden(user.id));
4469            pw.print(" suspended=");
4470            pw.print(ps.getSuspended(user.id));
4471            pw.print(" stopped=");
4472            pw.print(ps.getStopped(user.id));
4473            pw.print(" notLaunched=");
4474            pw.print(ps.getNotLaunched(user.id));
4475            pw.print(" enabled=");
4476            pw.println(ps.getEnabled(user.id));
4477            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4478            if (lastDisabledAppCaller != null) {
4479                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4480                        pw.println(lastDisabledAppCaller);
4481            }
4482
4483            if (ps.sharedUser == null) {
4484                PermissionsState permissionsState = ps.getPermissionsState();
4485                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4486                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4487                        .getRuntimePermissionStates(user.id), dumpAll);
4488            }
4489
4490            if (permissionNames == null) {
4491                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4492                if (cmp != null && cmp.size() > 0) {
4493                    pw.print(prefix); pw.println("    disabledComponents:");
4494                    for (String s : cmp) {
4495                        pw.print(prefix); pw.print("      "); pw.println(s);
4496                    }
4497                }
4498                cmp = ps.getEnabledComponents(user.id);
4499                if (cmp != null && cmp.size() > 0) {
4500                    pw.print(prefix); pw.println("    enabledComponents:");
4501                    for (String s : cmp) {
4502                        pw.print(prefix); pw.print("      "); pw.println(s);
4503                    }
4504                }
4505            }
4506        }
4507    }
4508
4509    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4510            DumpState dumpState, boolean checkin) {
4511        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4512        final Date date = new Date();
4513        boolean printedSomething = false;
4514        List<UserInfo> users = getAllUsers();
4515        for (final PackageSetting ps : mPackages.values()) {
4516            if (packageName != null && !packageName.equals(ps.realName)
4517                    && !packageName.equals(ps.name)) {
4518                continue;
4519            }
4520            if (permissionNames != null
4521                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4522                continue;
4523            }
4524
4525            if (!checkin && packageName != null) {
4526                dumpState.setSharedUser(ps.sharedUser);
4527            }
4528
4529            if (!checkin && !printedSomething) {
4530                if (dumpState.onTitlePrinted())
4531                    pw.println();
4532                pw.println("Packages:");
4533                printedSomething = true;
4534            }
4535            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4536                    packageName != null);
4537        }
4538
4539        printedSomething = false;
4540        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4541            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4542                if (packageName != null && !packageName.equals(e.getKey())
4543                        && !packageName.equals(e.getValue())) {
4544                    continue;
4545                }
4546                if (!checkin) {
4547                    if (!printedSomething) {
4548                        if (dumpState.onTitlePrinted())
4549                            pw.println();
4550                        pw.println("Renamed packages:");
4551                        printedSomething = true;
4552                    }
4553                    pw.print("  ");
4554                } else {
4555                    pw.print("ren,");
4556                }
4557                pw.print(e.getKey());
4558                pw.print(checkin ? " -> " : ",");
4559                pw.println(e.getValue());
4560            }
4561        }
4562
4563        printedSomething = false;
4564        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4565            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4566                if (packageName != null && !packageName.equals(ps.realName)
4567                        && !packageName.equals(ps.name)) {
4568                    continue;
4569                }
4570                if (!checkin && !printedSomething) {
4571                    if (dumpState.onTitlePrinted())
4572                        pw.println();
4573                    pw.println("Hidden system packages:");
4574                    printedSomething = true;
4575                }
4576                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4577                        users, packageName != null);
4578            }
4579        }
4580    }
4581
4582    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4583            DumpState dumpState) {
4584        boolean printedSomething = false;
4585        for (BasePermission p : mPermissions.values()) {
4586            if (packageName != null && !packageName.equals(p.sourcePackage)) {
4587                continue;
4588            }
4589            if (permissionNames != null && !permissionNames.contains(p.name)) {
4590                continue;
4591            }
4592            if (!printedSomething) {
4593                if (dumpState.onTitlePrinted())
4594                    pw.println();
4595                pw.println("Permissions:");
4596                printedSomething = true;
4597            }
4598            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
4599                    pw.print(Integer.toHexString(System.identityHashCode(p)));
4600                    pw.println("):");
4601            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
4602            pw.print("    uid="); pw.print(p.uid);
4603                    pw.print(" gids="); pw.print(Arrays.toString(
4604                            p.computeGids(UserHandle.USER_SYSTEM)));
4605                    pw.print(" type="); pw.print(p.type);
4606                    pw.print(" prot=");
4607                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
4608            if (p.perm != null) {
4609                pw.print("    perm="); pw.println(p.perm);
4610                if ((p.perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0
4611                        || (p.perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0) {
4612                    pw.print("    flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags));
4613                }
4614            }
4615            if (p.packageSetting != null) {
4616                pw.print("    packageSetting="); pw.println(p.packageSetting);
4617            }
4618            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
4619                pw.print("    enforced=");
4620                pw.println(mReadExternalStorageEnforced);
4621            }
4622        }
4623    }
4624
4625    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4626            DumpState dumpState, boolean checkin) {
4627        boolean printedSomething = false;
4628        for (SharedUserSetting su : mSharedUsers.values()) {
4629            if (packageName != null && su != dumpState.getSharedUser()) {
4630                continue;
4631            }
4632            if (permissionNames != null
4633                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4634                continue;
4635            }
4636            if (!checkin) {
4637                if (!printedSomething) {
4638                    if (dumpState.onTitlePrinted())
4639                        pw.println();
4640                    pw.println("Shared users:");
4641                    printedSomething = true;
4642                }
4643                pw.print("  SharedUser [");
4644                pw.print(su.name);
4645                pw.print("] (");
4646                pw.print(Integer.toHexString(System.identityHashCode(su)));
4647                        pw.println("):");
4648
4649                String prefix = "    ";
4650                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4651
4652                PermissionsState permissionsState = su.getPermissionsState();
4653                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4654
4655                for (int userId : UserManagerService.getInstance().getUserIds()) {
4656                    final int[] gids = permissionsState.computeGids(userId);
4657                    List<PermissionState> permissions = permissionsState
4658                            .getRuntimePermissionStates(userId);
4659                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4660                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4661                        dumpGidsLPr(pw, prefix + "  ", gids);
4662                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4663                                packageName != null);
4664                    }
4665                }
4666            } else {
4667                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4668            }
4669        }
4670    }
4671
4672    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4673        pw.println("Settings parse messages:");
4674        pw.print(mReadMessages.toString());
4675    }
4676
4677    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4678        if (mRestoredUserGrants.size() > 0) {
4679            pw.println();
4680            pw.println("Restored (pending) permission grants:");
4681            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4682                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4683                        mRestoredUserGrants.valueAt(userIndex);
4684                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4685                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4686                    pw.print("  User "); pw.println(userId);
4687
4688                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4689                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4690                        if (grants != null && grants.size() > 0) {
4691                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4692                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4693
4694                            for (RestoredPermissionGrant g : grants) {
4695                                pw.print("      ");
4696                                pw.print(g.permissionName);
4697                                if (g.granted) {
4698                                    pw.print(" GRANTED");
4699                                }
4700                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4701                                    pw.print(" user_set");
4702                                }
4703                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4704                                    pw.print(" user_fixed");
4705                                }
4706                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4707                                    pw.print(" revoke_on_upgrade");
4708                                }
4709                                pw.println();
4710                            }
4711                        }
4712                    }
4713                }
4714            }
4715            pw.println();
4716        }
4717    }
4718
4719    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4720        if (pkg == null) {
4721            pw.print("unknown");
4722        } else {
4723            // [base:10, config.mdpi, config.xhdpi:12]
4724            pw.print("[");
4725            pw.print("base");
4726            if (pkg.baseRevisionCode != 0) {
4727                pw.print(":"); pw.print(pkg.baseRevisionCode);
4728            }
4729            if (pkg.splitNames != null) {
4730                for (int i = 0; i < pkg.splitNames.length; i++) {
4731                    pw.print(", ");
4732                    pw.print(pkg.splitNames[i]);
4733                    if (pkg.splitRevisionCodes[i] != 0) {
4734                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4735                    }
4736                }
4737            }
4738            pw.print("]");
4739        }
4740    }
4741
4742    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4743        if (!ArrayUtils.isEmpty(gids)) {
4744            pw.print(prefix);
4745            pw.print("gids="); pw.println(
4746                    PackageManagerService.arrayToString(gids));
4747        }
4748    }
4749
4750    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4751            List<PermissionState> permissionStates, boolean dumpAll) {
4752        if (!permissionStates.isEmpty() || dumpAll) {
4753            pw.print(prefix); pw.println("runtime permissions:");
4754            for (PermissionState permissionState : permissionStates) {
4755                if (permissionNames != null
4756                        && !permissionNames.contains(permissionState.getName())) {
4757                    continue;
4758                }
4759                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4760                pw.print(": granted="); pw.print(permissionState.isGranted());
4761                    pw.println(permissionFlagsToString(", flags=",
4762                            permissionState.getFlags()));
4763            }
4764        }
4765    }
4766
4767    private static String permissionFlagsToString(String prefix, int flags) {
4768        StringBuilder flagsString = null;
4769        while (flags != 0) {
4770            if (flagsString == null) {
4771                flagsString = new StringBuilder();
4772                flagsString.append(prefix);
4773                flagsString.append("[ ");
4774            }
4775            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4776            flags &= ~flag;
4777            flagsString.append(PackageManager.permissionFlagToString(flag));
4778            flagsString.append(' ');
4779        }
4780        if (flagsString != null) {
4781            flagsString.append(']');
4782            return flagsString.toString();
4783        } else {
4784            return "";
4785        }
4786    }
4787
4788    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4789            PermissionsState permissionsState) {
4790        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
4791        if (!permissionStates.isEmpty()) {
4792            pw.print(prefix); pw.println("install permissions:");
4793            for (PermissionState permissionState : permissionStates) {
4794                if (permissionNames != null
4795                        && !permissionNames.contains(permissionState.getName())) {
4796                    continue;
4797                }
4798                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4799                    pw.print(": granted="); pw.print(permissionState.isGranted());
4800                    pw.println(permissionFlagsToString(", flags=",
4801                        permissionState.getFlags()));
4802            }
4803        }
4804    }
4805
4806    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
4807        if (sync) {
4808            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
4809        } else {
4810            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
4811        }
4812    }
4813
4814    private final class RuntimePermissionPersistence {
4815        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
4816        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
4817
4818        private final Handler mHandler = new MyHandler();
4819
4820        private final Object mLock;
4821
4822        @GuardedBy("mLock")
4823        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
4824
4825        @GuardedBy("mLock")
4826        // The mapping keys are user ids.
4827        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
4828
4829        @GuardedBy("mLock")
4830        // The mapping keys are user ids.
4831        private final SparseArray<String> mFingerprints = new SparseArray<>();
4832
4833        @GuardedBy("mLock")
4834        // The mapping keys are user ids.
4835        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
4836
4837        public RuntimePermissionPersistence(Object lock) {
4838            mLock = lock;
4839        }
4840
4841        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
4842            return mDefaultPermissionsGranted.get(userId);
4843        }
4844
4845        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
4846            mFingerprints.put(userId, Build.FINGERPRINT);
4847            writePermissionsForUserAsyncLPr(userId);
4848        }
4849
4850        public void writePermissionsForUserSyncLPr(int userId) {
4851            mHandler.removeMessages(userId);
4852            writePermissionsSync(userId);
4853        }
4854
4855        public void writePermissionsForUserAsyncLPr(int userId) {
4856            final long currentTimeMillis = SystemClock.uptimeMillis();
4857
4858            if (mWriteScheduled.get(userId)) {
4859                mHandler.removeMessages(userId);
4860
4861                // If enough time passed, write without holding off anymore.
4862                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
4863                        .get(userId);
4864                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
4865                        - lastNotWrittenMutationTimeMillis;
4866                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
4867                    mHandler.obtainMessage(userId).sendToTarget();
4868                    return;
4869                }
4870
4871                // Hold off a bit more as settings are frequently changing.
4872                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
4873                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
4874                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
4875                        maxDelayMillis);
4876
4877                Message message = mHandler.obtainMessage(userId);
4878                mHandler.sendMessageDelayed(message, writeDelayMillis);
4879            } else {
4880                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
4881                Message message = mHandler.obtainMessage(userId);
4882                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
4883                mWriteScheduled.put(userId, true);
4884            }
4885        }
4886
4887        private void writePermissionsSync(int userId) {
4888            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
4889
4890            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
4891            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
4892
4893            synchronized (mLock) {
4894                mWriteScheduled.delete(userId);
4895
4896                final int packageCount = mPackages.size();
4897                for (int i = 0; i < packageCount; i++) {
4898                    String packageName = mPackages.keyAt(i);
4899                    PackageSetting packageSetting = mPackages.valueAt(i);
4900                    if (packageSetting.sharedUser == null) {
4901                        PermissionsState permissionsState = packageSetting.getPermissionsState();
4902                        List<PermissionState> permissionsStates = permissionsState
4903                                .getRuntimePermissionStates(userId);
4904                        if (!permissionsStates.isEmpty()) {
4905                            permissionsForPackage.put(packageName, permissionsStates);
4906                        }
4907                    }
4908                }
4909
4910                final int sharedUserCount = mSharedUsers.size();
4911                for (int i = 0; i < sharedUserCount; i++) {
4912                    String sharedUserName = mSharedUsers.keyAt(i);
4913                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
4914                    PermissionsState permissionsState = sharedUser.getPermissionsState();
4915                    List<PermissionState> permissionsStates = permissionsState
4916                            .getRuntimePermissionStates(userId);
4917                    if (!permissionsStates.isEmpty()) {
4918                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
4919                    }
4920                }
4921            }
4922
4923            FileOutputStream out = null;
4924            try {
4925                out = destination.startWrite();
4926
4927                XmlSerializer serializer = Xml.newSerializer();
4928                serializer.setOutput(out, StandardCharsets.UTF_8.name());
4929                serializer.setFeature(
4930                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
4931                serializer.startDocument(null, true);
4932
4933                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
4934
4935                String fingerprint = mFingerprints.get(userId);
4936                if (fingerprint != null) {
4937                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
4938                }
4939
4940                final int packageCount = permissionsForPackage.size();
4941                for (int i = 0; i < packageCount; i++) {
4942                    String packageName = permissionsForPackage.keyAt(i);
4943                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
4944                    serializer.startTag(null, TAG_PACKAGE);
4945                    serializer.attribute(null, ATTR_NAME, packageName);
4946                    writePermissions(serializer, permissionStates);
4947                    serializer.endTag(null, TAG_PACKAGE);
4948                }
4949
4950                final int sharedUserCount = permissionsForSharedUser.size();
4951                for (int i = 0; i < sharedUserCount; i++) {
4952                    String packageName = permissionsForSharedUser.keyAt(i);
4953                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
4954                    serializer.startTag(null, TAG_SHARED_USER);
4955                    serializer.attribute(null, ATTR_NAME, packageName);
4956                    writePermissions(serializer, permissionStates);
4957                    serializer.endTag(null, TAG_SHARED_USER);
4958                }
4959
4960                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
4961
4962                // Now any restored permission grants that are waiting for the apps
4963                // in question to be installed.  These are stored as per-package
4964                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
4965                // number of individual permission grant entities.
4966                if (mRestoredUserGrants.get(userId) != null) {
4967                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
4968                            mRestoredUserGrants.get(userId);
4969                    if (restoredGrants != null) {
4970                        final int pkgCount = restoredGrants.size();
4971                        for (int i = 0; i < pkgCount; i++) {
4972                            final ArraySet<RestoredPermissionGrant> pkgGrants =
4973                                    restoredGrants.valueAt(i);
4974                            if (pkgGrants != null && pkgGrants.size() > 0) {
4975                                final String pkgName = restoredGrants.keyAt(i);
4976                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
4977                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
4978
4979                                final int N = pkgGrants.size();
4980                                for (int z = 0; z < N; z++) {
4981                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
4982                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
4983                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
4984
4985                                    if (g.granted) {
4986                                        serializer.attribute(null, ATTR_GRANTED, "true");
4987                                    }
4988
4989                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4990                                        serializer.attribute(null, ATTR_USER_SET, "true");
4991                                    }
4992                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4993                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
4994                                    }
4995                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4996                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
4997                                    }
4998                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
4999                                }
5000                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5001                            }
5002                        }
5003                    }
5004                }
5005
5006                serializer.endDocument();
5007                destination.finishWrite(out);
5008
5009                if (Build.FINGERPRINT.equals(fingerprint)) {
5010                    mDefaultPermissionsGranted.put(userId, true);
5011                }
5012            // Any error while writing is fatal.
5013            } catch (Throwable t) {
5014                Slog.wtf(PackageManagerService.TAG,
5015                        "Failed to write settings, restoring backup", t);
5016                destination.failWrite(out);
5017            } finally {
5018                IoUtils.closeQuietly(out);
5019            }
5020        }
5021
5022        private void onUserRemoved(int userId) {
5023            // Make sure we do not
5024            mHandler.removeMessages(userId);
5025
5026            for (SettingBase sb : mPackages.values()) {
5027                revokeRuntimePermissionsAndClearFlags(sb, userId);
5028            }
5029
5030            for (SettingBase sb : mSharedUsers.values()) {
5031                revokeRuntimePermissionsAndClearFlags(sb, userId);
5032            }
5033        }
5034
5035        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5036            PermissionsState permissionsState = sb.getPermissionsState();
5037            for (PermissionState permissionState
5038                    : permissionsState.getRuntimePermissionStates(userId)) {
5039                BasePermission bp = mPermissions.get(permissionState.getName());
5040                if (bp != null) {
5041                    permissionsState.revokeRuntimePermission(bp, userId);
5042                    permissionsState.updatePermissionFlags(bp, userId,
5043                            PackageManager.MASK_PERMISSION_FLAGS, 0);
5044                }
5045            }
5046        }
5047
5048        public void deleteUserRuntimePermissionsFile(int userId) {
5049            getUserRuntimePermissionsFile(userId).delete();
5050        }
5051
5052        public void readStateForUserSyncLPr(int userId) {
5053            File permissionsFile = getUserRuntimePermissionsFile(userId);
5054            if (!permissionsFile.exists()) {
5055                return;
5056            }
5057
5058            FileInputStream in;
5059            try {
5060                in = new AtomicFile(permissionsFile).openRead();
5061            } catch (FileNotFoundException fnfe) {
5062                Slog.i(PackageManagerService.TAG, "No permissions state");
5063                return;
5064            }
5065
5066            try {
5067                XmlPullParser parser = Xml.newPullParser();
5068                parser.setInput(in, null);
5069                parseRuntimePermissionsLPr(parser, userId);
5070
5071            } catch (XmlPullParserException | IOException e) {
5072                throw new IllegalStateException("Failed parsing permissions file: "
5073                        + permissionsFile , e);
5074            } finally {
5075                IoUtils.closeQuietly(in);
5076            }
5077        }
5078
5079        // Backup/restore support
5080
5081        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
5082                boolean isGranted, int restoredFlagSet, int userId) {
5083            // This change will be remembered at write-settings time
5084            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
5085                    mRestoredUserGrants.get(userId);
5086            if (grantsByPackage == null) {
5087                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
5088                mRestoredUserGrants.put(userId, grantsByPackage);
5089            }
5090
5091            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
5092            if (grants == null) {
5093                grants = new ArraySet<RestoredPermissionGrant>();
5094                grantsByPackage.put(pkgName, grants);
5095            }
5096
5097            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
5098                    isGranted, restoredFlagSet);
5099            grants.add(grant);
5100        }
5101
5102        // Private internals
5103
5104        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5105                throws IOException, XmlPullParserException {
5106            final int outerDepth = parser.getDepth();
5107            int type;
5108            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5109                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5110                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5111                    continue;
5112                }
5113
5114                switch (parser.getName()) {
5115                    case TAG_RUNTIME_PERMISSIONS: {
5116                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5117                        mFingerprints.put(userId, fingerprint);
5118                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5119                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
5120                    } break;
5121
5122                    case TAG_PACKAGE: {
5123                        String name = parser.getAttributeValue(null, ATTR_NAME);
5124                        PackageSetting ps = mPackages.get(name);
5125                        if (ps == null) {
5126                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5127                            XmlUtils.skipCurrentTag(parser);
5128                            continue;
5129                        }
5130                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5131                    } break;
5132
5133                    case TAG_SHARED_USER: {
5134                        String name = parser.getAttributeValue(null, ATTR_NAME);
5135                        SharedUserSetting sus = mSharedUsers.get(name);
5136                        if (sus == null) {
5137                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5138                            XmlUtils.skipCurrentTag(parser);
5139                            continue;
5140                        }
5141                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5142                    } break;
5143
5144                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
5145                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
5146                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
5147                    } break;
5148                }
5149            }
5150        }
5151
5152        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
5153                final String pkgName, final int userId) throws IOException, XmlPullParserException {
5154            final int outerDepth = parser.getDepth();
5155            int type;
5156            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5157                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5158                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5159                    continue;
5160                }
5161
5162                switch (parser.getName()) {
5163                    case TAG_PERMISSION_ENTRY: {
5164                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
5165                        final boolean isGranted = "true".equals(
5166                                parser.getAttributeValue(null, ATTR_GRANTED));
5167
5168                        int permBits = 0;
5169                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
5170                            permBits |= FLAG_PERMISSION_USER_SET;
5171                        }
5172                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
5173                            permBits |= FLAG_PERMISSION_USER_FIXED;
5174                        }
5175                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
5176                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
5177                        }
5178
5179                        if (isGranted || permBits != 0) {
5180                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5181                        }
5182                    } break;
5183                }
5184            }
5185        }
5186
5187        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5188                int userId) throws IOException, XmlPullParserException {
5189            final int outerDepth = parser.getDepth();
5190            int type;
5191            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5192                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5193                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5194                    continue;
5195                }
5196
5197                switch (parser.getName()) {
5198                    case TAG_ITEM: {
5199                        String name = parser.getAttributeValue(null, ATTR_NAME);
5200                        BasePermission bp = mPermissions.get(name);
5201                        if (bp == null) {
5202                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5203                            XmlUtils.skipCurrentTag(parser);
5204                            continue;
5205                        }
5206
5207                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5208                        final boolean granted = grantedStr == null
5209                                || Boolean.parseBoolean(grantedStr);
5210
5211                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5212                        final int flags = (flagsStr != null)
5213                                ? Integer.parseInt(flagsStr, 16) : 0;
5214
5215                        if (granted) {
5216                            permissionsState.grantRuntimePermission(bp, userId);
5217                            permissionsState.updatePermissionFlags(bp, userId,
5218                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5219                        } else {
5220                            permissionsState.updatePermissionFlags(bp, userId,
5221                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5222                        }
5223
5224                    } break;
5225                }
5226            }
5227        }
5228
5229        private void writePermissions(XmlSerializer serializer,
5230                List<PermissionState> permissionStates) throws IOException {
5231            for (PermissionState permissionState : permissionStates) {
5232                serializer.startTag(null, TAG_ITEM);
5233                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5234                serializer.attribute(null, ATTR_GRANTED,
5235                        String.valueOf(permissionState.isGranted()));
5236                serializer.attribute(null, ATTR_FLAGS,
5237                        Integer.toHexString(permissionState.getFlags()));
5238                serializer.endTag(null, TAG_ITEM);
5239            }
5240        }
5241
5242        private final class MyHandler extends Handler {
5243            public MyHandler() {
5244                super(BackgroundThread.getHandler().getLooper());
5245            }
5246
5247            @Override
5248            public void handleMessage(Message message) {
5249                final int userId = message.what;
5250                Runnable callback = (Runnable) message.obj;
5251                writePermissionsSync(userId);
5252                if (callback != null) {
5253                    callback.run();
5254                }
5255            }
5256        }
5257    }
5258}
5259