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