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