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