Settings.java revision 6d051fc68d1b1f2c09eb2e58c26821e1e13935dc
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            mVersion.put(volumeUuid, ver);
1419        }
1420        return ver;
1421    }
1422
1423    public VersionInfo getInternalVersion() {
1424        return mVersion.get(StorageManager.UUID_PRIVATE_INTERNAL);
1425    }
1426
1427    public VersionInfo getExternalVersion() {
1428        return mVersion.get(StorageManager.UUID_PRIMARY_PHYSICAL);
1429    }
1430
1431    public void onVolumeForgotten(String fsUuid) {
1432        mVersion.remove(fsUuid);
1433    }
1434
1435    /**
1436     * Applies the preferred activity state described by the given XML.  This code
1437     * also supports the restore-from-backup code path.
1438     *
1439     * @see PreferredActivityBackupHelper
1440     */
1441    void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
1442            throws XmlPullParserException, IOException {
1443        int outerDepth = parser.getDepth();
1444        int type;
1445        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1446                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1447            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1448                continue;
1449            }
1450
1451            String tagName = parser.getName();
1452            if (tagName.equals(TAG_ITEM)) {
1453                PreferredActivity pa = new PreferredActivity(parser);
1454                if (pa.mPref.getParseError() == null) {
1455                    editPreferredActivitiesLPw(userId).addFilter(pa);
1456                } else {
1457                    PackageManagerService.reportSettingsProblem(Log.WARN,
1458                            "Error in package manager settings: <preferred-activity> "
1459                                    + pa.mPref.getParseError() + " at "
1460                                    + parser.getPositionDescription());
1461                }
1462            } else {
1463                PackageManagerService.reportSettingsProblem(Log.WARN,
1464                        "Unknown element under <preferred-activities>: " + parser.getName());
1465                XmlUtils.skipCurrentTag(parser);
1466            }
1467        }
1468    }
1469
1470    private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)
1471            throws XmlPullParserException, IOException {
1472        int outerDepth = parser.getDepth();
1473        int type;
1474        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1475                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1476            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1477                continue;
1478            }
1479            String tagName = parser.getName();
1480            if (tagName.equals(TAG_ITEM)) {
1481                PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
1482                editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
1483            } else {
1484                PackageManagerService.reportSettingsProblem(Log.WARN,
1485                        "Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: "
1486                        + parser.getName());
1487                XmlUtils.skipCurrentTag(parser);
1488            }
1489        }
1490    }
1491
1492    private void readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)
1493            throws XmlPullParserException, IOException {
1494        int outerDepth = parser.getDepth();
1495        int type;
1496        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1497                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1498            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1499                continue;
1500            }
1501            final String tagName = parser.getName();
1502            if (tagName.equals(TAG_ITEM)) {
1503                CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
1504                editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
1505            } else {
1506                String msg = "Unknown element under " +  TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
1507                        tagName;
1508                PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1509                XmlUtils.skipCurrentTag(parser);
1510            }
1511        }
1512    }
1513
1514    private void readDomainVerificationLPw(XmlPullParser parser, PackageSettingBase packageSetting)
1515            throws XmlPullParserException, IOException {
1516        IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1517        packageSetting.setIntentFilterVerificationInfo(ivi);
1518        if (DEBUG_PARSER) {
1519            Log.d(TAG, "Read domain verification for package: " + ivi.getPackageName());
1520        }
1521    }
1522
1523    private void readRestoredIntentFilterVerifications(XmlPullParser parser)
1524            throws XmlPullParserException, IOException {
1525        int outerDepth = parser.getDepth();
1526        int type;
1527        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1528                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1529            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1530                continue;
1531            }
1532            final String tagName = parser.getName();
1533            if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
1534                IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1535                if (DEBUG_DOMAIN_VERIFICATION) {
1536                    Slog.i(TAG, "Restored IVI for " + ivi.getPackageName()
1537                            + " status=" + ivi.getStatusString());
1538                }
1539                mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi);
1540            } else {
1541                Slog.w(TAG, "Unknown element: " + tagName);
1542                XmlUtils.skipCurrentTag(parser);
1543            }
1544        }
1545    }
1546
1547    void readDefaultAppsLPw(XmlPullParser parser, int userId)
1548            throws XmlPullParserException, IOException {
1549        int outerDepth = parser.getDepth();
1550        int type;
1551        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1552                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1553            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1554                continue;
1555            }
1556            String tagName = parser.getName();
1557            if (tagName.equals(TAG_DEFAULT_BROWSER)) {
1558                String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
1559                mDefaultBrowserApp.put(userId, packageName);
1560            } else if (tagName.equals(TAG_DEFAULT_DIALER)) {
1561                String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
1562                mDefaultDialerApp.put(userId, packageName);
1563            } else {
1564                String msg = "Unknown element under " +  TAG_DEFAULT_APPS + ": " +
1565                        parser.getName();
1566                PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1567                XmlUtils.skipCurrentTag(parser);
1568            }
1569        }
1570    }
1571
1572    void readPackageRestrictionsLPr(int userId) {
1573        if (DEBUG_MU) {
1574            Log.i(TAG, "Reading package restrictions for user=" + userId);
1575        }
1576        FileInputStream str = null;
1577        File userPackagesStateFile = getUserPackagesStateFile(userId);
1578        File backupFile = getUserPackagesStateBackupFile(userId);
1579        if (backupFile.exists()) {
1580            try {
1581                str = new FileInputStream(backupFile);
1582                mReadMessages.append("Reading from backup stopped packages file\n");
1583                PackageManagerService.reportSettingsProblem(Log.INFO,
1584                        "Need to read from backup stopped packages file");
1585                if (userPackagesStateFile.exists()) {
1586                    // If both the backup and normal file exist, we
1587                    // ignore the normal one since it might have been
1588                    // corrupted.
1589                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1590                            + userPackagesStateFile);
1591                    userPackagesStateFile.delete();
1592                }
1593            } catch (java.io.IOException e) {
1594                // We'll try for the normal settings file.
1595            }
1596        }
1597
1598        try {
1599            if (str == null) {
1600                if (!userPackagesStateFile.exists()) {
1601                    mReadMessages.append("No stopped packages file found\n");
1602                    PackageManagerService.reportSettingsProblem(Log.INFO,
1603                            "No stopped packages file; "
1604                            + "assuming all started");
1605                    // At first boot, make sure no packages are stopped.
1606                    // We usually want to have third party apps initialize
1607                    // in the stopped state, but not at first boot.  Also
1608                    // consider all applications to be installed.
1609                    for (PackageSetting pkg : mPackages.values()) {
1610                        pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
1611                                true,   // installed
1612                                false,  // stopped
1613                                false,  // notLaunched
1614                                false,  // hidden
1615                                false,  // suspended
1616                                null, null, null,
1617                                false, // blockUninstall
1618                                INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0);
1619                    }
1620                    return;
1621                }
1622                str = new FileInputStream(userPackagesStateFile);
1623            }
1624            final XmlPullParser parser = Xml.newPullParser();
1625            parser.setInput(str, StandardCharsets.UTF_8.name());
1626
1627            int type;
1628            while ((type=parser.next()) != XmlPullParser.START_TAG
1629                       && type != XmlPullParser.END_DOCUMENT) {
1630                ;
1631            }
1632
1633            if (type != XmlPullParser.START_TAG) {
1634                mReadMessages.append("No start tag found in package restrictions file\n");
1635                PackageManagerService.reportSettingsProblem(Log.WARN,
1636                        "No start tag found in package manager stopped packages");
1637                return;
1638            }
1639
1640            int maxAppLinkGeneration = 0;
1641
1642            int outerDepth = parser.getDepth();
1643            PackageSetting ps = null;
1644            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1645                   && (type != XmlPullParser.END_TAG
1646                           || parser.getDepth() > outerDepth)) {
1647                if (type == XmlPullParser.END_TAG
1648                        || type == XmlPullParser.TEXT) {
1649                    continue;
1650                }
1651
1652                String tagName = parser.getName();
1653                if (tagName.equals(TAG_PACKAGE)) {
1654                    String name = parser.getAttributeValue(null, ATTR_NAME);
1655                    ps = mPackages.get(name);
1656                    if (ps == null) {
1657                        Slog.w(PackageManagerService.TAG, "No package known for stopped package "
1658                                + name);
1659                        XmlUtils.skipCurrentTag(parser);
1660                        continue;
1661                    }
1662
1663                    final long ceDataInode = XmlUtils.readLongAttribute(parser, ATTR_CE_DATA_INODE,
1664                            0);
1665                    final boolean installed = XmlUtils.readBooleanAttribute(parser, ATTR_INSTALLED,
1666                            true);
1667                    final boolean stopped = XmlUtils.readBooleanAttribute(parser, ATTR_STOPPED,
1668                            false);
1669                    final boolean notLaunched = XmlUtils.readBooleanAttribute(parser,
1670                            ATTR_NOT_LAUNCHED, false);
1671
1672                    // For backwards compatibility with the previous name of "blocked", which
1673                    // now means hidden, read the old attribute as well.
1674                    final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
1675                    boolean hidden = blockedStr == null
1676                            ? false : Boolean.parseBoolean(blockedStr);
1677                    final String hiddenStr = parser.getAttributeValue(null, ATTR_HIDDEN);
1678                    hidden = hiddenStr == null
1679                            ? hidden : Boolean.parseBoolean(hiddenStr);
1680
1681                    final boolean suspended = XmlUtils.readBooleanAttribute(parser, ATTR_SUSPENDED,
1682                            false);
1683                    final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser,
1684                            ATTR_BLOCK_UNINSTALL, false);
1685                    final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED,
1686                            COMPONENT_ENABLED_STATE_DEFAULT);
1687                    final String enabledCaller = parser.getAttributeValue(null,
1688                            ATTR_ENABLED_CALLER);
1689
1690                    final int verifState = XmlUtils.readIntAttribute(parser,
1691                            ATTR_DOMAIN_VERIFICATON_STATE,
1692                            PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
1693                    final int linkGeneration = XmlUtils.readIntAttribute(parser,
1694                            ATTR_APP_LINK_GENERATION, 0);
1695                    if (linkGeneration > maxAppLinkGeneration) {
1696                        maxAppLinkGeneration = linkGeneration;
1697                    }
1698
1699                    ArraySet<String> enabledComponents = null;
1700                    ArraySet<String> disabledComponents = null;
1701
1702                    int packageDepth = parser.getDepth();
1703                    while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1704                            && (type != XmlPullParser.END_TAG
1705                            || parser.getDepth() > packageDepth)) {
1706                        if (type == XmlPullParser.END_TAG
1707                                || type == XmlPullParser.TEXT) {
1708                            continue;
1709                        }
1710                        tagName = parser.getName();
1711                        if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
1712                            enabledComponents = readComponentsLPr(parser);
1713                        } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
1714                            disabledComponents = readComponentsLPr(parser);
1715                        }
1716                    }
1717
1718                    ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
1719                            hidden, suspended, enabledCaller, enabledComponents, disabledComponents,
1720                            blockUninstall, verifState, linkGeneration);
1721                } else if (tagName.equals("preferred-activities")) {
1722                    readPreferredActivitiesLPw(parser, userId);
1723                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1724                    readPersistentPreferredActivitiesLPw(parser, userId);
1725                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
1726                    readCrossProfileIntentFiltersLPw(parser, userId);
1727                } else if (tagName.equals(TAG_DEFAULT_APPS)) {
1728                    readDefaultAppsLPw(parser, userId);
1729                } else {
1730                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1731                          + parser.getName());
1732                    XmlUtils.skipCurrentTag(parser);
1733                }
1734            }
1735
1736            str.close();
1737
1738            mNextAppLinkGeneration.put(userId, maxAppLinkGeneration + 1);
1739
1740        } catch (XmlPullParserException e) {
1741            mReadMessages.append("Error reading: " + e.toString());
1742            PackageManagerService.reportSettingsProblem(Log.ERROR,
1743                    "Error reading stopped packages: " + e);
1744            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1745                    e);
1746
1747        } catch (java.io.IOException e) {
1748            mReadMessages.append("Error reading: " + e.toString());
1749            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1750            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1751                    e);
1752        }
1753    }
1754
1755    private ArraySet<String> readComponentsLPr(XmlPullParser parser)
1756            throws IOException, XmlPullParserException {
1757        ArraySet<String> components = null;
1758        int type;
1759        int outerDepth = parser.getDepth();
1760        String tagName;
1761        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1762                && (type != XmlPullParser.END_TAG
1763                || parser.getDepth() > outerDepth)) {
1764            if (type == XmlPullParser.END_TAG
1765                    || type == XmlPullParser.TEXT) {
1766                continue;
1767            }
1768            tagName = parser.getName();
1769            if (tagName.equals(TAG_ITEM)) {
1770                String componentName = parser.getAttributeValue(null, ATTR_NAME);
1771                if (componentName != null) {
1772                    if (components == null) {
1773                        components = new ArraySet<String>();
1774                    }
1775                    components.add(componentName);
1776                }
1777            }
1778        }
1779        return components;
1780    }
1781
1782    /**
1783     * Record the state of preferred activity configuration into XML.  This is used both
1784     * for recording packages.xml internally and for supporting backup/restore of the
1785     * preferred activity configuration.
1786     */
1787    void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
1788            throws IllegalArgumentException, IllegalStateException, IOException {
1789        serializer.startTag(null, "preferred-activities");
1790        PreferredIntentResolver pir = mPreferredActivities.get(userId);
1791        if (pir != null) {
1792            for (final PreferredActivity pa : pir.filterSet()) {
1793                serializer.startTag(null, TAG_ITEM);
1794                pa.writeToXml(serializer, full);
1795                serializer.endTag(null, TAG_ITEM);
1796            }
1797        }
1798        serializer.endTag(null, "preferred-activities");
1799    }
1800
1801    void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
1802            throws IllegalArgumentException, IllegalStateException, IOException {
1803        serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1804        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1805        if (ppir != null) {
1806            for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
1807                serializer.startTag(null, TAG_ITEM);
1808                ppa.writeToXml(serializer);
1809                serializer.endTag(null, TAG_ITEM);
1810            }
1811        }
1812        serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1813    }
1814
1815    void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)
1816            throws IllegalArgumentException, IllegalStateException, IOException {
1817        serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1818        CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1819        if (cpir != null) {
1820            for (final CrossProfileIntentFilter cpif : cpir.filterSet()) {
1821                serializer.startTag(null, TAG_ITEM);
1822                cpif.writeToXml(serializer);
1823                serializer.endTag(null, TAG_ITEM);
1824            }
1825        }
1826        serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1827    }
1828
1829    void writeDomainVerificationsLPr(XmlSerializer serializer,
1830                                     IntentFilterVerificationInfo verificationInfo)
1831            throws IllegalArgumentException, IllegalStateException, IOException {
1832        if (verificationInfo != null && verificationInfo.getPackageName() != null) {
1833            serializer.startTag(null, TAG_DOMAIN_VERIFICATION);
1834            verificationInfo.writeToXml(serializer);
1835            if (DEBUG_DOMAIN_VERIFICATION) {
1836                Slog.d(TAG, "Wrote domain verification for package: "
1837                        + verificationInfo.getPackageName());
1838            }
1839            serializer.endTag(null, TAG_DOMAIN_VERIFICATION);
1840        }
1841    }
1842
1843    // Specifically for backup/restore
1844    void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)
1845            throws IllegalArgumentException, IllegalStateException, IOException {
1846        serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
1847        final int N = mPackages.size();
1848        for (int i = 0; i < N; i++) {
1849            PackageSetting ps = mPackages.valueAt(i);
1850            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
1851            if (ivi != null) {
1852                writeDomainVerificationsLPr(serializer, ivi);
1853            }
1854        }
1855        serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
1856    }
1857
1858    // Specifically for backup/restore
1859    void readAllDomainVerificationsLPr(XmlPullParser parser, int userId)
1860            throws XmlPullParserException, IOException {
1861        mRestoredIntentFilterVerifications.clear();
1862
1863        int outerDepth = parser.getDepth();
1864        int type;
1865        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1866                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1867            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1868                continue;
1869            }
1870
1871            String tagName = parser.getName();
1872            if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
1873                IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
1874                final String pkgName = ivi.getPackageName();
1875                final PackageSetting ps = mPackages.get(pkgName);
1876                if (ps != null) {
1877                    // known/existing package; update in place
1878                    ps.setIntentFilterVerificationInfo(ivi);
1879                    if (DEBUG_DOMAIN_VERIFICATION) {
1880                        Slog.d(TAG, "Restored IVI for existing app " + pkgName
1881                                + " status=" + ivi.getStatusString());
1882                    }
1883                } else {
1884                    mRestoredIntentFilterVerifications.put(pkgName, ivi);
1885                    if (DEBUG_DOMAIN_VERIFICATION) {
1886                        Slog.d(TAG, "Restored IVI for pending app " + pkgName
1887                                + " status=" + ivi.getStatusString());
1888                    }
1889                }
1890            } else {
1891                PackageManagerService.reportSettingsProblem(Log.WARN,
1892                        "Unknown element under <all-intent-filter-verification>: "
1893                        + parser.getName());
1894                XmlUtils.skipCurrentTag(parser);
1895            }
1896        }
1897    }
1898
1899    // Specifically for backup/restore
1900    public void processRestoredPermissionGrantLPr(String pkgName, String permission,
1901            boolean isGranted, int restoredFlagSet, int userId)
1902            throws IOException, XmlPullParserException {
1903        mRuntimePermissionsPersistence.rememberRestoredUserGrantLPr(
1904                pkgName, permission, isGranted, restoredFlagSet, userId);
1905    }
1906
1907    void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
1908            throws IllegalArgumentException, IllegalStateException, IOException {
1909        serializer.startTag(null, TAG_DEFAULT_APPS);
1910        String defaultBrowser = mDefaultBrowserApp.get(userId);
1911        if (!TextUtils.isEmpty(defaultBrowser)) {
1912            serializer.startTag(null, TAG_DEFAULT_BROWSER);
1913            serializer.attribute(null, ATTR_PACKAGE_NAME, defaultBrowser);
1914            serializer.endTag(null, TAG_DEFAULT_BROWSER);
1915        }
1916        String defaultDialer = mDefaultDialerApp.get(userId);
1917        if (!TextUtils.isEmpty(defaultDialer)) {
1918            serializer.startTag(null, TAG_DEFAULT_DIALER);
1919            serializer.attribute(null, ATTR_PACKAGE_NAME, defaultDialer);
1920            serializer.endTag(null, TAG_DEFAULT_DIALER);
1921        }
1922        serializer.endTag(null, TAG_DEFAULT_APPS);
1923    }
1924
1925    void writePackageRestrictionsLPr(int userId) {
1926        if (DEBUG_MU) {
1927            Log.i(TAG, "Writing package restrictions for user=" + userId);
1928        }
1929        // Keep the old stopped packages around until we know the new ones have
1930        // been successfully written.
1931        File userPackagesStateFile = getUserPackagesStateFile(userId);
1932        File backupFile = getUserPackagesStateBackupFile(userId);
1933        new File(userPackagesStateFile.getParent()).mkdirs();
1934        if (userPackagesStateFile.exists()) {
1935            // Presence of backup settings file indicates that we failed
1936            // to persist packages earlier. So preserve the older
1937            // backup for future reference since the current packages
1938            // might have been corrupted.
1939            if (!backupFile.exists()) {
1940                if (!userPackagesStateFile.renameTo(backupFile)) {
1941                    Slog.wtf(PackageManagerService.TAG,
1942                            "Unable to backup user packages state file, "
1943                            + "current changes will be lost at reboot");
1944                    return;
1945                }
1946            } else {
1947                userPackagesStateFile.delete();
1948                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
1949            }
1950        }
1951
1952        try {
1953            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
1954            final BufferedOutputStream str = new BufferedOutputStream(fstr);
1955
1956            final XmlSerializer serializer = new FastXmlSerializer();
1957            serializer.setOutput(str, StandardCharsets.UTF_8.name());
1958            serializer.startDocument(null, true);
1959            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1960
1961            serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
1962
1963            for (final PackageSetting pkg : mPackages.values()) {
1964                final PackageUserState ustate = pkg.readUserState(userId);
1965                if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
1966
1967                serializer.startTag(null, TAG_PACKAGE);
1968                serializer.attribute(null, ATTR_NAME, pkg.name);
1969                if (ustate.ceDataInode != 0) {
1970                    XmlUtils.writeLongAttribute(serializer, ATTR_CE_DATA_INODE, ustate.ceDataInode);
1971                }
1972                if (!ustate.installed) {
1973                    serializer.attribute(null, ATTR_INSTALLED, "false");
1974                }
1975                if (ustate.stopped) {
1976                    serializer.attribute(null, ATTR_STOPPED, "true");
1977                }
1978                if (ustate.notLaunched) {
1979                    serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
1980                }
1981                if (ustate.hidden) {
1982                    serializer.attribute(null, ATTR_HIDDEN, "true");
1983                }
1984                if (ustate.suspended) {
1985                    serializer.attribute(null, ATTR_SUSPENDED, "true");
1986                }
1987                if (ustate.blockUninstall) {
1988                    serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
1989                }
1990                if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
1991                    serializer.attribute(null, ATTR_ENABLED,
1992                            Integer.toString(ustate.enabled));
1993                    if (ustate.lastDisableAppCaller != null) {
1994                        serializer.attribute(null, ATTR_ENABLED_CALLER,
1995                                ustate.lastDisableAppCaller);
1996                    }
1997                }
1998                if (ustate.domainVerificationStatus !=
1999                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
2000                    XmlUtils.writeIntAttribute(serializer, ATTR_DOMAIN_VERIFICATON_STATE,
2001                            ustate.domainVerificationStatus);
2002                }
2003                if (ustate.appLinkGeneration != 0) {
2004                    XmlUtils.writeIntAttribute(serializer, ATTR_APP_LINK_GENERATION,
2005                            ustate.appLinkGeneration);
2006                }
2007                if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
2008                    serializer.startTag(null, TAG_ENABLED_COMPONENTS);
2009                    for (final String name : ustate.enabledComponents) {
2010                        serializer.startTag(null, TAG_ITEM);
2011                        serializer.attribute(null, ATTR_NAME, name);
2012                        serializer.endTag(null, TAG_ITEM);
2013                    }
2014                    serializer.endTag(null, TAG_ENABLED_COMPONENTS);
2015                }
2016                if (!ArrayUtils.isEmpty(ustate.disabledComponents)) {
2017                    serializer.startTag(null, TAG_DISABLED_COMPONENTS);
2018                    for (final String name : ustate.disabledComponents) {
2019                        serializer.startTag(null, TAG_ITEM);
2020                        serializer.attribute(null, ATTR_NAME, name);
2021                        serializer.endTag(null, TAG_ITEM);
2022                    }
2023                    serializer.endTag(null, TAG_DISABLED_COMPONENTS);
2024                }
2025
2026                serializer.endTag(null, TAG_PACKAGE);
2027            }
2028
2029            writePreferredActivitiesLPr(serializer, userId, true);
2030            writePersistentPreferredActivitiesLPr(serializer, userId);
2031            writeCrossProfileIntentFiltersLPr(serializer, userId);
2032            writeDefaultAppsLPr(serializer, userId);
2033
2034            serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
2035
2036            serializer.endDocument();
2037
2038            str.flush();
2039            FileUtils.sync(fstr);
2040            str.close();
2041
2042            // New settings successfully written, old ones are no longer
2043            // needed.
2044            backupFile.delete();
2045            FileUtils.setPermissions(userPackagesStateFile.toString(),
2046                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
2047                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2048                    -1, -1);
2049
2050            // Done, all is good!
2051            return;
2052        } catch(java.io.IOException e) {
2053            Slog.wtf(PackageManagerService.TAG,
2054                    "Unable to write package manager user packages state, "
2055                    + " current changes will be lost at reboot", e);
2056        }
2057
2058        // Clean up partially written files
2059        if (userPackagesStateFile.exists()) {
2060            if (!userPackagesStateFile.delete()) {
2061                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
2062                        + mStoppedPackagesFilename);
2063            }
2064        }
2065    }
2066
2067    void readInstallPermissionsLPr(XmlPullParser parser,
2068            PermissionsState permissionsState) throws IOException, XmlPullParserException {
2069        int outerDepth = parser.getDepth();
2070        int type;
2071        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2072                && (type != XmlPullParser.END_TAG
2073                || parser.getDepth() > outerDepth)) {
2074            if (type == XmlPullParser.END_TAG
2075                    || type == XmlPullParser.TEXT) {
2076                continue;
2077            }
2078            String tagName = parser.getName();
2079            if (tagName.equals(TAG_ITEM)) {
2080                String name = parser.getAttributeValue(null, ATTR_NAME);
2081
2082                BasePermission bp = mPermissions.get(name);
2083                if (bp == null) {
2084                    Slog.w(PackageManagerService.TAG, "Unknown permission: " + name);
2085                    XmlUtils.skipCurrentTag(parser);
2086                    continue;
2087                }
2088
2089                String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
2090                final boolean granted = grantedStr == null
2091                        || Boolean.parseBoolean(grantedStr);
2092
2093                String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
2094                final int flags = (flagsStr != null)
2095                        ? Integer.parseInt(flagsStr, 16) : 0;
2096
2097                if (granted) {
2098                    if (permissionsState.grantInstallPermission(bp) ==
2099                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
2100                        Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2101                        XmlUtils.skipCurrentTag(parser);
2102                    } else {
2103                        permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2104                                PackageManager.MASK_PERMISSION_FLAGS, flags);
2105                    }
2106                } else {
2107                    if (permissionsState.revokeInstallPermission(bp) ==
2108                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
2109                        Slog.w(PackageManagerService.TAG, "Permission already added: " + name);
2110                        XmlUtils.skipCurrentTag(parser);
2111                    } else {
2112                        permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2113                                PackageManager.MASK_PERMISSION_FLAGS, flags);
2114                    }
2115                }
2116            } else {
2117                Slog.w(PackageManagerService.TAG, "Unknown element under <permissions>: "
2118                        + parser.getName());
2119                XmlUtils.skipCurrentTag(parser);
2120            }
2121        }
2122    }
2123
2124    void writePermissionsLPr(XmlSerializer serializer, List<PermissionState> permissionStates)
2125            throws IOException {
2126        if (permissionStates.isEmpty()) {
2127            return;
2128        }
2129
2130        serializer.startTag(null, TAG_PERMISSIONS);
2131
2132        for (PermissionState permissionState : permissionStates) {
2133            serializer.startTag(null, TAG_ITEM);
2134            serializer.attribute(null, ATTR_NAME, permissionState.getName());
2135            serializer.attribute(null, ATTR_GRANTED, String.valueOf(permissionState.isGranted()));
2136            serializer.attribute(null, ATTR_FLAGS, Integer.toHexString(permissionState.getFlags()));
2137            serializer.endTag(null, TAG_ITEM);
2138        }
2139
2140        serializer.endTag(null, TAG_PERMISSIONS);
2141    }
2142
2143    void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames)
2144            throws IOException {
2145        if (childPackageNames == null) {
2146            return;
2147        }
2148        final int childCount = childPackageNames.size();
2149        for (int i = 0; i < childCount; i++) {
2150            String childPackageName = childPackageNames.get(i);
2151            serializer.startTag(null, TAG_CHILD_PACKAGE);
2152            serializer.attribute(null, ATTR_NAME, childPackageName);
2153            serializer.endTag(null, TAG_CHILD_PACKAGE);
2154        }
2155    }
2156
2157    // Note: assumed "stopped" field is already cleared in all packages.
2158    // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
2159    void readStoppedLPw() {
2160        FileInputStream str = null;
2161        if (mBackupStoppedPackagesFilename.exists()) {
2162            try {
2163                str = new FileInputStream(mBackupStoppedPackagesFilename);
2164                mReadMessages.append("Reading from backup stopped packages file\n");
2165                PackageManagerService.reportSettingsProblem(Log.INFO,
2166                        "Need to read from backup stopped packages file");
2167                if (mSettingsFilename.exists()) {
2168                    // If both the backup and normal file exist, we
2169                    // ignore the normal one since it might have been
2170                    // corrupted.
2171                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
2172                            + mStoppedPackagesFilename);
2173                    mStoppedPackagesFilename.delete();
2174                }
2175            } catch (java.io.IOException e) {
2176                // We'll try for the normal settings file.
2177            }
2178        }
2179
2180        try {
2181            if (str == null) {
2182                if (!mStoppedPackagesFilename.exists()) {
2183                    mReadMessages.append("No stopped packages file found\n");
2184                    PackageManagerService.reportSettingsProblem(Log.INFO,
2185                            "No stopped packages file file; assuming all started");
2186                    // At first boot, make sure no packages are stopped.
2187                    // We usually want to have third party apps initialize
2188                    // in the stopped state, but not at first boot.
2189                    for (PackageSetting pkg : mPackages.values()) {
2190                        pkg.setStopped(false, 0);
2191                        pkg.setNotLaunched(false, 0);
2192                    }
2193                    return;
2194                }
2195                str = new FileInputStream(mStoppedPackagesFilename);
2196            }
2197            final XmlPullParser parser = Xml.newPullParser();
2198            parser.setInput(str, null);
2199
2200            int type;
2201            while ((type=parser.next()) != XmlPullParser.START_TAG
2202                       && type != XmlPullParser.END_DOCUMENT) {
2203                ;
2204            }
2205
2206            if (type != XmlPullParser.START_TAG) {
2207                mReadMessages.append("No start tag found in stopped packages file\n");
2208                PackageManagerService.reportSettingsProblem(Log.WARN,
2209                        "No start tag found in package manager stopped packages");
2210                return;
2211            }
2212
2213            int outerDepth = parser.getDepth();
2214            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
2215                   && (type != XmlPullParser.END_TAG
2216                           || parser.getDepth() > outerDepth)) {
2217                if (type == XmlPullParser.END_TAG
2218                        || type == XmlPullParser.TEXT) {
2219                    continue;
2220                }
2221
2222                String tagName = parser.getName();
2223                if (tagName.equals(TAG_PACKAGE)) {
2224                    String name = parser.getAttributeValue(null, ATTR_NAME);
2225                    PackageSetting ps = mPackages.get(name);
2226                    if (ps != null) {
2227                        ps.setStopped(true, 0);
2228                        if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
2229                            ps.setNotLaunched(true, 0);
2230                        }
2231                    } else {
2232                        Slog.w(PackageManagerService.TAG,
2233                                "No package known for stopped package " + name);
2234                    }
2235                    XmlUtils.skipCurrentTag(parser);
2236                } else {
2237                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
2238                          + parser.getName());
2239                    XmlUtils.skipCurrentTag(parser);
2240                }
2241            }
2242
2243            str.close();
2244
2245        } catch (XmlPullParserException e) {
2246            mReadMessages.append("Error reading: " + e.toString());
2247            PackageManagerService.reportSettingsProblem(Log.ERROR,
2248                    "Error reading stopped packages: " + e);
2249            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2250                    e);
2251
2252        } catch (java.io.IOException e) {
2253            mReadMessages.append("Error reading: " + e.toString());
2254            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2255            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
2256                    e);
2257
2258        }
2259    }
2260
2261    void writeLPr() {
2262        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
2263
2264        // Keep the old settings around until we know the new ones have
2265        // been successfully written.
2266        if (mSettingsFilename.exists()) {
2267            // Presence of backup settings file indicates that we failed
2268            // to persist settings earlier. So preserve the older
2269            // backup for future reference since the current settings
2270            // might have been corrupted.
2271            if (!mBackupSettingsFilename.exists()) {
2272                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
2273                    Slog.wtf(PackageManagerService.TAG,
2274                            "Unable to backup package manager settings, "
2275                            + " current changes will be lost at reboot");
2276                    return;
2277                }
2278            } else {
2279                mSettingsFilename.delete();
2280                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
2281            }
2282        }
2283
2284        mPastSignatures.clear();
2285
2286        try {
2287            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
2288            BufferedOutputStream str = new BufferedOutputStream(fstr);
2289
2290            //XmlSerializer serializer = XmlUtils.serializerInstance();
2291            XmlSerializer serializer = new FastXmlSerializer();
2292            serializer.setOutput(str, StandardCharsets.UTF_8.name());
2293            serializer.startDocument(null, true);
2294            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2295
2296            serializer.startTag(null, "packages");
2297
2298            for (int i = 0; i < mVersion.size(); i++) {
2299                final String volumeUuid = mVersion.keyAt(i);
2300                final VersionInfo ver = mVersion.valueAt(i);
2301
2302                serializer.startTag(null, TAG_VERSION);
2303                XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid);
2304                XmlUtils.writeIntAttribute(serializer, ATTR_SDK_VERSION, ver.sdkVersion);
2305                XmlUtils.writeIntAttribute(serializer, ATTR_DATABASE_VERSION, ver.databaseVersion);
2306                XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint);
2307                serializer.endTag(null, TAG_VERSION);
2308            }
2309
2310            if (mVerifierDeviceIdentity != null) {
2311                serializer.startTag(null, "verifier");
2312                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
2313                serializer.endTag(null, "verifier");
2314            }
2315
2316            if (mReadExternalStorageEnforced != null) {
2317                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
2318                serializer.attribute(
2319                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
2320                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
2321            }
2322
2323            serializer.startTag(null, "permission-trees");
2324            for (BasePermission bp : mPermissionTrees.values()) {
2325                writePermissionLPr(serializer, bp);
2326            }
2327            serializer.endTag(null, "permission-trees");
2328
2329            serializer.startTag(null, "permissions");
2330            for (BasePermission bp : mPermissions.values()) {
2331                writePermissionLPr(serializer, bp);
2332            }
2333            serializer.endTag(null, "permissions");
2334
2335            for (final PackageSetting pkg : mPackages.values()) {
2336                writePackageLPr(serializer, pkg);
2337            }
2338
2339            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
2340                writeDisabledSysPackageLPr(serializer, pkg);
2341            }
2342
2343            for (final SharedUserSetting usr : mSharedUsers.values()) {
2344                serializer.startTag(null, "shared-user");
2345                serializer.attribute(null, ATTR_NAME, usr.name);
2346                serializer.attribute(null, "userId",
2347                        Integer.toString(usr.userId));
2348                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
2349                writePermissionsLPr(serializer, usr.getPermissionsState()
2350                        .getInstallPermissionStates());
2351                serializer.endTag(null, "shared-user");
2352            }
2353
2354            if (mPackagesToBeCleaned.size() > 0) {
2355                for (PackageCleanItem item : mPackagesToBeCleaned) {
2356                    final String userStr = Integer.toString(item.userId);
2357                    serializer.startTag(null, "cleaning-package");
2358                    serializer.attribute(null, ATTR_NAME, item.packageName);
2359                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
2360                    serializer.attribute(null, ATTR_USER, userStr);
2361                    serializer.endTag(null, "cleaning-package");
2362                }
2363            }
2364
2365            if (mRenamedPackages.size() > 0) {
2366                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
2367                    serializer.startTag(null, "renamed-package");
2368                    serializer.attribute(null, "new", e.getKey());
2369                    serializer.attribute(null, "old", e.getValue());
2370                    serializer.endTag(null, "renamed-package");
2371                }
2372            }
2373
2374            final int numIVIs = mRestoredIntentFilterVerifications.size();
2375            if (numIVIs > 0) {
2376                if (DEBUG_DOMAIN_VERIFICATION) {
2377                    Slog.i(TAG, "Writing restored-ivi entries to packages.xml");
2378                }
2379                serializer.startTag(null, "restored-ivi");
2380                for (int i = 0; i < numIVIs; i++) {
2381                    IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i);
2382                    writeDomainVerificationsLPr(serializer, ivi);
2383                }
2384                serializer.endTag(null, "restored-ivi");
2385            } else {
2386                if (DEBUG_DOMAIN_VERIFICATION) {
2387                    Slog.i(TAG, "  no restored IVI entries to write");
2388                }
2389            }
2390
2391            mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
2392
2393            serializer.endTag(null, "packages");
2394
2395            serializer.endDocument();
2396
2397            str.flush();
2398            FileUtils.sync(fstr);
2399            str.close();
2400
2401            // New settings successfully written, old ones are no longer
2402            // needed.
2403            mBackupSettingsFilename.delete();
2404            FileUtils.setPermissions(mSettingsFilename.toString(),
2405                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
2406                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
2407                    -1, -1);
2408
2409            writeKernelMappingLPr();
2410            writePackageListLPr();
2411            writeAllUsersPackageRestrictionsLPr();
2412            writeAllRuntimePermissionsLPr();
2413            return;
2414
2415        } catch(XmlPullParserException e) {
2416            Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
2417                    + "current changes will be lost at reboot", e);
2418        } catch(java.io.IOException e) {
2419            Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
2420                    + "current changes will be lost at reboot", e);
2421        }
2422        // Clean up partially written files
2423        if (mSettingsFilename.exists()) {
2424            if (!mSettingsFilename.delete()) {
2425                Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
2426                        + mSettingsFilename);
2427            }
2428        }
2429        //Debug.stopMethodTracing();
2430    }
2431
2432    void writeKernelMappingLPr() {
2433        if (mKernelMappingFilename == null) return;
2434
2435        final String[] known = mKernelMappingFilename.list();
2436        final ArraySet<String> knownSet = new ArraySet<>(known.length);
2437        for (String name : known) {
2438            knownSet.add(name);
2439        }
2440
2441        for (final PackageSetting ps : mPackages.values()) {
2442            // Package is actively claimed
2443            knownSet.remove(ps.name);
2444            writeKernelMappingLPr(ps);
2445        }
2446
2447        // Remove any unclaimed mappings
2448        for (int i = 0; i < knownSet.size(); i++) {
2449            final String name = knownSet.valueAt(i);
2450            if (DEBUG_KERNEL) Slog.d(TAG, "Dropping mapping " + name);
2451
2452            mKernelMapping.remove(name);
2453            new File(mKernelMappingFilename, name).delete();
2454        }
2455    }
2456
2457    void writeKernelMappingLPr(PackageSetting ps) {
2458        if (mKernelMappingFilename == null) return;
2459
2460        final Integer cur = mKernelMapping.get(ps.name);
2461        if (cur != null && cur.intValue() == ps.appId) {
2462            // Ignore when mapping already matches
2463            return;
2464        }
2465
2466        if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + ps.name + " to " + ps.appId);
2467
2468        final File dir = new File(mKernelMappingFilename, ps.name);
2469        dir.mkdir();
2470
2471        final File file = new File(dir, "appid");
2472        try {
2473            // Note that the use of US_ASCII here is safe, we're only writing a decimal
2474            // number to the file.
2475            FileUtils.bytesToFile(file.getAbsolutePath(),
2476                    Integer.toString(ps.appId).getBytes(StandardCharsets.US_ASCII));
2477            mKernelMapping.put(ps.name, ps.appId);
2478        } catch (IOException ignored) {
2479        }
2480    }
2481
2482    void writePackageListLPr() {
2483        writePackageListLPr(-1);
2484    }
2485
2486    void writePackageListLPr(int creatingUserId) {
2487        // Only derive GIDs for active users (not dying)
2488        final List<UserInfo> users = UserManagerService.getInstance().getUsers(true);
2489        int[] userIds = new int[users.size()];
2490        for (int i = 0; i < userIds.length; i++) {
2491            userIds[i] = users.get(i).id;
2492        }
2493        if (creatingUserId != -1) {
2494            userIds = ArrayUtils.appendInt(userIds, creatingUserId);
2495        }
2496
2497        // Write package list file now, use a JournaledFile.
2498        File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
2499        JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
2500
2501        final File writeTarget = journal.chooseForWrite();
2502        FileOutputStream fstr;
2503        BufferedWriter writer = null;
2504        try {
2505            fstr = new FileOutputStream(writeTarget);
2506            writer = new BufferedWriter(new OutputStreamWriter(fstr, Charset.defaultCharset()));
2507            FileUtils.setPermissions(fstr.getFD(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
2508
2509            StringBuilder sb = new StringBuilder();
2510            for (final PackageSetting pkg : mPackages.values()) {
2511                if (pkg.pkg == null || pkg.pkg.applicationInfo == null
2512                        || pkg.pkg.applicationInfo.dataDir == null) {
2513                    if (!"android".equals(pkg.name)) {
2514                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
2515                    }
2516                    continue;
2517                }
2518
2519                final ApplicationInfo ai = pkg.pkg.applicationInfo;
2520                final String dataPath = ai.dataDir;
2521                final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
2522                final int[] gids = pkg.getPermissionsState().computeGids(userIds);
2523
2524                // Avoid any application that has a space in its path.
2525                if (dataPath.indexOf(' ') >= 0)
2526                    continue;
2527
2528                // we store on each line the following information for now:
2529                //
2530                // pkgName    - package name
2531                // userId     - application-specific user id
2532                // debugFlag  - 0 or 1 if the package is debuggable.
2533                // dataPath   - path to package's data path
2534                // seinfo     - seinfo label for the app (assigned at install time)
2535                // gids       - supplementary gids this app launches with
2536                //
2537                // NOTE: We prefer not to expose all ApplicationInfo flags for now.
2538                //
2539                // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
2540                // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
2541                //   frameworks/base/libs/packagelistparser
2542                //   system/core/run-as/run-as.c
2543                //
2544                sb.setLength(0);
2545                sb.append(ai.packageName);
2546                sb.append(" ");
2547                sb.append(ai.uid);
2548                sb.append(isDebug ? " 1 " : " 0 ");
2549                sb.append(dataPath);
2550                sb.append(" ");
2551                sb.append(ai.seinfo);
2552                sb.append(" ");
2553                if (gids != null && gids.length > 0) {
2554                    sb.append(gids[0]);
2555                    for (int i = 1; i < gids.length; i++) {
2556                        sb.append(",");
2557                        sb.append(gids[i]);
2558                    }
2559                } else {
2560                    sb.append("none");
2561                }
2562                sb.append("\n");
2563                writer.append(sb);
2564            }
2565            writer.flush();
2566            FileUtils.sync(fstr);
2567            writer.close();
2568            journal.commit();
2569        } catch (Exception e) {
2570            Slog.wtf(TAG, "Failed to write packages.list", e);
2571            IoUtils.closeQuietly(writer);
2572            journal.rollback();
2573        }
2574    }
2575
2576    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2577            throws java.io.IOException {
2578        serializer.startTag(null, "updated-package");
2579        serializer.attribute(null, ATTR_NAME, pkg.name);
2580        if (pkg.realName != null) {
2581            serializer.attribute(null, "realName", pkg.realName);
2582        }
2583        serializer.attribute(null, "codePath", pkg.codePathString);
2584        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2585        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2586        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2587        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2588        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2589            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2590        }
2591        if (pkg.legacyNativeLibraryPathString != null) {
2592            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2593        }
2594        if (pkg.primaryCpuAbiString != null) {
2595           serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2596        }
2597        if (pkg.secondaryCpuAbiString != null) {
2598            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2599        }
2600        if (pkg.cpuAbiOverrideString != null) {
2601            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2602        }
2603
2604        if (pkg.sharedUser == null) {
2605            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2606        } else {
2607            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2608        }
2609
2610        if (pkg.parentPackageName != null) {
2611            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2612        }
2613
2614        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2615
2616        // If this is a shared user, the permissions will be written there.
2617        if (pkg.sharedUser == null) {
2618            writePermissionsLPr(serializer, pkg.getPermissionsState()
2619                    .getInstallPermissionStates());
2620        }
2621
2622        serializer.endTag(null, "updated-package");
2623    }
2624
2625    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
2626            throws java.io.IOException {
2627        serializer.startTag(null, "package");
2628        serializer.attribute(null, ATTR_NAME, pkg.name);
2629        if (pkg.realName != null) {
2630            serializer.attribute(null, "realName", pkg.realName);
2631        }
2632        serializer.attribute(null, "codePath", pkg.codePathString);
2633        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
2634            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
2635        }
2636
2637        if (pkg.legacyNativeLibraryPathString != null) {
2638            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
2639        }
2640        if (pkg.primaryCpuAbiString != null) {
2641            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
2642        }
2643        if (pkg.secondaryCpuAbiString != null) {
2644            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
2645        }
2646        if (pkg.cpuAbiOverrideString != null) {
2647            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
2648        }
2649
2650        serializer.attribute(null, "publicFlags", Integer.toString(pkg.pkgFlags));
2651        serializer.attribute(null, "privateFlags", Integer.toString(pkg.pkgPrivateFlags));
2652        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
2653        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
2654        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
2655        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
2656        if (pkg.sharedUser == null) {
2657            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
2658        } else {
2659            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
2660        }
2661        if (pkg.uidError) {
2662            serializer.attribute(null, "uidError", "true");
2663        }
2664        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2665            serializer.attribute(null, "installStatus", "false");
2666        }
2667        if (pkg.installerPackageName != null) {
2668            serializer.attribute(null, "installer", pkg.installerPackageName);
2669        }
2670        if (pkg.isOrphaned) {
2671            serializer.attribute(null, "isOrphaned", "true");
2672        }
2673        if (pkg.volumeUuid != null) {
2674            serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
2675        }
2676        if (pkg.parentPackageName != null) {
2677            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
2678        }
2679
2680        writeChildPackagesLPw(serializer, pkg.childPackageNames);
2681
2682        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
2683
2684        writePermissionsLPr(serializer, pkg.getPermissionsState()
2685                    .getInstallPermissionStates());
2686
2687        writeSigningKeySetLPr(serializer, pkg.keySetData);
2688        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
2689        writeKeySetAliasesLPr(serializer, pkg.keySetData);
2690        writeDomainVerificationsLPr(serializer, pkg.verificationInfo);
2691
2692        serializer.endTag(null, "package");
2693    }
2694
2695    void writeSigningKeySetLPr(XmlSerializer serializer,
2696            PackageKeySetData data) throws IOException {
2697        serializer.startTag(null, "proper-signing-keyset");
2698        serializer.attribute(null, "identifier",
2699                Long.toString(data.getProperSigningKeySet()));
2700        serializer.endTag(null, "proper-signing-keyset");
2701    }
2702
2703    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
2704            PackageKeySetData data) throws IOException {
2705        long properSigning = data.getProperSigningKeySet();
2706        if (data.isUsingUpgradeKeySets()) {
2707            for (long id : data.getUpgradeKeySets()) {
2708                serializer.startTag(null, "upgrade-keyset");
2709                serializer.attribute(null, "identifier", Long.toString(id));
2710                serializer.endTag(null, "upgrade-keyset");
2711            }
2712        }
2713    }
2714
2715    void writeKeySetAliasesLPr(XmlSerializer serializer,
2716            PackageKeySetData data) throws IOException {
2717        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
2718            serializer.startTag(null, "defined-keyset");
2719            serializer.attribute(null, "alias", e.getKey());
2720            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
2721            serializer.endTag(null, "defined-keyset");
2722        }
2723    }
2724
2725    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
2726            throws XmlPullParserException, java.io.IOException {
2727        if (bp.sourcePackage != null) {
2728            serializer.startTag(null, TAG_ITEM);
2729            serializer.attribute(null, ATTR_NAME, bp.name);
2730            serializer.attribute(null, "package", bp.sourcePackage);
2731            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
2732                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
2733            }
2734            if (PackageManagerService.DEBUG_SETTINGS)
2735                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
2736                        + bp.type);
2737            if (bp.type == BasePermission.TYPE_DYNAMIC) {
2738                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
2739                if (pi != null) {
2740                    serializer.attribute(null, "type", "dynamic");
2741                    if (pi.icon != 0) {
2742                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
2743                    }
2744                    if (pi.nonLocalizedLabel != null) {
2745                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
2746                    }
2747                }
2748            }
2749            serializer.endTag(null, TAG_ITEM);
2750        }
2751    }
2752
2753    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
2754        final ArraySet<String> kList = new ArraySet<String>(mPackages.keySet());
2755        final Iterator<String> its = kList.iterator();
2756        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
2757        while (its.hasNext()) {
2758            final String key = its.next();
2759            final PackageSetting ps = mPackages.get(key);
2760            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2761                ret.add(ps);
2762            }
2763        }
2764        return ret;
2765    }
2766
2767    void addPackageToCleanLPw(PackageCleanItem pkg) {
2768        if (!mPackagesToBeCleaned.contains(pkg)) {
2769            mPackagesToBeCleaned.add(pkg);
2770        }
2771    }
2772
2773    boolean readLPw(@NonNull List<UserInfo> users) {
2774        FileInputStream str = null;
2775        if (mBackupSettingsFilename.exists()) {
2776            try {
2777                str = new FileInputStream(mBackupSettingsFilename);
2778                mReadMessages.append("Reading from backup settings file\n");
2779                PackageManagerService.reportSettingsProblem(Log.INFO,
2780                        "Need to read from backup settings file");
2781                if (mSettingsFilename.exists()) {
2782                    // If both the backup and settings file exist, we
2783                    // ignore the settings since it might have been
2784                    // corrupted.
2785                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2786                            + mSettingsFilename);
2787                    mSettingsFilename.delete();
2788                }
2789            } catch (java.io.IOException e) {
2790                // We'll try for the normal settings file.
2791            }
2792        }
2793
2794        mPendingPackages.clear();
2795        mPastSignatures.clear();
2796        mKeySetRefs.clear();
2797        mInstallerPackages.clear();
2798
2799        try {
2800            if (str == null) {
2801                if (!mSettingsFilename.exists()) {
2802                    mReadMessages.append("No settings file found\n");
2803                    PackageManagerService.reportSettingsProblem(Log.INFO,
2804                            "No settings file; creating initial state");
2805                    // It's enough to just touch version details to create them
2806                    // with default values
2807                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
2808                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
2809                    return false;
2810                }
2811                str = new FileInputStream(mSettingsFilename);
2812            }
2813            XmlPullParser parser = Xml.newPullParser();
2814            parser.setInput(str, StandardCharsets.UTF_8.name());
2815
2816            int type;
2817            while ((type = parser.next()) != XmlPullParser.START_TAG
2818                    && type != XmlPullParser.END_DOCUMENT) {
2819                ;
2820            }
2821
2822            if (type != XmlPullParser.START_TAG) {
2823                mReadMessages.append("No start tag found in settings file\n");
2824                PackageManagerService.reportSettingsProblem(Log.WARN,
2825                        "No start tag found in package manager settings");
2826                Slog.wtf(PackageManagerService.TAG,
2827                        "No start tag found in package manager settings");
2828                return false;
2829            }
2830
2831            int outerDepth = parser.getDepth();
2832            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2833                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2834                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2835                    continue;
2836                }
2837
2838                String tagName = parser.getName();
2839                if (tagName.equals("package")) {
2840                    readPackageLPw(parser);
2841                } else if (tagName.equals("permissions")) {
2842                    readPermissionsLPw(mPermissions, parser);
2843                } else if (tagName.equals("permission-trees")) {
2844                    readPermissionsLPw(mPermissionTrees, parser);
2845                } else if (tagName.equals("shared-user")) {
2846                    readSharedUserLPw(parser);
2847                } else if (tagName.equals("preferred-packages")) {
2848                    // no longer used.
2849                } else if (tagName.equals("preferred-activities")) {
2850                    // Upgrading from old single-user implementation;
2851                    // these are the preferred activities for user 0.
2852                    readPreferredActivitiesLPw(parser, 0);
2853                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2854                    // TODO: check whether this is okay! as it is very
2855                    // similar to how preferred-activities are treated
2856                    readPersistentPreferredActivitiesLPw(parser, 0);
2857                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2858                    // TODO: check whether this is okay! as it is very
2859                    // similar to how preferred-activities are treated
2860                    readCrossProfileIntentFiltersLPw(parser, 0);
2861                } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
2862                    readDefaultAppsLPw(parser, 0);
2863                } else if (tagName.equals("updated-package")) {
2864                    readDisabledSysPackageLPw(parser);
2865                } else if (tagName.equals("cleaning-package")) {
2866                    String name = parser.getAttributeValue(null, ATTR_NAME);
2867                    String userStr = parser.getAttributeValue(null, ATTR_USER);
2868                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
2869                    if (name != null) {
2870                        int userId = UserHandle.USER_SYSTEM;
2871                        boolean andCode = true;
2872                        try {
2873                            if (userStr != null) {
2874                                userId = Integer.parseInt(userStr);
2875                            }
2876                        } catch (NumberFormatException e) {
2877                        }
2878                        if (codeStr != null) {
2879                            andCode = Boolean.parseBoolean(codeStr);
2880                        }
2881                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
2882                    }
2883                } else if (tagName.equals("renamed-package")) {
2884                    String nname = parser.getAttributeValue(null, "new");
2885                    String oname = parser.getAttributeValue(null, "old");
2886                    if (nname != null && oname != null) {
2887                        mRenamedPackages.put(nname, oname);
2888                    }
2889                } else if (tagName.equals("restored-ivi")) {
2890                    readRestoredIntentFilterVerifications(parser);
2891                } else if (tagName.equals("last-platform-version")) {
2892                    // Upgrade from older XML schema
2893                    final VersionInfo internal = findOrCreateVersion(
2894                            StorageManager.UUID_PRIVATE_INTERNAL);
2895                    final VersionInfo external = findOrCreateVersion(
2896                            StorageManager.UUID_PRIMARY_PHYSICAL);
2897
2898                    internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
2899                    external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
2900                    internal.fingerprint = external.fingerprint =
2901                            XmlUtils.readStringAttribute(parser, "fingerprint");
2902
2903                } else if (tagName.equals("database-version")) {
2904                    // Upgrade from older XML schema
2905                    final VersionInfo internal = findOrCreateVersion(
2906                            StorageManager.UUID_PRIVATE_INTERNAL);
2907                    final VersionInfo external = findOrCreateVersion(
2908                            StorageManager.UUID_PRIMARY_PHYSICAL);
2909
2910                    internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
2911                    external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);
2912
2913                } else if (tagName.equals("verifier")) {
2914                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2915                    try {
2916                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2917                    } catch (IllegalArgumentException e) {
2918                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2919                                + e.getMessage());
2920                    }
2921                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2922                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2923                    mReadExternalStorageEnforced = "1".equals(enforcement);
2924                } else if (tagName.equals("keyset-settings")) {
2925                    mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
2926                } else if (TAG_VERSION.equals(tagName)) {
2927                    final String volumeUuid = XmlUtils.readStringAttribute(parser,
2928                            ATTR_VOLUME_UUID);
2929                    final VersionInfo ver = findOrCreateVersion(volumeUuid);
2930                    ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
2931                    ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
2932                    ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
2933                } else {
2934                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2935                            + parser.getName());
2936                    XmlUtils.skipCurrentTag(parser);
2937                }
2938            }
2939
2940            str.close();
2941
2942        } catch (XmlPullParserException e) {
2943            mReadMessages.append("Error reading: " + e.toString());
2944            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2945            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2946
2947        } catch (java.io.IOException e) {
2948            mReadMessages.append("Error reading: " + e.toString());
2949            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2950            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2951        }
2952
2953        // If the build is setup to drop runtime permissions
2954        // on update drop the files before loading them.
2955        if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
2956            final VersionInfo internal = getInternalVersion();
2957            if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
2958                for (UserInfo user : users) {
2959                    mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
2960                }
2961            }
2962        }
2963
2964        final int N = mPendingPackages.size();
2965
2966        for (int i = 0; i < N; i++) {
2967            final PackageSetting p = mPendingPackages.get(i);
2968            final int sharedUserId = p.getSharedUserId();
2969            final Object idObj = getUserIdLPr(sharedUserId);
2970            if (idObj instanceof SharedUserSetting) {
2971                final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
2972                p.sharedUser = sharedUser;
2973                p.appId = sharedUser.userId;
2974                addPackageSettingLPw(p, sharedUser);
2975            } else if (idObj != null) {
2976                String msg = "Bad package setting: package " + p.name + " has shared uid "
2977                        + sharedUserId + " that is not a shared uid\n";
2978                mReadMessages.append(msg);
2979                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2980            } else {
2981                String msg = "Bad package setting: package " + p.name + " has shared uid "
2982                        + sharedUserId + " that is not defined\n";
2983                mReadMessages.append(msg);
2984                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2985            }
2986        }
2987        mPendingPackages.clear();
2988
2989        if (mBackupStoppedPackagesFilename.exists()
2990                || mStoppedPackagesFilename.exists()) {
2991            // Read old file
2992            readStoppedLPw();
2993            mBackupStoppedPackagesFilename.delete();
2994            mStoppedPackagesFilename.delete();
2995            // Migrate to new file format
2996            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
2997        } else {
2998            for (UserInfo user : users) {
2999                readPackageRestrictionsLPr(user.id);
3000            }
3001        }
3002
3003        for (UserInfo user : users) {
3004            mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
3005        }
3006
3007        /*
3008         * Make sure all the updated system packages have their shared users
3009         * associated with them.
3010         */
3011        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
3012        while (disabledIt.hasNext()) {
3013            final PackageSetting disabledPs = disabledIt.next();
3014            final Object id = getUserIdLPr(disabledPs.appId);
3015            if (id != null && id instanceof SharedUserSetting) {
3016                disabledPs.sharedUser = (SharedUserSetting) id;
3017            }
3018        }
3019
3020        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
3021                + mSharedUsers.size() + " shared uids\n");
3022
3023        writeKernelMappingLPr();
3024
3025        return true;
3026    }
3027
3028    void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
3029        // First pull data from any pre-installed apps.
3030        for (PackageSetting ps : mPackages.values()) {
3031            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
3032                    && ps.pkg.preferredActivityFilters != null) {
3033                ArrayList<PackageParser.ActivityIntentInfo> intents
3034                        = ps.pkg.preferredActivityFilters;
3035                for (int i=0; i<intents.size(); i++) {
3036                    PackageParser.ActivityIntentInfo aii = intents.get(i);
3037                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
3038                            ps.name, aii.activity.className), userId);
3039                }
3040            }
3041        }
3042
3043        // Read preferred apps from .../etc/preferred-apps directory.
3044        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
3045        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
3046            return;
3047        }
3048        if (!preferredDir.canRead()) {
3049            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
3050            return;
3051        }
3052
3053        // Iterate over the files in the directory and scan .xml files
3054        for (File f : preferredDir.listFiles()) {
3055            if (!f.getPath().endsWith(".xml")) {
3056                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
3057                continue;
3058            }
3059            if (!f.canRead()) {
3060                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
3061                continue;
3062            }
3063
3064            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
3065            InputStream str = null;
3066            try {
3067                str = new BufferedInputStream(new FileInputStream(f));
3068                XmlPullParser parser = Xml.newPullParser();
3069                parser.setInput(str, null);
3070
3071                int type;
3072                while ((type = parser.next()) != XmlPullParser.START_TAG
3073                        && type != XmlPullParser.END_DOCUMENT) {
3074                    ;
3075                }
3076
3077                if (type != XmlPullParser.START_TAG) {
3078                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
3079                    continue;
3080                }
3081                if (!"preferred-activities".equals(parser.getName())) {
3082                    Slog.w(TAG, "Preferred apps file " + f
3083                            + " does not start with 'preferred-activities'");
3084                    continue;
3085                }
3086                readDefaultPreferredActivitiesLPw(service, parser, userId);
3087            } catch (XmlPullParserException e) {
3088                Slog.w(TAG, "Error reading apps file " + f, e);
3089            } catch (IOException e) {
3090                Slog.w(TAG, "Error reading apps file " + f, e);
3091            } finally {
3092                if (str != null) {
3093                    try {
3094                        str.close();
3095                    } catch (IOException e) {
3096                    }
3097                }
3098            }
3099        }
3100    }
3101
3102    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3103            IntentFilter tmpPa, ComponentName cn, int userId) {
3104        // The initial preferences only specify the target activity
3105        // component and intent-filter, not the set of matches.  So we
3106        // now need to query for the matches to build the correct
3107        // preferred activity entry.
3108        if (PackageManagerService.DEBUG_PREFERRED) {
3109            Log.d(TAG, "Processing preferred:");
3110            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
3111        }
3112        Intent intent = new Intent();
3113        int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE
3114                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
3115        intent.setAction(tmpPa.getAction(0));
3116        for (int i=0; i<tmpPa.countCategories(); i++) {
3117            String cat = tmpPa.getCategory(i);
3118            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
3119                flags |= MATCH_DEFAULT_ONLY;
3120            } else {
3121                intent.addCategory(cat);
3122            }
3123        }
3124
3125        boolean doNonData = true;
3126        boolean hasSchemes = false;
3127
3128        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3129            boolean doScheme = true;
3130            String scheme = tmpPa.getDataScheme(ischeme);
3131            if (scheme != null && !scheme.isEmpty()) {
3132                hasSchemes = true;
3133            }
3134            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
3135                Uri.Builder builder = new Uri.Builder();
3136                builder.scheme(scheme);
3137                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
3138                builder.opaquePart(ssp.getPath());
3139                Intent finalIntent = new Intent(intent);
3140                finalIntent.setData(builder.build());
3141                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3142                        scheme, ssp, null, null, userId);
3143                doScheme = false;
3144            }
3145            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
3146                boolean doAuth = true;
3147                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
3148                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
3149                    Uri.Builder builder = new Uri.Builder();
3150                    builder.scheme(scheme);
3151                    if (auth.getHost() != null) {
3152                        builder.authority(auth.getHost());
3153                    }
3154                    PatternMatcher path = tmpPa.getDataPath(ipath);
3155                    builder.path(path.getPath());
3156                    Intent finalIntent = new Intent(intent);
3157                    finalIntent.setData(builder.build());
3158                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3159                            scheme, null, auth, path, userId);
3160                    doAuth = doScheme = false;
3161                }
3162                if (doAuth) {
3163                    Uri.Builder builder = new Uri.Builder();
3164                    builder.scheme(scheme);
3165                    if (auth.getHost() != null) {
3166                        builder.authority(auth.getHost());
3167                    }
3168                    Intent finalIntent = new Intent(intent);
3169                    finalIntent.setData(builder.build());
3170                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3171                            scheme, null, auth, null, userId);
3172                    doScheme = false;
3173                }
3174            }
3175            if (doScheme) {
3176                Uri.Builder builder = new Uri.Builder();
3177                builder.scheme(scheme);
3178                Intent finalIntent = new Intent(intent);
3179                finalIntent.setData(builder.build());
3180                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3181                        scheme, null, null, null, userId);
3182            }
3183            doNonData = false;
3184        }
3185
3186        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
3187            String mimeType = tmpPa.getDataType(idata);
3188            if (hasSchemes) {
3189                Uri.Builder builder = new Uri.Builder();
3190                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
3191                    String scheme = tmpPa.getDataScheme(ischeme);
3192                    if (scheme != null && !scheme.isEmpty()) {
3193                        Intent finalIntent = new Intent(intent);
3194                        builder.scheme(scheme);
3195                        finalIntent.setDataAndType(builder.build(), mimeType);
3196                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3197                                scheme, null, null, null, userId);
3198                    }
3199                }
3200            } else {
3201                Intent finalIntent = new Intent(intent);
3202                finalIntent.setType(mimeType);
3203                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
3204                        null, null, null, null, userId);
3205            }
3206            doNonData = false;
3207        }
3208
3209        if (doNonData) {
3210            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
3211                    null, null, null, null, userId);
3212        }
3213    }
3214
3215    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
3216            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
3217            IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
3218        flags = service.updateFlagsForResolve(flags, userId, intent);
3219        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
3220                intent.getType(), flags, 0);
3221        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
3222                + " results: " + ri);
3223        int systemMatch = 0;
3224        int thirdPartyMatch = 0;
3225        if (ri != null && ri.size() > 1) {
3226            boolean haveAct = false;
3227            ComponentName haveNonSys = null;
3228            ComponentName[] set = new ComponentName[ri.size()];
3229            for (int i=0; i<ri.size(); i++) {
3230                ActivityInfo ai = ri.get(i).activityInfo;
3231                set[i] = new ComponentName(ai.packageName, ai.name);
3232                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3233                    if (ri.get(i).match >= thirdPartyMatch) {
3234                        // Keep track of the best match we find of all third
3235                        // party apps, for use later to determine if we actually
3236                        // want to set a preferred app for this intent.
3237                        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3238                                + ai.packageName + "/" + ai.name + ": non-system!");
3239                        haveNonSys = set[i];
3240                        break;
3241                    }
3242                } else if (cn.getPackageName().equals(ai.packageName)
3243                        && cn.getClassName().equals(ai.name)) {
3244                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3245                            + ai.packageName + "/" + ai.name + ": default!");
3246                    haveAct = true;
3247                    systemMatch = ri.get(i).match;
3248                } else {
3249                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3250                            + ai.packageName + "/" + ai.name + ": skipped");
3251                }
3252            }
3253            if (haveNonSys != null && thirdPartyMatch < systemMatch) {
3254                // If we have a matching third party app, but its match is not as
3255                // good as the built-in system app, then we don't want to actually
3256                // consider it a match because presumably the built-in app is still
3257                // the thing we want users to see by default.
3258                haveNonSys = null;
3259            }
3260            if (haveAct && haveNonSys == null) {
3261                IntentFilter filter = new IntentFilter();
3262                if (intent.getAction() != null) {
3263                    filter.addAction(intent.getAction());
3264                }
3265                if (intent.getCategories() != null) {
3266                    for (String cat : intent.getCategories()) {
3267                        filter.addCategory(cat);
3268                    }
3269                }
3270                if ((flags & MATCH_DEFAULT_ONLY) != 0) {
3271                    filter.addCategory(Intent.CATEGORY_DEFAULT);
3272                }
3273                if (scheme != null) {
3274                    filter.addDataScheme(scheme);
3275                }
3276                if (ssp != null) {
3277                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
3278                }
3279                if (auth != null) {
3280                    filter.addDataAuthority(auth);
3281                }
3282                if (path != null) {
3283                    filter.addDataPath(path);
3284                }
3285                if (intent.getType() != null) {
3286                    try {
3287                        filter.addDataType(intent.getType());
3288                    } catch (IntentFilter.MalformedMimeTypeException ex) {
3289                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
3290                    }
3291                }
3292                PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
3293                editPreferredActivitiesLPw(userId).addFilter(pa);
3294            } else if (haveNonSys == null) {
3295                StringBuilder sb = new StringBuilder();
3296                sb.append("No component ");
3297                sb.append(cn.flattenToShortString());
3298                sb.append(" found setting preferred ");
3299                sb.append(intent);
3300                sb.append("; possible matches are ");
3301                for (int i=0; i<set.length; i++) {
3302                    if (i > 0) sb.append(", ");
3303                    sb.append(set[i].flattenToShortString());
3304                }
3305                Slog.w(TAG, sb.toString());
3306            } else {
3307                Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
3308                        + haveNonSys.flattenToShortString());
3309            }
3310        } else {
3311            Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
3312                    + cn.flattenToShortString());
3313        }
3314    }
3315
3316    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
3317            XmlPullParser parser, int userId)
3318            throws XmlPullParserException, IOException {
3319        int outerDepth = parser.getDepth();
3320        int type;
3321        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3322                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3323            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3324                continue;
3325            }
3326
3327            String tagName = parser.getName();
3328            if (tagName.equals(TAG_ITEM)) {
3329                PreferredActivity tmpPa = new PreferredActivity(parser);
3330                if (tmpPa.mPref.getParseError() == null) {
3331                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
3332                            userId);
3333                } else {
3334                    PackageManagerService.reportSettingsProblem(Log.WARN,
3335                            "Error in package manager settings: <preferred-activity> "
3336                                    + tmpPa.mPref.getParseError() + " at "
3337                                    + parser.getPositionDescription());
3338                }
3339            } else {
3340                PackageManagerService.reportSettingsProblem(Log.WARN,
3341                        "Unknown element under <preferred-activities>: " + parser.getName());
3342                XmlUtils.skipCurrentTag(parser);
3343            }
3344        }
3345    }
3346
3347    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
3348        String v = parser.getAttributeValue(ns, name);
3349        try {
3350            if (v == null) {
3351                return defValue;
3352            }
3353            return Integer.parseInt(v);
3354        } catch (NumberFormatException e) {
3355            PackageManagerService.reportSettingsProblem(Log.WARN,
3356                    "Error in package manager settings: attribute " + name
3357                            + " has bad integer value " + v + " at "
3358                            + parser.getPositionDescription());
3359        }
3360        return defValue;
3361    }
3362
3363    private void readPermissionsLPw(ArrayMap<String, BasePermission> out, XmlPullParser parser)
3364            throws IOException, XmlPullParserException {
3365        int outerDepth = parser.getDepth();
3366        int type;
3367        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3368                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3369            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3370                continue;
3371            }
3372
3373            final String tagName = parser.getName();
3374            if (tagName.equals(TAG_ITEM)) {
3375                final String name = parser.getAttributeValue(null, ATTR_NAME);
3376                final String sourcePackage = parser.getAttributeValue(null, "package");
3377                final String ptype = parser.getAttributeValue(null, "type");
3378                if (name != null && sourcePackage != null) {
3379                    final boolean dynamic = "dynamic".equals(ptype);
3380                    BasePermission bp = out.get(name);
3381                    // If the permission is builtin, do not clobber it.
3382                    if (bp == null || bp.type != BasePermission.TYPE_BUILTIN) {
3383                        bp = new BasePermission(name.intern(), sourcePackage,
3384                                dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
3385                    }
3386                    bp.protectionLevel = readInt(parser, null, "protection",
3387                            PermissionInfo.PROTECTION_NORMAL);
3388                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
3389                    if (dynamic) {
3390                        PermissionInfo pi = new PermissionInfo();
3391                        pi.packageName = sourcePackage.intern();
3392                        pi.name = name.intern();
3393                        pi.icon = readInt(parser, null, "icon", 0);
3394                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
3395                        pi.protectionLevel = bp.protectionLevel;
3396                        bp.pendingInfo = pi;
3397                    }
3398                    out.put(bp.name, bp);
3399                } else {
3400                    PackageManagerService.reportSettingsProblem(Log.WARN,
3401                            "Error in package manager settings: permissions has" + " no name at "
3402                                    + parser.getPositionDescription());
3403                }
3404            } else {
3405                PackageManagerService.reportSettingsProblem(Log.WARN,
3406                        "Unknown element reading permissions: " + parser.getName() + " at "
3407                                + parser.getPositionDescription());
3408            }
3409            XmlUtils.skipCurrentTag(parser);
3410        }
3411    }
3412
3413    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
3414            IOException {
3415        String name = parser.getAttributeValue(null, ATTR_NAME);
3416        String realName = parser.getAttributeValue(null, "realName");
3417        String codePathStr = parser.getAttributeValue(null, "codePath");
3418        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3419
3420        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
3421        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3422
3423        String parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3424
3425        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
3426        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
3427        String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
3428
3429        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
3430            primaryCpuAbiStr = legacyCpuAbiStr;
3431        }
3432
3433        if (resourcePathStr == null) {
3434            resourcePathStr = codePathStr;
3435        }
3436        String version = parser.getAttributeValue(null, "version");
3437        int versionCode = 0;
3438        if (version != null) {
3439            try {
3440                versionCode = Integer.parseInt(version);
3441            } catch (NumberFormatException e) {
3442            }
3443        }
3444
3445        int pkgFlags = 0;
3446        int pkgPrivateFlags = 0;
3447        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3448        final File codePathFile = new File(codePathStr);
3449        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
3450            pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3451        }
3452        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
3453                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
3454                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
3455                parentPackageName, null /*childPackageNames*/, 0 /*sharedUserId*/);
3456        String timeStampStr = parser.getAttributeValue(null, "ft");
3457        if (timeStampStr != null) {
3458            try {
3459                long timeStamp = Long.parseLong(timeStampStr, 16);
3460                ps.setTimeStamp(timeStamp);
3461            } catch (NumberFormatException e) {
3462            }
3463        } else {
3464            timeStampStr = parser.getAttributeValue(null, "ts");
3465            if (timeStampStr != null) {
3466                try {
3467                    long timeStamp = Long.parseLong(timeStampStr);
3468                    ps.setTimeStamp(timeStamp);
3469                } catch (NumberFormatException e) {
3470                }
3471            }
3472        }
3473        timeStampStr = parser.getAttributeValue(null, "it");
3474        if (timeStampStr != null) {
3475            try {
3476                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
3477            } catch (NumberFormatException e) {
3478            }
3479        }
3480        timeStampStr = parser.getAttributeValue(null, "ut");
3481        if (timeStampStr != null) {
3482            try {
3483                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
3484            } catch (NumberFormatException e) {
3485            }
3486        }
3487        String idStr = parser.getAttributeValue(null, "userId");
3488        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
3489        if (ps.appId <= 0) {
3490            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3491            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3492        }
3493
3494        int outerDepth = parser.getDepth();
3495        int type;
3496        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3497                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3498            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3499                continue;
3500            }
3501
3502            if (parser.getName().equals(TAG_PERMISSIONS)) {
3503                readInstallPermissionsLPr(parser, ps.getPermissionsState());
3504            } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) {
3505                String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3506                if (ps.childPackageNames == null) {
3507                    ps.childPackageNames = new ArrayList<>();
3508                }
3509                ps.childPackageNames.add(childPackageName);
3510            } else {
3511                PackageManagerService.reportSettingsProblem(Log.WARN,
3512                        "Unknown element under <updated-package>: " + parser.getName());
3513                XmlUtils.skipCurrentTag(parser);
3514            }
3515        }
3516
3517        mDisabledSysPackages.put(name, ps);
3518    }
3519
3520    private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27;
3521    private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
3522    private static int PRE_M_APP_INFO_FLAG_FORWARD_LOCK = 1<<29;
3523    private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
3524
3525    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
3526        String name = null;
3527        String realName = null;
3528        String idStr = null;
3529        String sharedIdStr = null;
3530        String codePathStr = null;
3531        String resourcePathStr = null;
3532        String legacyCpuAbiString = null;
3533        String legacyNativeLibraryPathStr = null;
3534        String primaryCpuAbiString = null;
3535        String secondaryCpuAbiString = null;
3536        String cpuAbiOverrideString = null;
3537        String systemStr = null;
3538        String installerPackageName = null;
3539        String isOrphaned = null;
3540        String volumeUuid = null;
3541        String uidError = null;
3542        int pkgFlags = 0;
3543        int pkgPrivateFlags = 0;
3544        long timeStamp = 0;
3545        long firstInstallTime = 0;
3546        long lastUpdateTime = 0;
3547        PackageSetting packageSetting = null;
3548        String version = null;
3549        int versionCode = 0;
3550        String parentPackageName;
3551        try {
3552            name = parser.getAttributeValue(null, ATTR_NAME);
3553            realName = parser.getAttributeValue(null, "realName");
3554            idStr = parser.getAttributeValue(null, "userId");
3555            uidError = parser.getAttributeValue(null, "uidError");
3556            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3557            codePathStr = parser.getAttributeValue(null, "codePath");
3558            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3559
3560            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
3561
3562            parentPackageName = parser.getAttributeValue(null, "parentPackageName");
3563
3564            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3565            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
3566            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
3567            cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
3568
3569            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
3570                primaryCpuAbiString = legacyCpuAbiString;
3571            }
3572
3573            version = parser.getAttributeValue(null, "version");
3574            if (version != null) {
3575                try {
3576                    versionCode = Integer.parseInt(version);
3577                } catch (NumberFormatException e) {
3578                }
3579            }
3580            installerPackageName = parser.getAttributeValue(null, "installer");
3581            isOrphaned = parser.getAttributeValue(null, "isOrphaned");
3582            volumeUuid = parser.getAttributeValue(null, "volumeUuid");
3583
3584            systemStr = parser.getAttributeValue(null, "publicFlags");
3585            if (systemStr != null) {
3586                try {
3587                    pkgFlags = Integer.parseInt(systemStr);
3588                } catch (NumberFormatException e) {
3589                }
3590                systemStr = parser.getAttributeValue(null, "privateFlags");
3591                if (systemStr != null) {
3592                    try {
3593                        pkgPrivateFlags = Integer.parseInt(systemStr);
3594                    } catch (NumberFormatException e) {
3595                    }
3596                }
3597            } else {
3598                // Pre-M -- both public and private flags were stored in one "flags" field.
3599                systemStr = parser.getAttributeValue(null, "flags");
3600                if (systemStr != null) {
3601                    try {
3602                        pkgFlags = Integer.parseInt(systemStr);
3603                    } catch (NumberFormatException e) {
3604                    }
3605                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) {
3606                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
3607                    }
3608                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) {
3609                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
3610                    }
3611                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_FORWARD_LOCK) != 0) {
3612                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK;
3613                    }
3614                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) {
3615                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3616                    }
3617                    pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN
3618                            | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE
3619                            | PRE_M_APP_INFO_FLAG_FORWARD_LOCK
3620                            | PRE_M_APP_INFO_FLAG_PRIVILEGED);
3621                } else {
3622                    // For backward compatibility
3623                    systemStr = parser.getAttributeValue(null, "system");
3624                    if (systemStr != null) {
3625                        pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
3626                                : 0;
3627                    } else {
3628                        // Old settings that don't specify system... just treat
3629                        // them as system, good enough.
3630                        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3631                    }
3632                }
3633            }
3634            String timeStampStr = parser.getAttributeValue(null, "ft");
3635            if (timeStampStr != null) {
3636                try {
3637                    timeStamp = Long.parseLong(timeStampStr, 16);
3638                } catch (NumberFormatException e) {
3639                }
3640            } else {
3641                timeStampStr = parser.getAttributeValue(null, "ts");
3642                if (timeStampStr != null) {
3643                    try {
3644                        timeStamp = Long.parseLong(timeStampStr);
3645                    } catch (NumberFormatException e) {
3646                    }
3647                }
3648            }
3649            timeStampStr = parser.getAttributeValue(null, "it");
3650            if (timeStampStr != null) {
3651                try {
3652                    firstInstallTime = Long.parseLong(timeStampStr, 16);
3653                } catch (NumberFormatException e) {
3654                }
3655            }
3656            timeStampStr = parser.getAttributeValue(null, "ut");
3657            if (timeStampStr != null) {
3658                try {
3659                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
3660                } catch (NumberFormatException e) {
3661                }
3662            }
3663            if (PackageManagerService.DEBUG_SETTINGS)
3664                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
3665                        + " sharedUserId=" + sharedIdStr);
3666            final int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3667            final int sharedUserId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3668            if (resourcePathStr == null) {
3669                resourcePathStr = codePathStr;
3670            }
3671            if (realName != null) {
3672                realName = realName.intern();
3673            }
3674            if (name == null) {
3675                PackageManagerService.reportSettingsProblem(Log.WARN,
3676                        "Error in package manager settings: <package> has no name at "
3677                                + parser.getPositionDescription());
3678            } else if (codePathStr == null) {
3679                PackageManagerService.reportSettingsProblem(Log.WARN,
3680                        "Error in package manager settings: <package> has no codePath at "
3681                                + parser.getPositionDescription());
3682            } else if (userId > 0) {
3683                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
3684                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
3685                        secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
3686                        pkgPrivateFlags, parentPackageName, null /*childPackageNames*/);
3687                if (PackageManagerService.DEBUG_SETTINGS)
3688                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
3689                            + userId + " pkg=" + packageSetting);
3690                if (packageSetting == null) {
3691                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
3692                            + userId + " while parsing settings at "
3693                            + parser.getPositionDescription());
3694                } else {
3695                    packageSetting.setTimeStamp(timeStamp);
3696                    packageSetting.firstInstallTime = firstInstallTime;
3697                    packageSetting.lastUpdateTime = lastUpdateTime;
3698                }
3699            } else if (sharedIdStr != null) {
3700                if (sharedUserId > 0) {
3701                    packageSetting = new PackageSetting(name.intern(), realName, new File(
3702                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
3703                            primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
3704                            versionCode, pkgFlags, pkgPrivateFlags, parentPackageName,
3705                            null /*childPackageNames*/, sharedUserId);
3706                    packageSetting.setTimeStamp(timeStamp);
3707                    packageSetting.firstInstallTime = firstInstallTime;
3708                    packageSetting.lastUpdateTime = lastUpdateTime;
3709                    mPendingPackages.add(packageSetting);
3710                    if (PackageManagerService.DEBUG_SETTINGS)
3711                        Log.i(PackageManagerService.TAG, "Reading package " + name
3712                                + ": sharedUserId=" + sharedUserId + " pkg=" + packageSetting);
3713                } else {
3714                    PackageManagerService.reportSettingsProblem(Log.WARN,
3715                            "Error in package manager settings: package " + name
3716                                    + " has bad sharedId " + sharedIdStr + " at "
3717                                    + parser.getPositionDescription());
3718                }
3719            } else {
3720                PackageManagerService.reportSettingsProblem(Log.WARN,
3721                        "Error in package manager settings: package " + name + " has bad userId "
3722                                + idStr + " at " + parser.getPositionDescription());
3723            }
3724        } catch (NumberFormatException e) {
3725            PackageManagerService.reportSettingsProblem(Log.WARN,
3726                    "Error in package manager settings: package " + name + " has bad userId "
3727                            + idStr + " at " + parser.getPositionDescription());
3728        }
3729        if (packageSetting != null) {
3730            packageSetting.uidError = "true".equals(uidError);
3731            packageSetting.installerPackageName = installerPackageName;
3732            packageSetting.isOrphaned = "true".equals(isOrphaned);
3733            packageSetting.volumeUuid = volumeUuid;
3734            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
3735            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
3736            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
3737            // Handle legacy string here for single-user mode
3738            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
3739            if (enabledStr != null) {
3740                try {
3741                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
3742                } catch (NumberFormatException e) {
3743                    if (enabledStr.equalsIgnoreCase("true")) {
3744                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
3745                    } else if (enabledStr.equalsIgnoreCase("false")) {
3746                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
3747                    } else if (enabledStr.equalsIgnoreCase("default")) {
3748                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3749                    } else {
3750                        PackageManagerService.reportSettingsProblem(Log.WARN,
3751                                "Error in package manager settings: package " + name
3752                                        + " has bad enabled value: " + idStr + " at "
3753                                        + parser.getPositionDescription());
3754                    }
3755                }
3756            } else {
3757                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3758            }
3759
3760            if (installerPackageName != null) {
3761                mInstallerPackages.add(installerPackageName);
3762            }
3763
3764            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
3765            if (installStatusStr != null) {
3766                if (installStatusStr.equalsIgnoreCase("false")) {
3767                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
3768                } else {
3769                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
3770                }
3771            }
3772
3773            int outerDepth = parser.getDepth();
3774            int type;
3775            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3776                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3777                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3778                    continue;
3779                }
3780
3781                String tagName = parser.getName();
3782                // Legacy
3783                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
3784                    readDisabledComponentsLPw(packageSetting, parser, 0);
3785                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
3786                    readEnabledComponentsLPw(packageSetting, parser, 0);
3787                } else if (tagName.equals("sigs")) {
3788                    packageSetting.signatures.readXml(parser, mPastSignatures);
3789                } else if (tagName.equals(TAG_PERMISSIONS)) {
3790                    readInstallPermissionsLPr(parser,
3791                            packageSetting.getPermissionsState());
3792                    packageSetting.installPermissionsFixed = true;
3793                } else if (tagName.equals("proper-signing-keyset")) {
3794                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3795                    Integer refCt = mKeySetRefs.get(id);
3796                    if (refCt != null) {
3797                        mKeySetRefs.put(id, refCt + 1);
3798                    } else {
3799                        mKeySetRefs.put(id, 1);
3800                    }
3801                    packageSetting.keySetData.setProperSigningKeySet(id);
3802                } else if (tagName.equals("signing-keyset")) {
3803                    // from v1 of keysetmanagerservice - no longer used
3804                } else if (tagName.equals("upgrade-keyset")) {
3805                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3806                    packageSetting.keySetData.addUpgradeKeySetById(id);
3807                } else if (tagName.equals("defined-keyset")) {
3808                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3809                    String alias = parser.getAttributeValue(null, "alias");
3810                    Integer refCt = mKeySetRefs.get(id);
3811                    if (refCt != null) {
3812                        mKeySetRefs.put(id, refCt + 1);
3813                    } else {
3814                        mKeySetRefs.put(id, 1);
3815                    }
3816                    packageSetting.keySetData.addDefinedKeySet(id, alias);
3817                } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
3818                    readDomainVerificationLPw(parser, packageSetting);
3819                } else if (tagName.equals(TAG_CHILD_PACKAGE)) {
3820                    String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
3821                    if (packageSetting.childPackageNames == null) {
3822                        packageSetting.childPackageNames = new ArrayList<>();
3823                    }
3824                    packageSetting.childPackageNames.add(childPackageName);
3825                } else {
3826                    PackageManagerService.reportSettingsProblem(Log.WARN,
3827                            "Unknown element under <package>: " + parser.getName());
3828                    XmlUtils.skipCurrentTag(parser);
3829                }
3830            }
3831        } else {
3832            XmlUtils.skipCurrentTag(parser);
3833        }
3834    }
3835
3836    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3837            int userId) throws IOException, XmlPullParserException {
3838        int outerDepth = parser.getDepth();
3839        int type;
3840        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3841                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3842            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3843                continue;
3844            }
3845
3846            String tagName = parser.getName();
3847            if (tagName.equals(TAG_ITEM)) {
3848                String name = parser.getAttributeValue(null, ATTR_NAME);
3849                if (name != null) {
3850                    packageSetting.addDisabledComponent(name.intern(), userId);
3851                } else {
3852                    PackageManagerService.reportSettingsProblem(Log.WARN,
3853                            "Error in package manager settings: <disabled-components> has"
3854                                    + " no name at " + parser.getPositionDescription());
3855                }
3856            } else {
3857                PackageManagerService.reportSettingsProblem(Log.WARN,
3858                        "Unknown element under <disabled-components>: " + parser.getName());
3859            }
3860            XmlUtils.skipCurrentTag(parser);
3861        }
3862    }
3863
3864    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3865            int userId) throws IOException, XmlPullParserException {
3866        int outerDepth = parser.getDepth();
3867        int type;
3868        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3869                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3870            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3871                continue;
3872            }
3873
3874            String tagName = parser.getName();
3875            if (tagName.equals(TAG_ITEM)) {
3876                String name = parser.getAttributeValue(null, ATTR_NAME);
3877                if (name != null) {
3878                    packageSetting.addEnabledComponent(name.intern(), userId);
3879                } else {
3880                    PackageManagerService.reportSettingsProblem(Log.WARN,
3881                            "Error in package manager settings: <enabled-components> has"
3882                                    + " no name at " + parser.getPositionDescription());
3883                }
3884            } else {
3885                PackageManagerService.reportSettingsProblem(Log.WARN,
3886                        "Unknown element under <enabled-components>: " + parser.getName());
3887            }
3888            XmlUtils.skipCurrentTag(parser);
3889        }
3890    }
3891
3892    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
3893        String name = null;
3894        String idStr = null;
3895        int pkgFlags = 0;
3896        int pkgPrivateFlags = 0;
3897        SharedUserSetting su = null;
3898        try {
3899            name = parser.getAttributeValue(null, ATTR_NAME);
3900            idStr = parser.getAttributeValue(null, "userId");
3901            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3902            if ("true".equals(parser.getAttributeValue(null, "system"))) {
3903                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3904            }
3905            if (name == null) {
3906                PackageManagerService.reportSettingsProblem(Log.WARN,
3907                        "Error in package manager settings: <shared-user> has no name at "
3908                                + parser.getPositionDescription());
3909            } else if (userId == 0) {
3910                PackageManagerService.reportSettingsProblem(Log.WARN,
3911                        "Error in package manager settings: shared-user " + name
3912                                + " has bad userId " + idStr + " at "
3913                                + parser.getPositionDescription());
3914            } else {
3915                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
3916                        == null) {
3917                    PackageManagerService
3918                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
3919                                    + parser.getPositionDescription());
3920                }
3921            }
3922        } catch (NumberFormatException e) {
3923            PackageManagerService.reportSettingsProblem(Log.WARN,
3924                    "Error in package manager settings: package " + name + " has bad userId "
3925                            + idStr + " at " + parser.getPositionDescription());
3926        }
3927
3928        if (su != null) {
3929            int outerDepth = parser.getDepth();
3930            int type;
3931            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3932                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3933                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3934                    continue;
3935                }
3936
3937                String tagName = parser.getName();
3938                if (tagName.equals("sigs")) {
3939                    su.signatures.readXml(parser, mPastSignatures);
3940                } else if (tagName.equals("perms")) {
3941                    readInstallPermissionsLPr(parser, su.getPermissionsState());
3942                } else {
3943                    PackageManagerService.reportSettingsProblem(Log.WARN,
3944                            "Unknown element under <shared-user>: " + parser.getName());
3945                    XmlUtils.skipCurrentTag(parser);
3946                }
3947            }
3948        } else {
3949            XmlUtils.skipCurrentTag(parser);
3950        }
3951    }
3952
3953    void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
3954            int userHandle, String[] disallowedPackages) {
3955        String[] volumeUuids;
3956        String[] names;
3957        int[] appIds;
3958        String[] seinfos;
3959        int[] targetSdkVersions;
3960        int packagesCount;
3961        synchronized (mPackages) {
3962            Collection<PackageSetting> packages = mPackages.values();
3963            packagesCount = packages.size();
3964            volumeUuids = new String[packagesCount];
3965            names = new String[packagesCount];
3966            appIds = new int[packagesCount];
3967            seinfos = new String[packagesCount];
3968            targetSdkVersions = new int[packagesCount];
3969            Iterator<PackageSetting> packagesIterator = packages.iterator();
3970            for (int i = 0; i < packagesCount; i++) {
3971                PackageSetting ps = packagesIterator.next();
3972                if (ps.pkg == null || ps.pkg.applicationInfo == null) {
3973                    continue;
3974                }
3975                final boolean shouldInstall = ps.isSystem() &&
3976                        !ArrayUtils.contains(disallowedPackages, ps.name);
3977                // Only system apps are initially installed.
3978                ps.setInstalled(shouldInstall, userHandle);
3979                // Need to create a data directory for all apps under this user. Accumulate all
3980                // required args and call the installer after mPackages lock has been released
3981                volumeUuids[i] = ps.volumeUuid;
3982                names[i] = ps.name;
3983                appIds[i] = ps.appId;
3984                seinfos[i] = ps.pkg.applicationInfo.seinfo;
3985                targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
3986            }
3987        }
3988        for (int i = 0; i < packagesCount; i++) {
3989            if (names[i] == null) {
3990                continue;
3991            }
3992            // TODO: triage flags!
3993            final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
3994            try {
3995                installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
3996                        seinfos[i], targetSdkVersions[i]);
3997            } catch (InstallerException e) {
3998                Slog.w(TAG, "Failed to prepare app data", e);
3999            }
4000        }
4001        synchronized (mPackages) {
4002            applyDefaultPreferredAppsLPw(service, userHandle);
4003        }
4004    }
4005
4006    void removeUserLPw(int userId) {
4007        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
4008        for (Entry<String, PackageSetting> entry : entries) {
4009            entry.getValue().removeUser(userId);
4010        }
4011        mPreferredActivities.remove(userId);
4012        File file = getUserPackagesStateFile(userId);
4013        file.delete();
4014        file = getUserPackagesStateBackupFile(userId);
4015        file.delete();
4016        removeCrossProfileIntentFiltersLPw(userId);
4017
4018        mRuntimePermissionsPersistence.onUserRemovedLPw(userId);
4019
4020        writePackageListLPr();
4021    }
4022
4023    void removeCrossProfileIntentFiltersLPw(int userId) {
4024        synchronized (mCrossProfileIntentResolvers) {
4025            // userId is the source user
4026            if (mCrossProfileIntentResolvers.get(userId) != null) {
4027                mCrossProfileIntentResolvers.remove(userId);
4028                writePackageRestrictionsLPr(userId);
4029            }
4030            // userId is the target user
4031            int count = mCrossProfileIntentResolvers.size();
4032            for (int i = 0; i < count; i++) {
4033                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
4034                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
4035                boolean needsWriting = false;
4036                ArraySet<CrossProfileIntentFilter> cpifs =
4037                        new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
4038                for (CrossProfileIntentFilter cpif : cpifs) {
4039                    if (cpif.getTargetUserId() == userId) {
4040                        needsWriting = true;
4041                        cpir.removeFilter(cpif);
4042                    }
4043                }
4044                if (needsWriting) {
4045                    writePackageRestrictionsLPr(sourceUserId);
4046                }
4047            }
4048        }
4049    }
4050
4051    // This should be called (at least) whenever an application is removed
4052    private void setFirstAvailableUid(int uid) {
4053        if (uid > mFirstAvailableUid) {
4054            mFirstAvailableUid = uid;
4055        }
4056    }
4057
4058    // Returns -1 if we could not find an available UserId to assign
4059    private int newUserIdLPw(Object obj) {
4060        // Let's be stupidly inefficient for now...
4061        final int N = mUserIds.size();
4062        for (int i = mFirstAvailableUid; i < N; i++) {
4063            if (mUserIds.get(i) == null) {
4064                mUserIds.set(i, obj);
4065                return Process.FIRST_APPLICATION_UID + i;
4066            }
4067        }
4068
4069        // None left?
4070        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
4071            return -1;
4072        }
4073
4074        mUserIds.add(obj);
4075        return Process.FIRST_APPLICATION_UID + N;
4076    }
4077
4078    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
4079        if (mVerifierDeviceIdentity == null) {
4080            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
4081
4082            writeLPr();
4083        }
4084
4085        return mVerifierDeviceIdentity;
4086    }
4087
4088    boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
4089            String childPackageName) {
4090        final int packageCount = mDisabledSysPackages.size();
4091        for (int i = 0; i < packageCount; i++) {
4092            PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
4093            if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
4094                continue;
4095            }
4096            if (disabledPs.name.equals(parentPackageName)) {
4097                continue;
4098            }
4099            final int childCount = disabledPs.childPackageNames.size();
4100            for (int j = 0; j < childCount; j++) {
4101                String currChildPackageName = disabledPs.childPackageNames.get(j);
4102                if (currChildPackageName.equals(childPackageName)) {
4103                    return true;
4104                }
4105            }
4106        }
4107        return false;
4108    }
4109
4110    public PackageSetting getDisabledSystemPkgLPr(String name) {
4111        PackageSetting ps = mDisabledSysPackages.get(name);
4112        return ps;
4113    }
4114
4115    private String compToString(ArraySet<String> cmp) {
4116        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
4117    }
4118
4119    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
4120        final PackageSetting ps = mPackages.get(componentInfo.packageName);
4121        if (ps == null) return false;
4122
4123        final PackageUserState userState = ps.readUserState(userId);
4124        return userState.isMatch(componentInfo, flags);
4125    }
4126
4127    String getInstallerPackageNameLPr(String packageName) {
4128        final PackageSetting pkg = mPackages.get(packageName);
4129        if (pkg == null) {
4130            throw new IllegalArgumentException("Unknown package: " + packageName);
4131        }
4132        return pkg.installerPackageName;
4133    }
4134
4135    boolean isOrphaned(String packageName) {
4136        final PackageSetting pkg = mPackages.get(packageName);
4137        if (pkg == null) {
4138            throw new IllegalArgumentException("Unknown package: " + packageName);
4139        }
4140        return pkg.isOrphaned;
4141    }
4142
4143    int getApplicationEnabledSettingLPr(String packageName, int userId) {
4144        final PackageSetting pkg = mPackages.get(packageName);
4145        if (pkg == null) {
4146            throw new IllegalArgumentException("Unknown package: " + packageName);
4147        }
4148        return pkg.getEnabled(userId);
4149    }
4150
4151    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
4152        final String packageName = componentName.getPackageName();
4153        final PackageSetting pkg = mPackages.get(packageName);
4154        if (pkg == null) {
4155            throw new IllegalArgumentException("Unknown component: " + componentName);
4156        }
4157        final String classNameStr = componentName.getClassName();
4158        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
4159    }
4160
4161    boolean wasPackageEverLaunchedLPr(String packageName, int userId) {
4162        final PackageSetting pkgSetting = mPackages.get(packageName);
4163        if (pkgSetting == null) {
4164            throw new IllegalArgumentException("Unknown package: " + packageName);
4165        }
4166        return !pkgSetting.getNotLaunched(userId);
4167    }
4168
4169    boolean setPackageStoppedStateLPw(PackageManagerService pm, String packageName,
4170            boolean stopped, boolean allowedByPermission, int uid, int userId) {
4171        int appId = UserHandle.getAppId(uid);
4172        final PackageSetting pkgSetting = mPackages.get(packageName);
4173        if (pkgSetting == null) {
4174            throw new IllegalArgumentException("Unknown package: " + packageName);
4175        }
4176        if (!allowedByPermission && (appId != pkgSetting.appId)) {
4177            throw new SecurityException(
4178                    "Permission Denial: attempt to change stopped state from pid="
4179                    + Binder.getCallingPid()
4180                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
4181        }
4182        if (DEBUG_STOPPED) {
4183            if (stopped) {
4184                RuntimeException e = new RuntimeException("here");
4185                e.fillInStackTrace();
4186                Slog.i(TAG, "Stopping package " + packageName, e);
4187            }
4188        }
4189        if (pkgSetting.getStopped(userId) != stopped) {
4190            pkgSetting.setStopped(stopped, userId);
4191            // pkgSetting.pkg.mSetStopped = stopped;
4192            if (pkgSetting.getNotLaunched(userId)) {
4193                if (pkgSetting.installerPackageName != null) {
4194                    pm.notifyFirstLaunch(pkgSetting.name, pkgSetting.installerPackageName, userId);
4195                }
4196                pkgSetting.setNotLaunched(false, userId);
4197            }
4198            return true;
4199        }
4200        return false;
4201    }
4202
4203    private static List<UserInfo> getAllUsers(UserManagerService userManager) {
4204        long id = Binder.clearCallingIdentity();
4205        try {
4206            return userManager.getUsers(false);
4207        } catch (NullPointerException npe) {
4208            // packagemanager not yet initialized
4209        } finally {
4210            Binder.restoreCallingIdentity(id);
4211        }
4212        return null;
4213    }
4214
4215    /**
4216     * Return all {@link PackageSetting} that are actively installed on the
4217     * given {@link VolumeInfo#fsUuid}.
4218     */
4219    List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
4220        ArrayList<PackageSetting> res = new ArrayList<>();
4221        for (int i = 0; i < mPackages.size(); i++) {
4222            final PackageSetting setting = mPackages.valueAt(i);
4223            if (Objects.equals(volumeUuid, setting.volumeUuid)) {
4224                res.add(setting);
4225            }
4226        }
4227        return res;
4228    }
4229
4230    static void printFlags(PrintWriter pw, int val, Object[] spec) {
4231        pw.print("[ ");
4232        for (int i=0; i<spec.length; i+=2) {
4233            int mask = (Integer)spec[i];
4234            if ((val & mask) != 0) {
4235                pw.print(spec[i+1]);
4236                pw.print(" ");
4237            }
4238        }
4239        pw.print("]");
4240    }
4241
4242    static final Object[] FLAG_DUMP_SPEC = new Object[] {
4243        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4244        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4245        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4246        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4247        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4248        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4249        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4250        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4251        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4252        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4253        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4254        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4255        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4256        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4257        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4258    };
4259
4260    private static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4261        ApplicationInfo.PRIVATE_FLAG_HIDDEN, "HIDDEN",
4262        ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4263        ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK",
4264        ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4265        ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
4266        ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
4267        ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
4268        ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
4269        ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL",
4270        ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
4271        ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET, "RESIZEABLE_ACTIVITIES_EXPLICITLY_SET",
4272        ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION, "RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION",
4273        ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
4274    };
4275
4276    void dumpVersionLPr(IndentingPrintWriter pw) {
4277        pw.increaseIndent();
4278        for (int i= 0; i < mVersion.size(); i++) {
4279            final String volumeUuid = mVersion.keyAt(i);
4280            final VersionInfo ver = mVersion.valueAt(i);
4281            if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4282                pw.println("Internal:");
4283            } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4284                pw.println("External:");
4285            } else {
4286                pw.println("UUID " + volumeUuid + ":");
4287            }
4288            pw.increaseIndent();
4289            pw.printPair("sdkVersion", ver.sdkVersion);
4290            pw.printPair("databaseVersion", ver.databaseVersion);
4291            pw.println();
4292            pw.printPair("fingerprint", ver.fingerprint);
4293            pw.println();
4294            pw.decreaseIndent();
4295        }
4296        pw.decreaseIndent();
4297    }
4298
4299    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4300            ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4301            Date date, List<UserInfo> users, boolean dumpAll) {
4302        if (checkinTag != null) {
4303            pw.print(checkinTag);
4304            pw.print(",");
4305            pw.print(ps.realName != null ? ps.realName : ps.name);
4306            pw.print(",");
4307            pw.print(ps.appId);
4308            pw.print(",");
4309            pw.print(ps.versionCode);
4310            pw.print(",");
4311            pw.print(ps.firstInstallTime);
4312            pw.print(",");
4313            pw.print(ps.lastUpdateTime);
4314            pw.print(",");
4315            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4316            pw.println();
4317            if (ps.pkg != null) {
4318                pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4319                pw.print("base,");
4320                pw.println(ps.pkg.baseRevisionCode);
4321                if (ps.pkg.splitNames != null) {
4322                    for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4323                        pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4324                        pw.print(ps.pkg.splitNames[i]); pw.print(",");
4325                        pw.println(ps.pkg.splitRevisionCodes[i]);
4326                    }
4327                }
4328            }
4329            for (UserInfo user : users) {
4330                pw.print(checkinTag);
4331                pw.print("-");
4332                pw.print("usr");
4333                pw.print(",");
4334                pw.print(user.id);
4335                pw.print(",");
4336                pw.print(ps.getInstalled(user.id) ? "I" : "i");
4337                pw.print(ps.getHidden(user.id) ? "B" : "b");
4338                pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4339                pw.print(ps.getStopped(user.id) ? "S" : "s");
4340                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4341                pw.print(",");
4342                pw.print(ps.getEnabled(user.id));
4343                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4344                pw.print(",");
4345                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4346                pw.println();
4347            }
4348            return;
4349        }
4350
4351        pw.print(prefix); pw.print("Package [");
4352            pw.print(ps.realName != null ? ps.realName : ps.name);
4353            pw.print("] (");
4354            pw.print(Integer.toHexString(System.identityHashCode(ps)));
4355            pw.println("):");
4356
4357        if (ps.realName != null) {
4358            pw.print(prefix); pw.print("  compat name=");
4359            pw.println(ps.name);
4360        }
4361
4362        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4363
4364        if (ps.sharedUser != null) {
4365            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4366        }
4367        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4368        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4369        if (permissionNames == null) {
4370            pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4371            pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4372            pw.println(ps.legacyNativeLibraryPathString);
4373            pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4374            pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4375        }
4376        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4377        if (ps.pkg != null) {
4378            pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion);
4379            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4380        }
4381        pw.println();
4382        if (ps.pkg != null) {
4383            if (ps.pkg.parentPackage != null) {
4384                PackageParser.Package parentPkg = ps.pkg.parentPackage;
4385                PackageSetting pps = mPackages.get(parentPkg.packageName);
4386                if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
4387                    pps = mDisabledSysPackages.get(parentPkg.packageName);
4388                }
4389                if (pps != null) {
4390                    pw.print(prefix); pw.print("  parentPackage=");
4391                    pw.println(pps.realName != null ? pps.realName : pps.name);
4392                }
4393            } else if (ps.pkg.childPackages != null) {
4394                pw.print(prefix); pw.print("  childPackages=[");
4395                final int childCount = ps.pkg.childPackages.size();
4396                for (int i = 0; i < childCount; i++) {
4397                    PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
4398                    PackageSetting cps = mPackages.get(childPkg.packageName);
4399                    if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
4400                        cps = mDisabledSysPackages.get(childPkg.packageName);
4401                    }
4402                    if (cps != null) {
4403                        if (i > 0) {
4404                            pw.print(", ");
4405                        }
4406                        pw.print(cps.realName != null ? cps.realName : cps.name);
4407                    }
4408                }
4409                pw.println("]");
4410            }
4411            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4412            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4413            final int apkSigningVersion = PackageParser.getApkSigningVersion(ps.pkg);
4414            if (apkSigningVersion != PackageParser.APK_SIGNING_UNKNOWN) {
4415                pw.print(prefix); pw.print("  apkSigningVersion="); pw.println(apkSigningVersion);
4416            }
4417            pw.print(prefix); pw.print("  applicationInfo=");
4418                pw.println(ps.pkg.applicationInfo.toString());
4419            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4420                    FLAG_DUMP_SPEC); pw.println();
4421            if (ps.pkg.applicationInfo.privateFlags != 0) {
4422                pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4423                        ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4424            }
4425            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4426            pw.print(prefix); pw.print("  supportsScreens=[");
4427            boolean first = true;
4428            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4429                if (!first)
4430                    pw.print(", ");
4431                first = false;
4432                pw.print("small");
4433            }
4434            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4435                if (!first)
4436                    pw.print(", ");
4437                first = false;
4438                pw.print("medium");
4439            }
4440            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4441                if (!first)
4442                    pw.print(", ");
4443                first = false;
4444                pw.print("large");
4445            }
4446            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4447                if (!first)
4448                    pw.print(", ");
4449                first = false;
4450                pw.print("xlarge");
4451            }
4452            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4453                if (!first)
4454                    pw.print(", ");
4455                first = false;
4456                pw.print("resizeable");
4457            }
4458            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4459                if (!first)
4460                    pw.print(", ");
4461                first = false;
4462                pw.print("anyDensity");
4463            }
4464            pw.println("]");
4465            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4466                pw.print(prefix); pw.println("  libraries:");
4467                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
4468                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
4469                }
4470            }
4471            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4472                pw.print(prefix); pw.println("  usesLibraries:");
4473                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4474                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4475                }
4476            }
4477            if (ps.pkg.usesOptionalLibraries != null
4478                    && ps.pkg.usesOptionalLibraries.size() > 0) {
4479                pw.print(prefix); pw.println("  usesOptionalLibraries:");
4480                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4481                    pw.print(prefix); pw.print("    ");
4482                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
4483                }
4484            }
4485            if (ps.pkg.usesLibraryFiles != null
4486                    && ps.pkg.usesLibraryFiles.length > 0) {
4487                pw.print(prefix); pw.println("  usesLibraryFiles:");
4488                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4489                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4490                }
4491            }
4492        }
4493        pw.print(prefix); pw.print("  timeStamp=");
4494            date.setTime(ps.timeStamp);
4495            pw.println(sdf.format(date));
4496        pw.print(prefix); pw.print("  firstInstallTime=");
4497            date.setTime(ps.firstInstallTime);
4498            pw.println(sdf.format(date));
4499        pw.print(prefix); pw.print("  lastUpdateTime=");
4500            date.setTime(ps.lastUpdateTime);
4501            pw.println(sdf.format(date));
4502        if (ps.installerPackageName != null) {
4503            pw.print(prefix); pw.print("  installerPackageName=");
4504                    pw.println(ps.installerPackageName);
4505        }
4506        if (ps.volumeUuid != null) {
4507            pw.print(prefix); pw.print("  volumeUuid=");
4508                    pw.println(ps.volumeUuid);
4509        }
4510        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4511        pw.print(prefix); pw.print("  installPermissionsFixed=");
4512                pw.print(ps.installPermissionsFixed);
4513                pw.print(" installStatus="); pw.println(ps.installStatus);
4514        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4515                pw.println();
4516
4517        if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4518            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4519            pw.print(prefix); pw.println("  declared permissions:");
4520            for (int i=0; i<perms.size(); i++) {
4521                PackageParser.Permission perm = perms.get(i);
4522                if (permissionNames != null
4523                        && !permissionNames.contains(perm.info.name)) {
4524                    continue;
4525                }
4526                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4527                pw.print(": prot=");
4528                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4529                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4530                    pw.print(", COSTS_MONEY");
4531                }
4532                if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
4533                    pw.print(", HIDDEN");
4534                }
4535                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4536                    pw.print(", INSTALLED");
4537                }
4538                pw.println();
4539            }
4540        }
4541
4542        if ((permissionNames != null || dumpAll) && ps.pkg != null
4543                && ps.pkg.requestedPermissions != null
4544                && ps.pkg.requestedPermissions.size() > 0) {
4545            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4546            pw.print(prefix); pw.println("  requested permissions:");
4547            for (int i=0; i<perms.size(); i++) {
4548                String perm = perms.get(i);
4549                if (permissionNames != null
4550                        && !permissionNames.contains(perm)) {
4551                    continue;
4552                }
4553                pw.print(prefix); pw.print("    "); pw.println(perm);
4554            }
4555        }
4556
4557        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4558            PermissionsState permissionsState = ps.getPermissionsState();
4559            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4560        }
4561
4562        for (UserInfo user : users) {
4563            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4564            pw.print("ceDataInode=");
4565            pw.print(ps.getCeDataInode(user.id));
4566            pw.print(" installed=");
4567            pw.print(ps.getInstalled(user.id));
4568            pw.print(" hidden=");
4569            pw.print(ps.getHidden(user.id));
4570            pw.print(" suspended=");
4571            pw.print(ps.getSuspended(user.id));
4572            pw.print(" stopped=");
4573            pw.print(ps.getStopped(user.id));
4574            pw.print(" notLaunched=");
4575            pw.print(ps.getNotLaunched(user.id));
4576            pw.print(" enabled=");
4577            pw.println(ps.getEnabled(user.id));
4578            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4579            if (lastDisabledAppCaller != null) {
4580                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4581                        pw.println(lastDisabledAppCaller);
4582            }
4583
4584            if (ps.sharedUser == null) {
4585                PermissionsState permissionsState = ps.getPermissionsState();
4586                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4587                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4588                        .getRuntimePermissionStates(user.id), dumpAll);
4589            }
4590
4591            if (permissionNames == null) {
4592                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4593                if (cmp != null && cmp.size() > 0) {
4594                    pw.print(prefix); pw.println("    disabledComponents:");
4595                    for (String s : cmp) {
4596                        pw.print(prefix); pw.print("      "); pw.println(s);
4597                    }
4598                }
4599                cmp = ps.getEnabledComponents(user.id);
4600                if (cmp != null && cmp.size() > 0) {
4601                    pw.print(prefix); pw.println("    enabledComponents:");
4602                    for (String s : cmp) {
4603                        pw.print(prefix); pw.print("      "); pw.println(s);
4604                    }
4605                }
4606            }
4607        }
4608    }
4609
4610    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4611            DumpState dumpState, boolean checkin) {
4612        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4613        final Date date = new Date();
4614        boolean printedSomething = false;
4615        List<UserInfo> users = getAllUsers(UserManagerService.getInstance());
4616        for (final PackageSetting ps : mPackages.values()) {
4617            if (packageName != null && !packageName.equals(ps.realName)
4618                    && !packageName.equals(ps.name)) {
4619                continue;
4620            }
4621            if (permissionNames != null
4622                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4623                continue;
4624            }
4625
4626            if (!checkin && packageName != null) {
4627                dumpState.setSharedUser(ps.sharedUser);
4628            }
4629
4630            if (!checkin && !printedSomething) {
4631                if (dumpState.onTitlePrinted())
4632                    pw.println();
4633                pw.println("Packages:");
4634                printedSomething = true;
4635            }
4636            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4637                    packageName != null);
4638        }
4639
4640        printedSomething = false;
4641        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4642            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4643                if (packageName != null && !packageName.equals(e.getKey())
4644                        && !packageName.equals(e.getValue())) {
4645                    continue;
4646                }
4647                if (!checkin) {
4648                    if (!printedSomething) {
4649                        if (dumpState.onTitlePrinted())
4650                            pw.println();
4651                        pw.println("Renamed packages:");
4652                        printedSomething = true;
4653                    }
4654                    pw.print("  ");
4655                } else {
4656                    pw.print("ren,");
4657                }
4658                pw.print(e.getKey());
4659                pw.print(checkin ? " -> " : ",");
4660                pw.println(e.getValue());
4661            }
4662        }
4663
4664        printedSomething = false;
4665        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4666            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4667                if (packageName != null && !packageName.equals(ps.realName)
4668                        && !packageName.equals(ps.name)) {
4669                    continue;
4670                }
4671                if (!checkin && !printedSomething) {
4672                    if (dumpState.onTitlePrinted())
4673                        pw.println();
4674                    pw.println("Hidden system packages:");
4675                    printedSomething = true;
4676                }
4677                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4678                        users, packageName != null);
4679            }
4680        }
4681    }
4682
4683    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4684            DumpState dumpState) {
4685        boolean printedSomething = false;
4686        for (BasePermission p : mPermissions.values()) {
4687            if (packageName != null && !packageName.equals(p.sourcePackage)) {
4688                continue;
4689            }
4690            if (permissionNames != null && !permissionNames.contains(p.name)) {
4691                continue;
4692            }
4693            if (!printedSomething) {
4694                if (dumpState.onTitlePrinted())
4695                    pw.println();
4696                pw.println("Permissions:");
4697                printedSomething = true;
4698            }
4699            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
4700                    pw.print(Integer.toHexString(System.identityHashCode(p)));
4701                    pw.println("):");
4702            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
4703            pw.print("    uid="); pw.print(p.uid);
4704                    pw.print(" gids="); pw.print(Arrays.toString(
4705                            p.computeGids(UserHandle.USER_SYSTEM)));
4706                    pw.print(" type="); pw.print(p.type);
4707                    pw.print(" prot=");
4708                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
4709            if (p.perm != null) {
4710                pw.print("    perm="); pw.println(p.perm);
4711                if ((p.perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0
4712                        || (p.perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0) {
4713                    pw.print("    flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags));
4714                }
4715            }
4716            if (p.packageSetting != null) {
4717                pw.print("    packageSetting="); pw.println(p.packageSetting);
4718            }
4719            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
4720                pw.print("    enforced=");
4721                pw.println(mReadExternalStorageEnforced);
4722            }
4723        }
4724    }
4725
4726    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4727            DumpState dumpState, boolean checkin) {
4728        boolean printedSomething = false;
4729        for (SharedUserSetting su : mSharedUsers.values()) {
4730            if (packageName != null && su != dumpState.getSharedUser()) {
4731                continue;
4732            }
4733            if (permissionNames != null
4734                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4735                continue;
4736            }
4737            if (!checkin) {
4738                if (!printedSomething) {
4739                    if (dumpState.onTitlePrinted())
4740                        pw.println();
4741                    pw.println("Shared users:");
4742                    printedSomething = true;
4743                }
4744                pw.print("  SharedUser [");
4745                pw.print(su.name);
4746                pw.print("] (");
4747                pw.print(Integer.toHexString(System.identityHashCode(su)));
4748                        pw.println("):");
4749
4750                String prefix = "    ";
4751                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4752
4753                PermissionsState permissionsState = su.getPermissionsState();
4754                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4755
4756                for (int userId : UserManagerService.getInstance().getUserIds()) {
4757                    final int[] gids = permissionsState.computeGids(userId);
4758                    List<PermissionState> permissions = permissionsState
4759                            .getRuntimePermissionStates(userId);
4760                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4761                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4762                        dumpGidsLPr(pw, prefix + "  ", gids);
4763                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4764                                packageName != null);
4765                    }
4766                }
4767            } else {
4768                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4769            }
4770        }
4771    }
4772
4773    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4774        pw.println("Settings parse messages:");
4775        pw.print(mReadMessages.toString());
4776    }
4777
4778    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4779        if (mRestoredUserGrants.size() > 0) {
4780            pw.println();
4781            pw.println("Restored (pending) permission grants:");
4782            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4783                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4784                        mRestoredUserGrants.valueAt(userIndex);
4785                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4786                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4787                    pw.print("  User "); pw.println(userId);
4788
4789                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4790                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4791                        if (grants != null && grants.size() > 0) {
4792                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4793                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4794
4795                            for (RestoredPermissionGrant g : grants) {
4796                                pw.print("      ");
4797                                pw.print(g.permissionName);
4798                                if (g.granted) {
4799                                    pw.print(" GRANTED");
4800                                }
4801                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4802                                    pw.print(" user_set");
4803                                }
4804                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4805                                    pw.print(" user_fixed");
4806                                }
4807                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4808                                    pw.print(" revoke_on_upgrade");
4809                                }
4810                                pw.println();
4811                            }
4812                        }
4813                    }
4814                }
4815            }
4816            pw.println();
4817        }
4818    }
4819
4820    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4821        if (pkg == null) {
4822            pw.print("unknown");
4823        } else {
4824            // [base:10, config.mdpi, config.xhdpi:12]
4825            pw.print("[");
4826            pw.print("base");
4827            if (pkg.baseRevisionCode != 0) {
4828                pw.print(":"); pw.print(pkg.baseRevisionCode);
4829            }
4830            if (pkg.splitNames != null) {
4831                for (int i = 0; i < pkg.splitNames.length; i++) {
4832                    pw.print(", ");
4833                    pw.print(pkg.splitNames[i]);
4834                    if (pkg.splitRevisionCodes[i] != 0) {
4835                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4836                    }
4837                }
4838            }
4839            pw.print("]");
4840        }
4841    }
4842
4843    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4844        if (!ArrayUtils.isEmpty(gids)) {
4845            pw.print(prefix);
4846            pw.print("gids="); pw.println(
4847                    PackageManagerService.arrayToString(gids));
4848        }
4849    }
4850
4851    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4852            List<PermissionState> permissionStates, boolean dumpAll) {
4853        if (!permissionStates.isEmpty() || dumpAll) {
4854            pw.print(prefix); pw.println("runtime permissions:");
4855            for (PermissionState permissionState : permissionStates) {
4856                if (permissionNames != null
4857                        && !permissionNames.contains(permissionState.getName())) {
4858                    continue;
4859                }
4860                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4861                pw.print(": granted="); pw.print(permissionState.isGranted());
4862                    pw.println(permissionFlagsToString(", flags=",
4863                            permissionState.getFlags()));
4864            }
4865        }
4866    }
4867
4868    private static String permissionFlagsToString(String prefix, int flags) {
4869        StringBuilder flagsString = null;
4870        while (flags != 0) {
4871            if (flagsString == null) {
4872                flagsString = new StringBuilder();
4873                flagsString.append(prefix);
4874                flagsString.append("[ ");
4875            }
4876            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4877            flags &= ~flag;
4878            flagsString.append(PackageManager.permissionFlagToString(flag));
4879            flagsString.append(' ');
4880        }
4881        if (flagsString != null) {
4882            flagsString.append(']');
4883            return flagsString.toString();
4884        } else {
4885            return "";
4886        }
4887    }
4888
4889    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4890            PermissionsState permissionsState) {
4891        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
4892        if (!permissionStates.isEmpty()) {
4893            pw.print(prefix); pw.println("install permissions:");
4894            for (PermissionState permissionState : permissionStates) {
4895                if (permissionNames != null
4896                        && !permissionNames.contains(permissionState.getName())) {
4897                    continue;
4898                }
4899                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4900                    pw.print(": granted="); pw.print(permissionState.isGranted());
4901                    pw.println(permissionFlagsToString(", flags=",
4902                        permissionState.getFlags()));
4903            }
4904        }
4905    }
4906
4907    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
4908        if (sync) {
4909            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
4910        } else {
4911            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
4912        }
4913    }
4914
4915    private final class RuntimePermissionPersistence {
4916        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
4917        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
4918
4919        private final Handler mHandler = new MyHandler();
4920
4921        private final Object mLock;
4922
4923        @GuardedBy("mLock")
4924        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
4925
4926        @GuardedBy("mLock")
4927        // The mapping keys are user ids.
4928        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
4929
4930        @GuardedBy("mLock")
4931        // The mapping keys are user ids.
4932        private final SparseArray<String> mFingerprints = new SparseArray<>();
4933
4934        @GuardedBy("mLock")
4935        // The mapping keys are user ids.
4936        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
4937
4938        public RuntimePermissionPersistence(Object lock) {
4939            mLock = lock;
4940        }
4941
4942        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
4943            return mDefaultPermissionsGranted.get(userId);
4944        }
4945
4946        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
4947            mFingerprints.put(userId, Build.FINGERPRINT);
4948            writePermissionsForUserAsyncLPr(userId);
4949        }
4950
4951        public void writePermissionsForUserSyncLPr(int userId) {
4952            mHandler.removeMessages(userId);
4953            writePermissionsSync(userId);
4954        }
4955
4956        public void writePermissionsForUserAsyncLPr(int userId) {
4957            final long currentTimeMillis = SystemClock.uptimeMillis();
4958
4959            if (mWriteScheduled.get(userId)) {
4960                mHandler.removeMessages(userId);
4961
4962                // If enough time passed, write without holding off anymore.
4963                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
4964                        .get(userId);
4965                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
4966                        - lastNotWrittenMutationTimeMillis;
4967                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
4968                    mHandler.obtainMessage(userId).sendToTarget();
4969                    return;
4970                }
4971
4972                // Hold off a bit more as settings are frequently changing.
4973                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
4974                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
4975                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
4976                        maxDelayMillis);
4977
4978                Message message = mHandler.obtainMessage(userId);
4979                mHandler.sendMessageDelayed(message, writeDelayMillis);
4980            } else {
4981                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
4982                Message message = mHandler.obtainMessage(userId);
4983                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
4984                mWriteScheduled.put(userId, true);
4985            }
4986        }
4987
4988        private void writePermissionsSync(int userId) {
4989            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
4990
4991            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
4992            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
4993
4994            synchronized (mLock) {
4995                mWriteScheduled.delete(userId);
4996
4997                final int packageCount = mPackages.size();
4998                for (int i = 0; i < packageCount; i++) {
4999                    String packageName = mPackages.keyAt(i);
5000                    PackageSetting packageSetting = mPackages.valueAt(i);
5001                    if (packageSetting.sharedUser == null) {
5002                        PermissionsState permissionsState = packageSetting.getPermissionsState();
5003                        List<PermissionState> permissionsStates = permissionsState
5004                                .getRuntimePermissionStates(userId);
5005                        if (!permissionsStates.isEmpty()) {
5006                            permissionsForPackage.put(packageName, permissionsStates);
5007                        }
5008                    }
5009                }
5010
5011                final int sharedUserCount = mSharedUsers.size();
5012                for (int i = 0; i < sharedUserCount; i++) {
5013                    String sharedUserName = mSharedUsers.keyAt(i);
5014                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
5015                    PermissionsState permissionsState = sharedUser.getPermissionsState();
5016                    List<PermissionState> permissionsStates = permissionsState
5017                            .getRuntimePermissionStates(userId);
5018                    if (!permissionsStates.isEmpty()) {
5019                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
5020                    }
5021                }
5022            }
5023
5024            FileOutputStream out = null;
5025            try {
5026                out = destination.startWrite();
5027
5028                XmlSerializer serializer = Xml.newSerializer();
5029                serializer.setOutput(out, StandardCharsets.UTF_8.name());
5030                serializer.setFeature(
5031                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
5032                serializer.startDocument(null, true);
5033
5034                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
5035
5036                String fingerprint = mFingerprints.get(userId);
5037                if (fingerprint != null) {
5038                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
5039                }
5040
5041                final int packageCount = permissionsForPackage.size();
5042                for (int i = 0; i < packageCount; i++) {
5043                    String packageName = permissionsForPackage.keyAt(i);
5044                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
5045                    serializer.startTag(null, TAG_PACKAGE);
5046                    serializer.attribute(null, ATTR_NAME, packageName);
5047                    writePermissions(serializer, permissionStates);
5048                    serializer.endTag(null, TAG_PACKAGE);
5049                }
5050
5051                final int sharedUserCount = permissionsForSharedUser.size();
5052                for (int i = 0; i < sharedUserCount; i++) {
5053                    String packageName = permissionsForSharedUser.keyAt(i);
5054                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
5055                    serializer.startTag(null, TAG_SHARED_USER);
5056                    serializer.attribute(null, ATTR_NAME, packageName);
5057                    writePermissions(serializer, permissionStates);
5058                    serializer.endTag(null, TAG_SHARED_USER);
5059                }
5060
5061                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
5062
5063                // Now any restored permission grants that are waiting for the apps
5064                // in question to be installed.  These are stored as per-package
5065                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
5066                // number of individual permission grant entities.
5067                if (mRestoredUserGrants.get(userId) != null) {
5068                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
5069                            mRestoredUserGrants.get(userId);
5070                    if (restoredGrants != null) {
5071                        final int pkgCount = restoredGrants.size();
5072                        for (int i = 0; i < pkgCount; i++) {
5073                            final ArraySet<RestoredPermissionGrant> pkgGrants =
5074                                    restoredGrants.valueAt(i);
5075                            if (pkgGrants != null && pkgGrants.size() > 0) {
5076                                final String pkgName = restoredGrants.keyAt(i);
5077                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5078                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
5079
5080                                final int N = pkgGrants.size();
5081                                for (int z = 0; z < N; z++) {
5082                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
5083                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
5084                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
5085
5086                                    if (g.granted) {
5087                                        serializer.attribute(null, ATTR_GRANTED, "true");
5088                                    }
5089
5090                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
5091                                        serializer.attribute(null, ATTR_USER_SET, "true");
5092                                    }
5093                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
5094                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
5095                                    }
5096                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
5097                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
5098                                    }
5099                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
5100                                }
5101                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
5102                            }
5103                        }
5104                    }
5105                }
5106
5107                serializer.endDocument();
5108                destination.finishWrite(out);
5109
5110                if (Build.FINGERPRINT.equals(fingerprint)) {
5111                    mDefaultPermissionsGranted.put(userId, true);
5112                }
5113            // Any error while writing is fatal.
5114            } catch (Throwable t) {
5115                Slog.wtf(PackageManagerService.TAG,
5116                        "Failed to write settings, restoring backup", t);
5117                destination.failWrite(out);
5118            } finally {
5119                IoUtils.closeQuietly(out);
5120            }
5121        }
5122
5123        private void onUserRemovedLPw(int userId) {
5124            // Make sure we do not
5125            mHandler.removeMessages(userId);
5126
5127            for (SettingBase sb : mPackages.values()) {
5128                revokeRuntimePermissionsAndClearFlags(sb, userId);
5129            }
5130
5131            for (SettingBase sb : mSharedUsers.values()) {
5132                revokeRuntimePermissionsAndClearFlags(sb, userId);
5133            }
5134
5135            mDefaultPermissionsGranted.delete(userId);
5136            mFingerprints.remove(userId);
5137        }
5138
5139        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
5140            PermissionsState permissionsState = sb.getPermissionsState();
5141            for (PermissionState permissionState
5142                    : permissionsState.getRuntimePermissionStates(userId)) {
5143                BasePermission bp = mPermissions.get(permissionState.getName());
5144                if (bp != null) {
5145                    permissionsState.revokeRuntimePermission(bp, userId);
5146                    permissionsState.updatePermissionFlags(bp, userId,
5147                            PackageManager.MASK_PERMISSION_FLAGS, 0);
5148                }
5149            }
5150        }
5151
5152        public void deleteUserRuntimePermissionsFile(int userId) {
5153            getUserRuntimePermissionsFile(userId).delete();
5154        }
5155
5156        public void readStateForUserSyncLPr(int userId) {
5157            File permissionsFile = getUserRuntimePermissionsFile(userId);
5158            if (!permissionsFile.exists()) {
5159                return;
5160            }
5161
5162            FileInputStream in;
5163            try {
5164                in = new AtomicFile(permissionsFile).openRead();
5165            } catch (FileNotFoundException fnfe) {
5166                Slog.i(PackageManagerService.TAG, "No permissions state");
5167                return;
5168            }
5169
5170            try {
5171                XmlPullParser parser = Xml.newPullParser();
5172                parser.setInput(in, null);
5173                parseRuntimePermissionsLPr(parser, userId);
5174
5175            } catch (XmlPullParserException | IOException e) {
5176                throw new IllegalStateException("Failed parsing permissions file: "
5177                        + permissionsFile , e);
5178            } finally {
5179                IoUtils.closeQuietly(in);
5180            }
5181        }
5182
5183        // Backup/restore support
5184
5185        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
5186                boolean isGranted, int restoredFlagSet, int userId) {
5187            // This change will be remembered at write-settings time
5188            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
5189                    mRestoredUserGrants.get(userId);
5190            if (grantsByPackage == null) {
5191                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
5192                mRestoredUserGrants.put(userId, grantsByPackage);
5193            }
5194
5195            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
5196            if (grants == null) {
5197                grants = new ArraySet<RestoredPermissionGrant>();
5198                grantsByPackage.put(pkgName, grants);
5199            }
5200
5201            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
5202                    isGranted, restoredFlagSet);
5203            grants.add(grant);
5204        }
5205
5206        // Private internals
5207
5208        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
5209                throws IOException, XmlPullParserException {
5210            final int outerDepth = parser.getDepth();
5211            int type;
5212            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5213                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5214                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5215                    continue;
5216                }
5217
5218                switch (parser.getName()) {
5219                    case TAG_RUNTIME_PERMISSIONS: {
5220                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
5221                        mFingerprints.put(userId, fingerprint);
5222                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
5223                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
5224                    } break;
5225
5226                    case TAG_PACKAGE: {
5227                        String name = parser.getAttributeValue(null, ATTR_NAME);
5228                        PackageSetting ps = mPackages.get(name);
5229                        if (ps == null) {
5230                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
5231                            XmlUtils.skipCurrentTag(parser);
5232                            continue;
5233                        }
5234                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
5235                    } break;
5236
5237                    case TAG_SHARED_USER: {
5238                        String name = parser.getAttributeValue(null, ATTR_NAME);
5239                        SharedUserSetting sus = mSharedUsers.get(name);
5240                        if (sus == null) {
5241                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
5242                            XmlUtils.skipCurrentTag(parser);
5243                            continue;
5244                        }
5245                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
5246                    } break;
5247
5248                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
5249                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
5250                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
5251                    } break;
5252                }
5253            }
5254        }
5255
5256        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
5257                final String pkgName, final int userId) throws IOException, XmlPullParserException {
5258            final int outerDepth = parser.getDepth();
5259            int type;
5260            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5261                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5262                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5263                    continue;
5264                }
5265
5266                switch (parser.getName()) {
5267                    case TAG_PERMISSION_ENTRY: {
5268                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
5269                        final boolean isGranted = "true".equals(
5270                                parser.getAttributeValue(null, ATTR_GRANTED));
5271
5272                        int permBits = 0;
5273                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
5274                            permBits |= FLAG_PERMISSION_USER_SET;
5275                        }
5276                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
5277                            permBits |= FLAG_PERMISSION_USER_FIXED;
5278                        }
5279                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
5280                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
5281                        }
5282
5283                        if (isGranted || permBits != 0) {
5284                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5285                        }
5286                    } break;
5287                }
5288            }
5289        }
5290
5291        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5292                int userId) throws IOException, XmlPullParserException {
5293            final int outerDepth = parser.getDepth();
5294            int type;
5295            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5296                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5297                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5298                    continue;
5299                }
5300
5301                switch (parser.getName()) {
5302                    case TAG_ITEM: {
5303                        String name = parser.getAttributeValue(null, ATTR_NAME);
5304                        BasePermission bp = mPermissions.get(name);
5305                        if (bp == null) {
5306                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5307                            XmlUtils.skipCurrentTag(parser);
5308                            continue;
5309                        }
5310
5311                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5312                        final boolean granted = grantedStr == null
5313                                || Boolean.parseBoolean(grantedStr);
5314
5315                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5316                        final int flags = (flagsStr != null)
5317                                ? Integer.parseInt(flagsStr, 16) : 0;
5318
5319                        if (granted) {
5320                            permissionsState.grantRuntimePermission(bp, userId);
5321                            permissionsState.updatePermissionFlags(bp, userId,
5322                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5323                        } else {
5324                            permissionsState.updatePermissionFlags(bp, userId,
5325                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5326                        }
5327
5328                    } break;
5329                }
5330            }
5331        }
5332
5333        private void writePermissions(XmlSerializer serializer,
5334                List<PermissionState> permissionStates) throws IOException {
5335            for (PermissionState permissionState : permissionStates) {
5336                serializer.startTag(null, TAG_ITEM);
5337                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5338                serializer.attribute(null, ATTR_GRANTED,
5339                        String.valueOf(permissionState.isGranted()));
5340                serializer.attribute(null, ATTR_FLAGS,
5341                        Integer.toHexString(permissionState.getFlags()));
5342                serializer.endTag(null, TAG_ITEM);
5343            }
5344        }
5345
5346        private final class MyHandler extends Handler {
5347            public MyHandler() {
5348                super(BackgroundThread.getHandler().getLooper());
5349            }
5350
5351            @Override
5352            public void handleMessage(Message message) {
5353                final int userId = message.what;
5354                Runnable callback = (Runnable) message.obj;
5355                writePermissionsSync(userId);
5356                if (callback != null) {
5357                    callback.run();
5358                }
5359            }
5360        }
5361    }
5362}
5363