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