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