Settings.java revision 36ecd08dc1627a7ed9c0ef498b41c40a66d646b0
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            writePackageRestrictionsLPr(userHandle);
4000            writePackageListLPr(userHandle);
4001        }
4002    }
4003
4004    void removeUserLPw(int userId) {
4005        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
4006        for (Entry<String, PackageSetting> entry : entries) {
4007            entry.getValue().removeUser(userId);
4008        }
4009        mPreferredActivities.remove(userId);
4010        File file = getUserPackagesStateFile(userId);
4011        file.delete();
4012        file = getUserPackagesStateBackupFile(userId);
4013        file.delete();
4014        removeCrossProfileIntentFiltersLPw(userId);
4015
4016        mRuntimePermissionsPersistence.onUserRemoved(userId);
4017
4018        writePackageListLPr();
4019    }
4020
4021    void removeCrossProfileIntentFiltersLPw(int userId) {
4022        synchronized (mCrossProfileIntentResolvers) {
4023            // userId is the source user
4024            if (mCrossProfileIntentResolvers.get(userId) != null) {
4025                mCrossProfileIntentResolvers.remove(userId);
4026                writePackageRestrictionsLPr(userId);
4027            }
4028            // userId is the target user
4029            int count = mCrossProfileIntentResolvers.size();
4030            for (int i = 0; i < count; i++) {
4031                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
4032                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
4033                boolean needsWriting = false;
4034                ArraySet<CrossProfileIntentFilter> cpifs =
4035                        new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
4036                for (CrossProfileIntentFilter cpif : cpifs) {
4037                    if (cpif.getTargetUserId() == userId) {
4038                        needsWriting = true;
4039                        cpir.removeFilter(cpif);
4040                    }
4041                }
4042                if (needsWriting) {
4043                    writePackageRestrictionsLPr(sourceUserId);
4044                }
4045            }
4046        }
4047    }
4048
4049    // This should be called (at least) whenever an application is removed
4050    private void setFirstAvailableUid(int uid) {
4051        if (uid > mFirstAvailableUid) {
4052            mFirstAvailableUid = uid;
4053        }
4054    }
4055
4056    // Returns -1 if we could not find an available UserId to assign
4057    private int newUserIdLPw(Object obj) {
4058        // Let's be stupidly inefficient for now...
4059        final int N = mUserIds.size();
4060        for (int i = mFirstAvailableUid; i < N; i++) {
4061            if (mUserIds.get(i) == null) {
4062                mUserIds.set(i, obj);
4063                return Process.FIRST_APPLICATION_UID + i;
4064            }
4065        }
4066
4067        // None left?
4068        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
4069            return -1;
4070        }
4071
4072        mUserIds.add(obj);
4073        return Process.FIRST_APPLICATION_UID + N;
4074    }
4075
4076    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
4077        if (mVerifierDeviceIdentity == null) {
4078            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
4079
4080            writeLPr();
4081        }
4082
4083        return mVerifierDeviceIdentity;
4084    }
4085
4086    public boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
4087            String childPackageName) {
4088        final int packageCount = mDisabledSysPackages.size();
4089        for (int i = 0; i < packageCount; i++) {
4090            PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
4091            if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
4092                continue;
4093            }
4094            if (disabledPs.name.equals(parentPackageName)) {
4095                continue;
4096            }
4097            final int childCount = disabledPs.childPackageNames.size();
4098            for (int j = 0; j < childCount; j++) {
4099                String currChildPackageName = disabledPs.childPackageNames.get(j);
4100                if (currChildPackageName.equals(childPackageName)) {
4101                    return true;
4102                }
4103            }
4104        }
4105        return false;
4106    }
4107
4108    public PackageSetting getDisabledSystemPkgLPr(String name) {
4109        PackageSetting ps = mDisabledSysPackages.get(name);
4110        return ps;
4111    }
4112
4113    private String compToString(ArraySet<String> cmp) {
4114        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
4115    }
4116
4117    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
4118        final PackageSetting ps = mPackages.get(componentInfo.packageName);
4119        if (ps == null) return false;
4120
4121        final PackageUserState userState = ps.readUserState(userId);
4122        return userState.isMatch(componentInfo, flags);
4123    }
4124
4125    String getInstallerPackageNameLPr(String packageName) {
4126        final PackageSetting pkg = mPackages.get(packageName);
4127        if (pkg == null) {
4128            throw new IllegalArgumentException("Unknown package: " + packageName);
4129        }
4130        return pkg.installerPackageName;
4131    }
4132
4133    boolean isOrphaned(String packageName) {
4134        final PackageSetting pkg = mPackages.get(packageName);
4135        if (pkg == null) {
4136            throw new IllegalArgumentException("Unknown package: " + packageName);
4137        }
4138        return pkg.isOrphaned;
4139    }
4140
4141    int getApplicationEnabledSettingLPr(String packageName, int userId) {
4142        final PackageSetting pkg = mPackages.get(packageName);
4143        if (pkg == null) {
4144            throw new IllegalArgumentException("Unknown package: " + packageName);
4145        }
4146        return pkg.getEnabled(userId);
4147    }
4148
4149    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
4150        final String packageName = componentName.getPackageName();
4151        final PackageSetting pkg = mPackages.get(packageName);
4152        if (pkg == null) {
4153            throw new IllegalArgumentException("Unknown component: " + componentName);
4154        }
4155        final String classNameStr = componentName.getClassName();
4156        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
4157    }
4158
4159    boolean setPackageStoppedStateLPw(PackageManagerService pm, String packageName,
4160            boolean stopped, boolean allowedByPermission, int uid, int userId) {
4161        int appId = UserHandle.getAppId(uid);
4162        final PackageSetting pkgSetting = mPackages.get(packageName);
4163        if (pkgSetting == null) {
4164            throw new IllegalArgumentException("Unknown package: " + packageName);
4165        }
4166        if (!allowedByPermission && (appId != pkgSetting.appId)) {
4167            throw new SecurityException(
4168                    "Permission Denial: attempt to change stopped state from pid="
4169                    + Binder.getCallingPid()
4170                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
4171        }
4172        if (DEBUG_STOPPED) {
4173            if (stopped) {
4174                RuntimeException e = new RuntimeException("here");
4175                e.fillInStackTrace();
4176                Slog.i(TAG, "Stopping package " + packageName, e);
4177            }
4178        }
4179        if (pkgSetting.getStopped(userId) != stopped) {
4180            pkgSetting.setStopped(stopped, userId);
4181            // pkgSetting.pkg.mSetStopped = stopped;
4182            if (pkgSetting.getNotLaunched(userId)) {
4183                if (pkgSetting.installerPackageName != null) {
4184                    pm.notifyFirstLaunch(pkgSetting.name, pkgSetting.installerPackageName, userId);
4185                }
4186                pkgSetting.setNotLaunched(false, userId);
4187            }
4188            return true;
4189        }
4190        return false;
4191    }
4192
4193    List<UserInfo> getAllUsers() {
4194        long id = Binder.clearCallingIdentity();
4195        try {
4196            return UserManagerService.getInstance().getUsers(false);
4197        } catch (NullPointerException npe) {
4198            // packagemanager not yet initialized
4199        } finally {
4200            Binder.restoreCallingIdentity(id);
4201        }
4202        return null;
4203    }
4204
4205    /**
4206     * Return all {@link PackageSetting} that are actively installed on the
4207     * given {@link VolumeInfo#fsUuid}.
4208     */
4209    List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
4210        ArrayList<PackageSetting> res = new ArrayList<>();
4211        for (int i = 0; i < mPackages.size(); i++) {
4212            final PackageSetting setting = mPackages.valueAt(i);
4213            if (Objects.equals(volumeUuid, setting.volumeUuid)) {
4214                res.add(setting);
4215            }
4216        }
4217        return res;
4218    }
4219
4220    static void printFlags(PrintWriter pw, int val, Object[] spec) {
4221        pw.print("[ ");
4222        for (int i=0; i<spec.length; i+=2) {
4223            int mask = (Integer)spec[i];
4224            if ((val & mask) != 0) {
4225                pw.print(spec[i+1]);
4226                pw.print(" ");
4227            }
4228        }
4229        pw.print("]");
4230    }
4231
4232    static final Object[] FLAG_DUMP_SPEC = new Object[] {
4233        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4234        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4235        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4236        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4237        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4238        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4239        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4240        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4241        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4242        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4243        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4244        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4245        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4246        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4247        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4248    };
4249
4250    static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4251        ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN",
4252        ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4253        ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK",
4254        ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4255        ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
4256        ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
4257        ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
4258        ApplicationInfo.PRIVATE_FLAG_AUTOPLAY, "AUTOPLAY",
4259        ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
4260        ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL",
4261        ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
4262        ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES, "RESIZEABLE_ACTIVITIES",
4263        ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
4264    };
4265
4266    void dumpVersionLPr(IndentingPrintWriter pw) {
4267        pw.increaseIndent();
4268        for (int i= 0; i < mVersion.size(); i++) {
4269            final String volumeUuid = mVersion.keyAt(i);
4270            final VersionInfo ver = mVersion.valueAt(i);
4271            if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4272                pw.println("Internal:");
4273            } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4274                pw.println("External:");
4275            } else {
4276                pw.println("UUID " + volumeUuid + ":");
4277            }
4278            pw.increaseIndent();
4279            pw.printPair("sdkVersion", ver.sdkVersion);
4280            pw.printPair("databaseVersion", ver.databaseVersion);
4281            pw.println();
4282            pw.printPair("fingerprint", ver.fingerprint);
4283            pw.println();
4284            pw.decreaseIndent();
4285        }
4286        pw.decreaseIndent();
4287    }
4288
4289    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4290            ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4291            Date date, List<UserInfo> users, boolean dumpAll) {
4292        if (checkinTag != null) {
4293            pw.print(checkinTag);
4294            pw.print(",");
4295            pw.print(ps.realName != null ? ps.realName : ps.name);
4296            pw.print(",");
4297            pw.print(ps.appId);
4298            pw.print(",");
4299            pw.print(ps.versionCode);
4300            pw.print(",");
4301            pw.print(ps.firstInstallTime);
4302            pw.print(",");
4303            pw.print(ps.lastUpdateTime);
4304            pw.print(",");
4305            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4306            pw.println();
4307            if (ps.pkg != null) {
4308                pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4309                pw.print("base,");
4310                pw.println(ps.pkg.baseRevisionCode);
4311                if (ps.pkg.splitNames != null) {
4312                    for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4313                        pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4314                        pw.print(ps.pkg.splitNames[i]); pw.print(",");
4315                        pw.println(ps.pkg.splitRevisionCodes[i]);
4316                    }
4317                }
4318            }
4319            for (UserInfo user : users) {
4320                pw.print(checkinTag);
4321                pw.print("-");
4322                pw.print("usr");
4323                pw.print(",");
4324                pw.print(user.id);
4325                pw.print(",");
4326                pw.print(ps.getInstalled(user.id) ? "I" : "i");
4327                pw.print(ps.getHidden(user.id) ? "B" : "b");
4328                pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4329                pw.print(ps.getStopped(user.id) ? "S" : "s");
4330                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4331                pw.print(",");
4332                pw.print(ps.getEnabled(user.id));
4333                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4334                pw.print(",");
4335                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4336                pw.println();
4337            }
4338            return;
4339        }
4340
4341        pw.print(prefix); pw.print("Package [");
4342            pw.print(ps.realName != null ? ps.realName : ps.name);
4343            pw.print("] (");
4344            pw.print(Integer.toHexString(System.identityHashCode(ps)));
4345            pw.println("):");
4346
4347        if (ps.realName != null) {
4348            pw.print(prefix); pw.print("  compat name=");
4349            pw.println(ps.name);
4350        }
4351
4352        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4353
4354        if (ps.sharedUser != null) {
4355            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4356        }
4357        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4358        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4359        if (permissionNames == null) {
4360            pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4361            pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4362            pw.println(ps.legacyNativeLibraryPathString);
4363            pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4364            pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4365        }
4366        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4367        if (ps.pkg != null) {
4368            pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion);
4369            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4370        }
4371        pw.println();
4372        if (ps.pkg != null) {
4373            if (ps.pkg.parentPackage != null) {
4374                PackageParser.Package parentPkg = ps.pkg.parentPackage;
4375                PackageSetting pps = mPackages.get(parentPkg.packageName);
4376                if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
4377                    pps = mDisabledSysPackages.get(parentPkg.packageName);
4378                }
4379                if (pps != null) {
4380                    pw.print(prefix); pw.print("  parentPackage=");
4381                    pw.println(pps.realName != null ? pps.realName : pps.name);
4382                }
4383            } else if (ps.pkg.childPackages != null) {
4384                pw.print(prefix); pw.print("  childPackages=[");
4385                final int childCount = ps.pkg.childPackages.size();
4386                for (int i = 0; i < childCount; i++) {
4387                    PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
4388                    PackageSetting cps = mPackages.get(childPkg.packageName);
4389                    if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
4390                        cps = mDisabledSysPackages.get(childPkg.packageName);
4391                    }
4392                    if (cps != null) {
4393                        if (i > 0) {
4394                            pw.print(", ");
4395                        }
4396                        pw.print(cps.realName != null ? cps.realName : cps.name);
4397                    }
4398                }
4399                pw.println("]");
4400            }
4401            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4402            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4403            final int apkSigningVersion = PackageParser.getApkSigningVersion(ps.pkg);
4404            if (apkSigningVersion != PackageParser.APK_SIGNING_UNKNOWN) {
4405                pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
4406            }
4407            pw.print(prefix); pw.print("  applicationInfo=");
4408                pw.println(ps.pkg.applicationInfo.toString());
4409            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4410                    FLAG_DUMP_SPEC); pw.println();
4411            if (ps.pkg.applicationInfo.privateFlags != 0) {
4412                pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4413                        ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4414            }
4415            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4416            pw.print(prefix); pw.print("  supportsScreens=[");
4417            boolean first = true;
4418            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4419                if (!first)
4420                    pw.print(", ");
4421                first = false;
4422                pw.print("small");
4423            }
4424            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4425                if (!first)
4426                    pw.print(", ");
4427                first = false;
4428                pw.print("medium");
4429            }
4430            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4431                if (!first)
4432                    pw.print(", ");
4433                first = false;
4434                pw.print("large");
4435            }
4436            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4437                if (!first)
4438                    pw.print(", ");
4439                first = false;
4440                pw.print("xlarge");
4441            }
4442            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4443                if (!first)
4444                    pw.print(", ");
4445                first = false;
4446                pw.print("resizeable");
4447            }
4448            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4449                if (!first)
4450                    pw.print(", ");
4451                first = false;
4452                pw.print("anyDensity");
4453            }
4454            pw.println("]");
4455            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4456                pw.print(prefix); pw.println("  libraries:");
4457                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
4458                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
4459                }
4460            }
4461            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4462                pw.print(prefix); pw.println("  usesLibraries:");
4463                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4464                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4465                }
4466            }
4467            if (ps.pkg.usesOptionalLibraries != null
4468                    && ps.pkg.usesOptionalLibraries.size() > 0) {
4469                pw.print(prefix); pw.println("  usesOptionalLibraries:");
4470                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4471                    pw.print(prefix); pw.print("    ");
4472                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
4473                }
4474            }
4475            if (ps.pkg.usesLibraryFiles != null
4476                    && ps.pkg.usesLibraryFiles.length > 0) {
4477                pw.print(prefix); pw.println("  usesLibraryFiles:");
4478                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4479                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4480                }
4481            }
4482        }
4483        pw.print(prefix); pw.print("  timeStamp=");
4484            date.setTime(ps.timeStamp);
4485            pw.println(sdf.format(date));
4486        pw.print(prefix); pw.print("  firstInstallTime=");
4487            date.setTime(ps.firstInstallTime);
4488            pw.println(sdf.format(date));
4489        pw.print(prefix); pw.print("  lastUpdateTime=");
4490            date.setTime(ps.lastUpdateTime);
4491            pw.println(sdf.format(date));
4492        if (ps.installerPackageName != null) {
4493            pw.print(prefix); pw.print("  installerPackageName=");
4494                    pw.println(ps.installerPackageName);
4495        }
4496        if (ps.volumeUuid != null) {
4497            pw.print(prefix); pw.print("  volumeUuid=");
4498                    pw.println(ps.volumeUuid);
4499        }
4500        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4501        pw.print(prefix); pw.print("  installPermissionsFixed=");
4502                pw.print(ps.installPermissionsFixed);
4503                pw.print(" installStatus="); pw.println(ps.installStatus);
4504        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4505                pw.println();
4506
4507        if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4508            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4509            pw.print(prefix); pw.println("  declared permissions:");
4510            for (int i=0; i<perms.size(); i++) {
4511                PackageParser.Permission perm = perms.get(i);
4512                if (permissionNames != null
4513                        && !permissionNames.contains(perm.info.name)) {
4514                    continue;
4515                }
4516                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4517                pw.print(": prot=");
4518                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4519                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4520                    pw.print(", COSTS_MONEY");
4521                }
4522                if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4523                    pw.print(", HIDDEN");
4524                }
4525                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4526                    pw.print(", INSTALLED");
4527                }
4528                pw.println();
4529            }
4530        }
4531
4532        if ((permissionNames != null || dumpAll) && ps.pkg != null
4533                && ps.pkg.requestedPermissions != null
4534                && ps.pkg.requestedPermissions.size() > 0) {
4535            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4536            pw.print(prefix); pw.println("  requested permissions:");
4537            for (int i=0; i<perms.size(); i++) {
4538                String perm = perms.get(i);
4539                if (permissionNames != null
4540                        && !permissionNames.contains(perm)) {
4541                    continue;
4542                }
4543                pw.print(prefix); pw.print("    "); pw.println(perm);
4544            }
4545        }
4546
4547        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4548            PermissionsState permissionsState = ps.getPermissionsState();
4549            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4550        }
4551
4552        for (UserInfo user : users) {
4553            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4554            pw.print("ceDataInode=");
4555            pw.print(ps.getCeDataInode(user.id));
4556            pw.print(" installed=");
4557            pw.print(ps.getInstalled(user.id));
4558            pw.print(" hidden=");
4559            pw.print(ps.getHidden(user.id));
4560            pw.print(" suspended=");
4561            pw.print(ps.getSuspended(user.id));
4562            pw.print(" stopped=");
4563            pw.print(ps.getStopped(user.id));
4564            pw.print(" notLaunched=");
4565            pw.print(ps.getNotLaunched(user.id));
4566            pw.print(" enabled=");
4567            pw.println(ps.getEnabled(user.id));
4568            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4569            if (lastDisabledAppCaller != null) {
4570                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4571                        pw.println(lastDisabledAppCaller);
4572            }
4573
4574            if (ps.sharedUser == null) {
4575                PermissionsState permissionsState = ps.getPermissionsState();
4576                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4577                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4578                        .getRuntimePermissionStates(user.id), dumpAll);
4579            }
4580
4581            if (permissionNames == null) {
4582                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4583                if (cmp != null && cmp.size() > 0) {
4584                    pw.print(prefix); pw.println("    disabledComponents:");
4585                    for (String s : cmp) {
4586                        pw.print(prefix); pw.print("      "); pw.println(s);
4587                    }
4588                }
4589                cmp = ps.getEnabledComponents(user.id);
4590                if (cmp != null && cmp.size() > 0) {
4591                    pw.print(prefix); pw.println("    enabledComponents:");
4592                    for (String s : cmp) {
4593                        pw.print(prefix); pw.print("      "); pw.println(s);
4594                    }
4595                }
4596            }
4597        }
4598    }
4599
4600    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4601            DumpState dumpState, boolean checkin) {
4602        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4603        final Date date = new Date();
4604        boolean printedSomething = false;
4605        List<UserInfo> users = getAllUsers();
4606        for (final PackageSetting ps : mPackages.values()) {
4607            if (packageName != null && !packageName.equals(ps.realName)
4608                    && !packageName.equals(ps.name)) {
4609                continue;
4610            }
4611            if (permissionNames != null
4612                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4613                continue;
4614            }
4615
4616            if (!checkin && packageName != null) {
4617                dumpState.setSharedUser(ps.sharedUser);
4618            }
4619
4620            if (!checkin && !printedSomething) {
4621                if (dumpState.onTitlePrinted())
4622                    pw.println();
4623                pw.println("Packages:");
4624                printedSomething = true;
4625            }
4626            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4627                    packageName != null);
4628        }
4629
4630        printedSomething = false;
4631        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4632            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4633                if (packageName != null && !packageName.equals(e.getKey())
4634                        && !packageName.equals(e.getValue())) {
4635                    continue;
4636                }
4637                if (!checkin) {
4638                    if (!printedSomething) {
4639                        if (dumpState.onTitlePrinted())
4640                            pw.println();
4641                        pw.println("Renamed packages:");
4642                        printedSomething = true;
4643                    }
4644                    pw.print("  ");
4645                } else {
4646                    pw.print("ren,");
4647                }
4648                pw.print(e.getKey());
4649                pw.print(checkin ? " -> " : ",");
4650                pw.println(e.getValue());
4651            }
4652        }
4653
4654        printedSomething = false;
4655        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4656            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4657                if (packageName != null && !packageName.equals(ps.realName)
4658                        && !packageName.equals(ps.name)) {
4659                    continue;
4660                }
4661                if (!checkin && !printedSomething) {
4662                    if (dumpState.onTitlePrinted())
4663                        pw.println();
4664                    pw.println("Hidden system packages:");
4665                    printedSomething = true;
4666                }
4667                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4668                        users, packageName != null);
4669            }
4670        }
4671    }
4672
4673    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4674            DumpState dumpState) {
4675        boolean printedSomething = false;
4676        for (BasePermission p : mPermissions.values()) {
4677            if (packageName != null && !packageName.equals(p.sourcePackage)) {
4678                continue;
4679            }
4680            if (permissionNames != null && !permissionNames.contains(p.name)) {
4681                continue;
4682            }
4683            if (!printedSomething) {
4684                if (dumpState.onTitlePrinted())
4685                    pw.println();
4686                pw.println("Permissions:");
4687                printedSomething = true;
4688            }
4689            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
4690                    pw.print(Integer.toHexString(System.identityHashCode(p)));
4691                    pw.println("):");
4692            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
4693            pw.print("    uid="); pw.print(p.uid);
4694                    pw.print(" gids="); pw.print(Arrays.toString(
4695                            p.computeGids(UserHandle.USER_SYSTEM)));
4696                    pw.print(" type="); pw.print(p.type);
4697                    pw.print(" prot=");
4698                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
4699            if (p.perm != null) {
4700                pw.print("    perm="); pw.println(p.perm);
4701                if ((p.perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0
4702                        || (p.perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0) {
4703                    pw.print("    flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags));
4704                }
4705            }
4706            if (p.packageSetting != null) {
4707                pw.print("    packageSetting="); pw.println(p.packageSetting);
4708            }
4709            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
4710                pw.print("    enforced=");
4711                pw.println(mReadExternalStorageEnforced);
4712            }
4713        }
4714    }
4715
4716    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4717            DumpState dumpState, boolean checkin) {
4718        boolean printedSomething = false;
4719        for (SharedUserSetting su : mSharedUsers.values()) {
4720            if (packageName != null && su != dumpState.getSharedUser()) {
4721                continue;
4722            }
4723            if (permissionNames != null
4724                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4725                continue;
4726            }
4727            if (!checkin) {
4728                if (!printedSomething) {
4729                    if (dumpState.onTitlePrinted())
4730                        pw.println();
4731                    pw.println("Shared users:");
4732                    printedSomething = true;
4733                }
4734                pw.print("  SharedUser [");
4735                pw.print(su.name);
4736                pw.print("] (");
4737                pw.print(Integer.toHexString(System.identityHashCode(su)));
4738                        pw.println("):");
4739
4740                String prefix = "    ";
4741                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4742
4743                PermissionsState permissionsState = su.getPermissionsState();
4744                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4745
4746                for (int userId : UserManagerService.getInstance().getUserIds()) {
4747                    final int[] gids = permissionsState.computeGids(userId);
4748                    List<PermissionState> permissions = permissionsState
4749                            .getRuntimePermissionStates(userId);
4750                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4751                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4752                        dumpGidsLPr(pw, prefix + "  ", gids);
4753                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4754                                packageName != null);
4755                    }
4756                }
4757            } else {
4758                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4759            }
4760        }
4761    }
4762
4763    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4764        pw.println("Settings parse messages:");
4765        pw.print(mReadMessages.toString());
4766    }
4767
4768    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4769        if (mRestoredUserGrants.size() > 0) {
4770            pw.println();
4771            pw.println("Restored (pending) permission grants:");
4772            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4773                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4774                        mRestoredUserGrants.valueAt(userIndex);
4775                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4776                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4777                    pw.print("  User "); pw.println(userId);
4778
4779                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4780                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4781                        if (grants != null && grants.size() > 0) {
4782                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4783                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4784
4785                            for (RestoredPermissionGrant g : grants) {
4786                                pw.print("      ");
4787                                pw.print(g.permissionName);
4788                                if (g.granted) {
4789                                    pw.print(" GRANTED");
4790                                }
4791                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4792                                    pw.print(" user_set");
4793                                }
4794                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4795                                    pw.print(" user_fixed");
4796                                }
4797                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4798                                    pw.print(" revoke_on_upgrade");
4799                                }
4800                                pw.println();
4801                            }
4802                        }
4803                    }
4804                }
4805            }
4806            pw.println();
4807        }
4808    }
4809
4810    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4811        if (pkg == null) {
4812            pw.print("unknown");
4813        } else {
4814            // [base:10, config.mdpi, config.xhdpi:12]
4815            pw.print("[");
4816            pw.print("base");
4817            if (pkg.baseRevisionCode != 0) {
4818                pw.print(":"); pw.print(pkg.baseRevisionCode);
4819            }
4820            if (pkg.splitNames != null) {
4821                for (int i = 0; i < pkg.splitNames.length; i++) {
4822                    pw.print(", ");
4823                    pw.print(pkg.splitNames[i]);
4824                    if (pkg.splitRevisionCodes[i] != 0) {
4825                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4826                    }
4827                }
4828            }
4829            pw.print("]");
4830        }
4831    }
4832
4833    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4834        if (!ArrayUtils.isEmpty(gids)) {
4835            pw.print(prefix);
4836            pw.print("gids="); pw.println(
4837                    PackageManagerService.arrayToString(gids));
4838        }
4839    }
4840
4841    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4842            List<PermissionState> permissionStates, boolean dumpAll) {
4843        if (!permissionStates.isEmpty() || dumpAll) {
4844            pw.print(prefix); pw.println("runtime permissions:");
4845            for (PermissionState permissionState : permissionStates) {
4846                if (permissionNames != null
4847                        && !permissionNames.contains(permissionState.getName())) {
4848                    continue;
4849                }
4850                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4851                pw.print(": granted="); pw.print(permissionState.isGranted());
4852                    pw.println(permissionFlagsToString(", flags=",
4853                            permissionState.getFlags()));
4854            }
4855        }
4856    }
4857
4858    private static String permissionFlagsToString(String prefix, int flags) {
4859        StringBuilder flagsString = null;
4860        while (flags != 0) {
4861            if (flagsString == null) {
4862                flagsString = new StringBuilder();
4863                flagsString.append(prefix);
4864                flagsString.append("[ ");
4865            }
4866            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4867            flags &= ~flag;
4868            flagsString.append(PackageManager.permissionFlagToString(flag));
4869            flagsString.append(' ');
4870        }
4871        if (flagsString != null) {
4872            flagsString.append(']');
4873            return flagsString.toString();
4874        } else {
4875            return "";
4876        }
4877    }
4878
4879    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4880            PermissionsState permissionsState) {
4881        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
4882        if (!permissionStates.isEmpty()) {
4883            pw.print(prefix); pw.println("install permissions:");
4884            for (PermissionState permissionState : permissionStates) {
4885                if (permissionNames != null
4886                        && !permissionNames.contains(permissionState.getName())) {
4887                    continue;
4888                }
4889                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4890                    pw.print(": granted="); pw.print(permissionState.isGranted());
4891                    pw.println(permissionFlagsToString(", flags=",
4892                        permissionState.getFlags()));
4893            }
4894        }
4895    }
4896
4897    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
4898        if (sync) {
4899            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
4900        } else {
4901            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
4902        }
4903    }
4904
4905    private final class RuntimePermissionPersistence {
4906        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
4907        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
4908
4909        private final Handler mHandler = new MyHandler();
4910
4911        private final Object mLock;
4912
4913        @GuardedBy("mLock")
4914        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
4915
4916        @GuardedBy("mLock")
4917        // The mapping keys are user ids.
4918        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
4919
4920        @GuardedBy("mLock")
4921        // The mapping keys are user ids.
4922        private final SparseArray<String> mFingerprints = new SparseArray<>();
4923
4924        @GuardedBy("mLock")
4925        // The mapping keys are user ids.
4926        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
4927
4928        public RuntimePermissionPersistence(Object lock) {
4929            mLock = lock;
4930        }
4931
4932        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
4933            return mDefaultPermissionsGranted.get(userId);
4934        }
4935
4936        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
4937            mFingerprints.put(userId, Build.FINGERPRINT);
4938            writePermissionsForUserAsyncLPr(userId);
4939        }
4940
4941        public void writePermissionsForUserSyncLPr(int userId) {
4942            mHandler.removeMessages(userId);
4943            writePermissionsSync(userId);
4944        }
4945
4946        public void writePermissionsForUserAsyncLPr(int userId) {
4947            final long currentTimeMillis = SystemClock.uptimeMillis();
4948
4949            if (mWriteScheduled.get(userId)) {
4950                mHandler.removeMessages(userId);
4951
4952                // If enough time passed, write without holding off anymore.
4953                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
4954                        .get(userId);
4955                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
4956                        - lastNotWrittenMutationTimeMillis;
4957                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
4958                    mHandler.obtainMessage(userId).sendToTarget();
4959                    return;
4960                }
4961
4962                // Hold off a bit more as settings are frequently changing.
4963                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
4964                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
4965                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
4966                        maxDelayMillis);
4967
4968                Message message = mHandler.obtainMessage(userId);
4969                mHandler.sendMessageDelayed(message, writeDelayMillis);
4970            } else {
4971                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
4972                Message message = mHandler.obtainMessage(userId);
4973                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
4974                mWriteScheduled.put(userId, true);
4975            }
4976        }
4977
4978        private void writePermissionsSync(int userId) {
4979            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
4980
4981            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
4982            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
4983
4984            synchronized (mLock) {
4985                mWriteScheduled.delete(userId);
4986
4987                final int packageCount = mPackages.size();
4988                for (int i = 0; i < packageCount; i++) {
4989                    String packageName = mPackages.keyAt(i);
4990                    PackageSetting packageSetting = mPackages.valueAt(i);
4991                    if (packageSetting.sharedUser == null) {
4992                        PermissionsState permissionsState = packageSetting.getPermissionsState();
4993                        List<PermissionState> permissionsStates = permissionsState
4994                                .getRuntimePermissionStates(userId);
4995                        if (!permissionsStates.isEmpty()) {
4996                            permissionsForPackage.put(packageName, permissionsStates);
4997                        }
4998                    }
4999                }
5000
5001                final int sharedUserCount = mSharedUsers.size();
5002                for (int i = 0; i < sharedUserCount; i++) {
5003                    String sharedUserName = mSharedUsers.keyAt(i);
5004                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
5005                    PermissionsState permissionsState = sharedUser.getPermissionsState();
5006                    List<PermissionState> permissionsStates = permissionsState
5007                            .getRuntimePermissionStates(userId);
5008                    if (!permissionsStates.isEmpty()) {
5009                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
5010                    }
5011                }
5012            }
5013
5014            FileOutputStream out = null;
5015            try {
5016                out = destination.startWrite();
5017
5018                XmlSerializer serializer = Xml.newSerializer();
5019                serializer.setOutput(out, StandardCharsets.UTF_8.name());
5020                serializer.setFeature(
5021                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
5022                serializer.startDocument(null, true);
5023
5024                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
5025
5026                String fingerprint = mFingerprints.get(userId);
5027                if (fingerprint != null) {
5028                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
5029                }
5030
5031                final int packageCount = permissionsForPackage.size();
5032                for (int i = 0; i < packageCount; i++) {
5033                    String packageName = permissionsForPackage.keyAt(i);
5034                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
5035                    serializer.startTag(null, TAG_PACKAGE);
5036                    serializer.attribute(null, ATTR_NAME, packageName);
5037                    writePermissions(serializer, permissionStates);
5038                    serializer.endTag(null, TAG_PACKAGE);
5039                }
5040
5041                final int sharedUserCount = permissionsForSharedUser.size();
5042                for (int i = 0; i < sharedUserCount; i++) {
5043                    String packageName = permissionsForSharedUser.keyAt(i);
5044                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
5045                    serializer.startTag(null, TAG_SHARED_USER);
5046                    serializer.attribute(null, ATTR_NAME, packageName);
5047                    writePermissions(serializer, permissionStates);
5048                    serializer.endTag(null, TAG_SHARED_USER);
5049                }
5050
5051                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
5052
5053                // Now any restored permission grants that are waiting for the apps
5054                // in question to be installed.  These are stored as per-package
5055                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
5056                // number of individual permission grant entities.
5057                if (mRestoredUserGrants.get(userId) != null) {
5058                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
5059                            mRestoredUserGrants.get(userId);
5060                    if (restoredGrants != null) {
5061                        final int pkgCount = restoredGrants.size();
5062                        for (int i = 0; i < pkgCount; i++) {
5063                            final ArraySet<RestoredPermissionGrant> pkgGrants =
5064                                    restoredGrants.valueAt(i);
5065                            if (pkgGrants != null && pkgGrants.size() > 0) {
5066                                final String pkgName = restoredGrants.keyAt(i);
5067                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5068                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
5069
5070                                final int N = pkgGrants.size();
5071                                for (int z = 0; z < N; z++) {
5072                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
5073                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
5074                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
5075
5076                                    if (g.granted) {
5077                                        serializer.attribute(null, ATTR_GRANTED, "true");
5078                                    }
5079
5080                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
5081                                        serializer.attribute(null, ATTR_USER_SET, "true");
5082                                    }
5083                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
5084                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
5085                                    }
5086                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
5087                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
5088                                    }
5089                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
5090                                }
5091                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5092                            }
5093                        }
5094                    }
5095                }
5096
5097                serializer.endDocument();
5098                destination.finishWrite(out);
5099
5100                if (Build.FINGERPRINT.equals(fingerprint)) {
5101                    mDefaultPermissionsGranted.put(userId, true);
5102                }
5103            // Any error while writing is fatal.
5104            } catch (Throwable t) {
5105                Slog.wtf(PackageManagerService.TAG,
5106                        "Failed to write settings, restoring backup", t);
5107                destination.failWrite(out);
5108            } finally {
5109                IoUtils.closeQuietly(out);
5110            }
5111        }
5112
5113        private void onUserRemoved(int userId) {
5114            // Make sure we do not
5115            mHandler.removeMessages(userId);
5116
5117            for (SettingBase sb : mPackages.values()) {
5118                revokeRuntimePermissionsAndClearFlags(sb, userId);
5119            }
5120
5121            for (SettingBase sb : mSharedUsers.values()) {
5122                revokeRuntimePermissionsAndClearFlags(sb, userId);
5123            }
5124        }
5125
5126        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5127            PermissionsState permissionsState = sb.getPermissionsState();
5128            for (PermissionState permissionState
5129                    : permissionsState.getRuntimePermissionStates(userId)) {
5130                BasePermission bp = mPermissions.get(permissionState.getName());
5131                if (bp != null) {
5132                    permissionsState.revokeRuntimePermission(bp, userId);
5133                    permissionsState.updatePermissionFlags(bp, userId,
5134                            PackageManager.MASK_PERMISSION_FLAGS, 0);
5135                }
5136            }
5137        }
5138
5139        public void deleteUserRuntimePermissionsFile(int userId) {
5140            getUserRuntimePermissionsFile(userId).delete();
5141        }
5142
5143        public void readStateForUserSyncLPr(int userId) {
5144            File permissionsFile = getUserRuntimePermissionsFile(userId);
5145            if (!permissionsFile.exists()) {
5146                return;
5147            }
5148
5149            FileInputStream in;
5150            try {
5151                in = new AtomicFile(permissionsFile).openRead();
5152            } catch (FileNotFoundException fnfe) {
5153                Slog.i(PackageManagerService.TAG, "No permissions state");
5154                return;
5155            }
5156
5157            try {
5158                XmlPullParser parser = Xml.newPullParser();
5159                parser.setInput(in, null);
5160                parseRuntimePermissionsLPr(parser, userId);
5161
5162            } catch (XmlPullParserException | IOException e) {
5163                throw new IllegalStateException("Failed parsing permissions file: "
5164                        + permissionsFile , e);
5165            } finally {
5166                IoUtils.closeQuietly(in);
5167            }
5168        }
5169
5170        // Backup/restore support
5171
5172        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
5173                boolean isGranted, int restoredFlagSet, int userId) {
5174            // This change will be remembered at write-settings time
5175            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
5176                    mRestoredUserGrants.get(userId);
5177            if (grantsByPackage == null) {
5178                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
5179                mRestoredUserGrants.put(userId, grantsByPackage);
5180            }
5181
5182            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
5183            if (grants == null) {
5184                grants = new ArraySet<RestoredPermissionGrant>();
5185                grantsByPackage.put(pkgName, grants);
5186            }
5187
5188            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
5189                    isGranted, restoredFlagSet);
5190            grants.add(grant);
5191        }
5192
5193        // Private internals
5194
5195        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5196                throws IOException, XmlPullParserException {
5197            final int outerDepth = parser.getDepth();
5198            int type;
5199            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5200                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5201                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5202                    continue;
5203                }
5204
5205                switch (parser.getName()) {
5206                    case TAG_RUNTIME_PERMISSIONS: {
5207                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5208                        mFingerprints.put(userId, fingerprint);
5209                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5210                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
5211                    } break;
5212
5213                    case TAG_PACKAGE: {
5214                        String name = parser.getAttributeValue(null, ATTR_NAME);
5215                        PackageSetting ps = mPackages.get(name);
5216                        if (ps == null) {
5217                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5218                            XmlUtils.skipCurrentTag(parser);
5219                            continue;
5220                        }
5221                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5222                    } break;
5223
5224                    case TAG_SHARED_USER: {
5225                        String name = parser.getAttributeValue(null, ATTR_NAME);
5226                        SharedUserSetting sus = mSharedUsers.get(name);
5227                        if (sus == null) {
5228                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5229                            XmlUtils.skipCurrentTag(parser);
5230                            continue;
5231                        }
5232                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5233                    } break;
5234
5235                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
5236                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
5237                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
5238                    } break;
5239                }
5240            }
5241        }
5242
5243        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
5244                final String pkgName, final int userId) throws IOException, XmlPullParserException {
5245            final int outerDepth = parser.getDepth();
5246            int type;
5247            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5248                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5249                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5250                    continue;
5251                }
5252
5253                switch (parser.getName()) {
5254                    case TAG_PERMISSION_ENTRY: {
5255                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
5256                        final boolean isGranted = "true".equals(
5257                                parser.getAttributeValue(null, ATTR_GRANTED));
5258
5259                        int permBits = 0;
5260                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
5261                            permBits |= FLAG_PERMISSION_USER_SET;
5262                        }
5263                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
5264                            permBits |= FLAG_PERMISSION_USER_FIXED;
5265                        }
5266                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
5267                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
5268                        }
5269
5270                        if (isGranted || permBits != 0) {
5271                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5272                        }
5273                    } break;
5274                }
5275            }
5276        }
5277
5278        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5279                int userId) throws IOException, XmlPullParserException {
5280            final int outerDepth = parser.getDepth();
5281            int type;
5282            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5283                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5284                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5285                    continue;
5286                }
5287
5288                switch (parser.getName()) {
5289                    case TAG_ITEM: {
5290                        String name = parser.getAttributeValue(null, ATTR_NAME);
5291                        BasePermission bp = mPermissions.get(name);
5292                        if (bp == null) {
5293                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5294                            XmlUtils.skipCurrentTag(parser);
5295                            continue;
5296                        }
5297
5298                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5299                        final boolean granted = grantedStr == null
5300                                || Boolean.parseBoolean(grantedStr);
5301
5302                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5303                        final int flags = (flagsStr != null)
5304                                ? Integer.parseInt(flagsStr, 16) : 0;
5305
5306                        if (granted) {
5307                            permissionsState.grantRuntimePermission(bp, userId);
5308                            permissionsState.updatePermissionFlags(bp, userId,
5309                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5310                        } else {
5311                            permissionsState.updatePermissionFlags(bp, userId,
5312                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5313                        }
5314
5315                    } break;
5316                }
5317            }
5318        }
5319
5320        private void writePermissions(XmlSerializer serializer,
5321                List<PermissionState> permissionStates) throws IOException {
5322            for (PermissionState permissionState : permissionStates) {
5323                serializer.startTag(null, TAG_ITEM);
5324                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5325                serializer.attribute(null, ATTR_GRANTED,
5326                        String.valueOf(permissionState.isGranted()));
5327                serializer.attribute(null, ATTR_FLAGS,
5328                        Integer.toHexString(permissionState.getFlags()));
5329                serializer.endTag(null, TAG_ITEM);
5330            }
5331        }
5332
5333        private final class MyHandler extends Handler {
5334            public MyHandler() {
5335                super(BackgroundThread.getHandler().getLooper());
5336            }
5337
5338            @Override
5339            public void handleMessage(Message message) {
5340                final int userId = message.what;
5341                Runnable callback = (Runnable) message.obj;
5342                writePermissionsSync(userId);
5343                if (callback != null) {
5344                    callback.run();
5345                }
5346            }
5347        }
5348    }
5349}
5350