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