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