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