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