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