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