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