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