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