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