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