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