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