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