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