Settings.java revision ad0634c50c5c4a18b5b66f2c8250e6a09bf69f1c
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.os.Process.SYSTEM_UID;
26import static android.os.Process.PACKAGE_INFO_GID;
27
28import android.content.IntentFilter;
29import android.content.pm.ActivityInfo;
30import android.content.pm.ResolveInfo;
31import android.net.Uri;
32import android.os.PatternMatcher;
33import android.util.LogPrinter;
34import com.android.internal.util.FastXmlSerializer;
35import com.android.internal.util.JournaledFile;
36import com.android.internal.util.XmlUtils;
37import com.android.server.pm.PackageManagerService.DumpState;
38
39import java.util.Collection;
40import org.xmlpull.v1.XmlPullParser;
41import org.xmlpull.v1.XmlPullParserException;
42import org.xmlpull.v1.XmlSerializer;
43
44import android.content.ComponentName;
45import android.content.Context;
46import android.content.Intent;
47import android.content.pm.ApplicationInfo;
48import android.content.pm.ComponentInfo;
49import android.content.pm.PackageCleanItem;
50import android.content.pm.PackageManager;
51import android.content.pm.PackageParser;
52import android.content.pm.PermissionInfo;
53import android.content.pm.Signature;
54import android.content.pm.UserInfo;
55import android.content.pm.PackageUserState;
56import android.content.pm.VerifierDeviceIdentity;
57import android.os.Binder;
58import android.os.Environment;
59import android.os.FileUtils;
60import android.os.Process;
61import android.os.UserHandle;
62import android.os.UserManager;
63import android.util.Log;
64import android.util.Slog;
65import android.util.SparseArray;
66import android.util.Xml;
67
68import java.io.BufferedOutputStream;
69import java.io.File;
70import java.io.FileInputStream;
71import java.io.FileOutputStream;
72import java.io.IOException;
73import java.io.PrintWriter;
74import java.text.SimpleDateFormat;
75import java.util.ArrayList;
76import java.util.Arrays;
77import java.util.Date;
78import java.util.HashMap;
79import java.util.HashSet;
80import java.util.Iterator;
81import java.util.List;
82import java.util.Map;
83import java.util.Set;
84import java.util.Map.Entry;
85
86import libcore.io.IoUtils;
87
88/**
89 * Holds information about dynamic settings.
90 */
91final class Settings {
92    private static final String TAG = "PackageSettings";
93
94    /**
95     * Current version of the package database. Set it to the latest version in
96     * the {@link DatabaseVersion} class below to ensure the database upgrade
97     * doesn't happen repeatedly.
98     * <p>
99     * Note that care should be taken to make sure all database upgrades are
100     * idempotent.
101     */
102    private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_END_ENTITY;
103
104    /**
105     * This class contains constants that can be referred to from upgrade code.
106     * Insert constant values here that describe the upgrade reason. The version
107     * code must be monotonically increasing.
108     */
109    public static class DatabaseVersion {
110        /**
111         * The initial version of the database.
112         */
113        public static final int FIRST_VERSION = 1;
114
115        /**
116         * Migrating the Signature array from the entire certificate chain to
117         * just the signing certificate.
118         */
119        public static final int SIGNATURE_END_ENTITY = 2;
120    }
121
122    private static final boolean DEBUG_STOPPED = false;
123    private static final boolean DEBUG_MU = false;
124
125    private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
126    private static final String ATTR_ENFORCEMENT = "enforcement";
127
128    private static final String TAG_ITEM = "item";
129    private static final String TAG_DISABLED_COMPONENTS = "disabled-components";
130    private static final String TAG_ENABLED_COMPONENTS = "enabled-components";
131    private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions";
132    private static final String TAG_PACKAGE = "pkg";
133    private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
134            "persistent-preferred-activities";
135    static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
136            "crossProfile-intent-filters";
137    //Old name. Kept for compatibility
138    static final String TAG_FORWARDING_INTENT_FILTERS =
139            "forwarding-intent-filters";
140
141    private static final String ATTR_NAME = "name";
142    private static final String ATTR_USER = "user";
143    private static final String ATTR_CODE = "code";
144    private static final String ATTR_NOT_LAUNCHED = "nl";
145    private static final String ATTR_ENABLED = "enabled";
146    private static final String ATTR_ENABLED_CALLER = "enabledCaller";
147    private static final String ATTR_STOPPED = "stopped";
148    private static final String ATTR_BLOCKED = "blocked";
149    private static final String ATTR_INSTALLED = "inst";
150
151    private final File mSettingsFilename;
152    private final File mBackupSettingsFilename;
153    private final File mPackageListFilename;
154    private final File mStoppedPackagesFilename;
155    private final File mBackupStoppedPackagesFilename;
156
157    final HashMap<String, PackageSetting> mPackages =
158            new HashMap<String, PackageSetting>();
159    // List of replaced system applications
160    private final HashMap<String, PackageSetting> mDisabledSysPackages =
161        new HashMap<String, PackageSetting>();
162
163    private static int mFirstAvailableUid = 0;
164
165    // These are the last platform API version we were using for
166    // the apps installed on internal and external storage.  It is
167    // used to grant newer permissions one time during a system upgrade.
168    int mInternalSdkPlatform;
169    int mExternalSdkPlatform;
170
171    /**
172     * The current database version for apps on internal storage. This is
173     * used to upgrade the format of the packages.xml database not necessarily
174     * tied to an SDK version.
175     */
176    int mInternalDatabaseVersion;
177    int mExternalDatabaseVersion;
178
179    Boolean mReadExternalStorageEnforced;
180
181    /** Device identity for the purpose of package verification. */
182    private VerifierDeviceIdentity mVerifierDeviceIdentity;
183
184    // The user's preferred activities associated with particular intent
185    // filters.
186    final SparseArray<PreferredIntentResolver> mPreferredActivities =
187            new SparseArray<PreferredIntentResolver>();
188
189    // The persistent preferred activities of the user's profile/device owner
190    // associated with particular intent filters.
191    final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
192            new SparseArray<PersistentPreferredIntentResolver>();
193
194    // For every user, it is used to find to which other users the intent can be forwarded.
195    final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers =
196            new SparseArray<CrossProfileIntentResolver>();
197
198    final HashMap<String, SharedUserSetting> mSharedUsers =
199            new HashMap<String, SharedUserSetting>();
200    private final ArrayList<Object> mUserIds = new ArrayList<Object>();
201    private final SparseArray<Object> mOtherUserIds =
202            new SparseArray<Object>();
203
204    // For reading/writing settings file.
205    private final ArrayList<Signature> mPastSignatures =
206            new ArrayList<Signature>();
207
208    // Mapping from permission names to info about them.
209    final HashMap<String, BasePermission> mPermissions =
210            new HashMap<String, BasePermission>();
211
212    // Mapping from permission tree names to info about them.
213    final HashMap<String, BasePermission> mPermissionTrees =
214            new HashMap<String, BasePermission>();
215
216    // Packages that have been uninstalled and still need their external
217    // storage data deleted.
218    final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>();
219
220    // Packages that have been renamed since they were first installed.
221    // Keys are the new names of the packages, values are the original
222    // names.  The packages appear everwhere else under their original
223    // names.
224    final HashMap<String, String> mRenamedPackages = new HashMap<String, String>();
225
226    final StringBuilder mReadMessages = new StringBuilder();
227
228    /**
229     * Used to track packages that have a shared user ID that hasn't been read
230     * in yet.
231     * <p>
232     * TODO: make this just a local variable that is passed in during package
233     * scanning to make it less confusing.
234     */
235    private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
236
237    private final Context mContext;
238
239    private final File mSystemDir;
240
241    public final KeySetManager mKeySetManager = new KeySetManager(mPackages);
242
243    Settings(Context context) {
244        this(context, Environment.getDataDirectory());
245    }
246
247    Settings(Context context, File dataDir) {
248        mContext = context;
249        mSystemDir = new File(dataDir, "system");
250        mSystemDir.mkdirs();
251        FileUtils.setPermissions(mSystemDir.toString(),
252                FileUtils.S_IRWXU|FileUtils.S_IRWXG
253                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
254                -1, -1);
255        mSettingsFilename = new File(mSystemDir, "packages.xml");
256        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
257        mPackageListFilename = new File(mSystemDir, "packages.list");
258        FileUtils.setPermissions(mPackageListFilename, 0660, SYSTEM_UID, PACKAGE_INFO_GID);
259
260        // Deprecated: Needed for migration
261        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
262        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
263    }
264
265    PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
266            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
267            String nativeLibraryPathString, String cpuAbiString, int pkgFlags, UserHandle user, boolean add) {
268        final String name = pkg.packageName;
269        PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
270                resourcePath, nativeLibraryPathString, cpuAbiString, pkg.mVersionCode, pkgFlags,
271                user, add, true /* allowInstall */);
272        return p;
273    }
274
275    PackageSetting peekPackageLPr(String name) {
276        return mPackages.get(name);
277    }
278
279    void setInstallStatus(String pkgName, int status) {
280        PackageSetting p = mPackages.get(pkgName);
281        if(p != null) {
282            if(p.getInstallStatus() != status) {
283                p.setInstallStatus(status);
284            }
285        }
286    }
287
288    void setInstallerPackageName(String pkgName,
289            String installerPkgName) {
290        PackageSetting p = mPackages.get(pkgName);
291        if(p != null) {
292            p.setInstallerPackageName(installerPkgName);
293        }
294    }
295
296    SharedUserSetting getSharedUserLPw(String name,
297            int pkgFlags, boolean create) {
298        SharedUserSetting s = mSharedUsers.get(name);
299        if (s == null) {
300            if (!create) {
301                return null;
302            }
303            s = new SharedUserSetting(name, pkgFlags);
304            s.userId = newUserIdLPw(s);
305            Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
306            // < 0 means we couldn't assign a userid; fall out and return
307            // s, which is currently null
308            if (s.userId >= 0) {
309                mSharedUsers.put(name, s);
310            }
311        }
312
313        return s;
314    }
315
316    Collection<SharedUserSetting> getAllSharedUsersLPw() {
317        return mSharedUsers.values();
318    }
319
320
321    boolean disableSystemPackageLPw(String name) {
322        final PackageSetting p = mPackages.get(name);
323        if(p == null) {
324            Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
325            return false;
326        }
327        final PackageSetting dp = mDisabledSysPackages.get(name);
328        // always make sure the system package code and resource paths dont change
329        if (dp == null) {
330            if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
331                p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
332            }
333            mDisabledSysPackages.put(name, p);
334
335            // a little trick...  when we install the new package, we don't
336            // want to modify the existing PackageSetting for the built-in
337            // version.  so at this point we need a new PackageSetting that
338            // is okay to muck with.
339            PackageSetting newp = new PackageSetting(p);
340            replacePackageLPw(name, newp);
341            return true;
342        }
343        return false;
344    }
345
346    PackageSetting enableSystemPackageLPw(String name) {
347        PackageSetting p = mDisabledSysPackages.get(name);
348        if(p == null) {
349            Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
350            return null;
351        }
352        // Reset flag in ApplicationInfo object
353        if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
354            p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
355        }
356        PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
357                p.nativeLibraryPathString, p.cpuAbiString, p.appId, p.versionCode, p.pkgFlags);
358        mDisabledSysPackages.remove(name);
359        return ret;
360    }
361
362    boolean isDisabledSystemPackageLPr(String name) {
363        return mDisabledSysPackages.containsKey(name);
364    }
365
366    void removeDisabledSystemPackageLPw(String name) {
367        mDisabledSysPackages.remove(name);
368    }
369
370    PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
371            String nativeLibraryPathString, String cpuAbiString, int uid, int vc, int pkgFlags) {
372        PackageSetting p = mPackages.get(name);
373        if (p != null) {
374            if (p.appId == uid) {
375                return p;
376            }
377            PackageManagerService.reportSettingsProblem(Log.ERROR,
378                    "Adding duplicate package, keeping first: " + name);
379            return null;
380        }
381        p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString, cpuAbiString,
382                vc, pkgFlags);
383        p.appId = uid;
384        if (addUserIdLPw(uid, p, name)) {
385            mPackages.put(name, p);
386            return p;
387        }
388        return null;
389    }
390
391    SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
392        SharedUserSetting s = mSharedUsers.get(name);
393        if (s != null) {
394            if (s.userId == uid) {
395                return s;
396            }
397            PackageManagerService.reportSettingsProblem(Log.ERROR,
398                    "Adding duplicate shared user, keeping first: " + name);
399            return null;
400        }
401        s = new SharedUserSetting(name, pkgFlags);
402        s.userId = uid;
403        if (addUserIdLPw(uid, s, name)) {
404            mSharedUsers.put(name, s);
405            return s;
406        }
407        return null;
408    }
409
410    void pruneSharedUsersLPw() {
411        ArrayList<String> removeStage = new ArrayList<String>();
412        for (Map.Entry<String,SharedUserSetting> entry : mSharedUsers.entrySet()) {
413            final SharedUserSetting sus = entry.getValue();
414            if (sus == null || sus.packages.size() == 0) {
415                removeStage.add(entry.getKey());
416            }
417        }
418        for (int i = 0; i < removeStage.size(); i++) {
419            mSharedUsers.remove(removeStage.get(i));
420        }
421    }
422
423    // Transfer ownership of permissions from one package to another.
424    void transferPermissionsLPw(String origPkg, String newPkg) {
425        // Transfer ownership of permissions to the new package.
426        for (int i=0; i<2; i++) {
427            HashMap<String, BasePermission> permissions =
428                    i == 0 ? mPermissionTrees : mPermissions;
429            for (BasePermission bp : permissions.values()) {
430                if (origPkg.equals(bp.sourcePackage)) {
431                    if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG,
432                            "Moving permission " + bp.name
433                            + " from pkg " + bp.sourcePackage
434                            + " to " + newPkg);
435                    bp.sourcePackage = newPkg;
436                    bp.packageSetting = null;
437                    bp.perm = null;
438                    if (bp.pendingInfo != null) {
439                        bp.pendingInfo.packageName = newPkg;
440                    }
441                    bp.uid = 0;
442                    bp.gids = null;
443                }
444            }
445        }
446    }
447
448    private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
449            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
450            String nativeLibraryPathString, String cpuAbiString, int vc, int pkgFlags,
451            UserHandle installUser, boolean add, boolean allowInstall) {
452        PackageSetting p = mPackages.get(name);
453        if (p != null) {
454            p.cpuAbiString = cpuAbiString;
455            if (!p.codePath.equals(codePath)) {
456                // Check to see if its a disabled system app
457                if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
458                    // This is an updated system app with versions in both system
459                    // and data partition. Just let the most recent version
460                    // take precedence.
461                    Slog.w(PackageManagerService.TAG, "Trying to update system app code path from "
462                            + p.codePathString + " to " + codePath.toString());
463                } else {
464                    // Just a change in the code path is not an issue, but
465                    // let's log a message about it.
466                    Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from "
467                            + p.codePath + " to " + codePath + "; Retaining data and using new");
468                    /*
469                     * Since we've changed paths, we need to prefer the new
470                     * native library path over the one stored in the
471                     * package settings since we might have moved from
472                     * internal to external storage or vice versa.
473                     */
474                    p.nativeLibraryPathString = nativeLibraryPathString;
475                }
476            }
477            if (p.sharedUser != sharedUser) {
478                PackageManagerService.reportSettingsProblem(Log.WARN,
479                        "Package " + name + " shared user changed from "
480                        + (p.sharedUser != null ? p.sharedUser.name : "<nothing>")
481                        + " to "
482                        + (sharedUser != null ? sharedUser.name : "<nothing>")
483                        + "; replacing with new");
484                p = null;
485            } else {
486                // If what we are scanning is a system (and possibly privileged) package,
487                // then make it so, regardless of whether it was previously installed only
488                // in the data partition.
489                final int sysPrivFlags = pkgFlags
490                        & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PRIVILEGED);
491                p.pkgFlags |= sysPrivFlags;
492            }
493        }
494        if (p == null) {
495            if (origPackage != null) {
496                // We are consuming the data from an existing package.
497                p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
498                        nativeLibraryPathString, cpuAbiString, vc, pkgFlags);
499                if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
500                        + name + " is adopting original package " + origPackage.name);
501                // Note that we will retain the new package's signature so
502                // that we can keep its data.
503                PackageSignatures s = p.signatures;
504                p.copyFrom(origPackage);
505                p.signatures = s;
506                p.sharedUser = origPackage.sharedUser;
507                p.appId = origPackage.appId;
508                p.origPackage = origPackage;
509                mRenamedPackages.put(name, origPackage.name);
510                name = origPackage.name;
511                // Update new package state.
512                p.setTimeStamp(codePath.lastModified());
513            } else {
514                p = new PackageSetting(name, realName, codePath, resourcePath,
515                        nativeLibraryPathString, cpuAbiString, vc, pkgFlags);
516                p.setTimeStamp(codePath.lastModified());
517                p.sharedUser = sharedUser;
518                // If this is not a system app, it starts out stopped.
519                if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
520                    if (DEBUG_STOPPED) {
521                        RuntimeException e = new RuntimeException("here");
522                        e.fillInStackTrace();
523                        Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
524                    }
525                    List<UserInfo> users = getAllUsers();
526                    if (users != null && allowInstall) {
527                        for (UserInfo user : users) {
528                            // By default we consider this app to be installed
529                            // for the user if no user has been specified (which
530                            // means to leave it at its original value, and the
531                            // original default value is true), or we are being
532                            // asked to install for all users, or this is the
533                            // user we are installing for.
534                            // In this context all users (USER_ALL) implies an adb install,
535                            // so we additionally check whether that is allowed for this user.
536                            final boolean installed = installUser == null
537                                    || (installUser.getIdentifier() == UserHandle.USER_ALL
538                                            && (!isUnknownSourcesDisallowed(user.id)))
539                                    || installUser.getIdentifier() == user.id;
540                            p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
541                                    installed,
542                                    true, // stopped,
543                                    true, // notLaunched
544                                    false, // blocked
545                                    null, null, null);
546                            writePackageRestrictionsLPr(user.id);
547                        }
548                    }
549                }
550                if (sharedUser != null) {
551                    p.appId = sharedUser.userId;
552                } else {
553                    // Clone the setting here for disabled system packages
554                    PackageSetting dis = mDisabledSysPackages.get(name);
555                    if (dis != null) {
556                        // For disabled packages a new setting is created
557                        // from the existing user id. This still has to be
558                        // added to list of user id's
559                        // Copy signatures from previous setting
560                        if (dis.signatures.mSignatures != null) {
561                            p.signatures.mSignatures = dis.signatures.mSignatures.clone();
562                        }
563                        p.appId = dis.appId;
564                        // Clone permissions
565                        p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
566                        // Clone component info
567                        List<UserInfo> users = getAllUsers();
568                        if (users != null) {
569                            for (UserInfo user : users) {
570                                int userId = user.id;
571                                p.setDisabledComponentsCopy(
572                                        dis.getDisabledComponents(userId), userId);
573                                p.setEnabledComponentsCopy(
574                                        dis.getEnabledComponents(userId), userId);
575                            }
576                        }
577                        // Add new setting to list of user ids
578                        addUserIdLPw(p.appId, p, name);
579                    } else {
580                        // Assign new user id
581                        p.appId = newUserIdLPw(p);
582                    }
583                }
584            }
585            if (p.appId < 0) {
586                PackageManagerService.reportSettingsProblem(Log.WARN,
587                        "Package " + name + " could not be assigned a valid uid");
588                return null;
589            }
590            if (add) {
591                // Finish adding new package by adding it and updating shared
592                // user preferences
593                addPackageSettingLPw(p, name, sharedUser);
594            }
595        } else {
596            if (installUser != null && allowInstall) {
597                // The caller has explicitly specified the user they want this
598                // package installed for, and the package already exists.
599                // Make sure it conforms to the new request.
600                List<UserInfo> users = getAllUsers();
601                if (users != null) {
602                    for (UserInfo user : users) {
603                        // Installing for USER_ALL implies an adb install, so we
604                        // additionally check whether that is allowed for this user.
605                        if ((installUser.getIdentifier() == UserHandle.USER_ALL
606                                        && (!isUnknownSourcesDisallowed(user.id)))
607                                || installUser.getIdentifier() == user.id) {
608                            boolean installed = p.getInstalled(user.id);
609                            if (!installed) {
610                                p.setInstalled(true, user.id);
611                                writePackageRestrictionsLPr(user.id);
612                            }
613                        }
614                    }
615                }
616            }
617        }
618        return p;
619    }
620
621    boolean isUnknownSourcesDisallowed(int userId) {
622        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
623        return um.getUserRestrictions(new UserHandle(userId)).getBoolean(
624                UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, false);
625    }
626
627    void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
628        p.pkg = pkg;
629        // pkg.mSetEnabled = p.getEnabled(userId);
630        // pkg.mSetStopped = p.getStopped(userId);
631        final String codePath = pkg.applicationInfo.sourceDir;
632        final String resourcePath = pkg.applicationInfo.publicSourceDir;
633        // Update code path if needed
634        if (!codePath.equalsIgnoreCase(p.codePathString)) {
635            Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName +
636                    " changing from " + p.codePathString + " to " + codePath);
637            p.codePath = new File(codePath);
638            p.codePathString = codePath;
639        }
640        //Update resource path if needed
641        if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) {
642            Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName +
643                    " changing from " + p.resourcePathString + " to " + resourcePath);
644            p.resourcePath = new File(resourcePath);
645            p.resourcePathString = resourcePath;
646        }
647        // Update the native library path if needed
648        final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
649        if (nativeLibraryPath != null
650                && !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
651            p.nativeLibraryPathString = nativeLibraryPath;
652        }
653        // Update the required Cpu Abi
654        p.cpuAbiString = pkg.applicationInfo.cpuAbi;
655        // Update version code if needed
656        if (pkg.mVersionCode != p.versionCode) {
657            p.versionCode = pkg.mVersionCode;
658        }
659        // Update signatures if needed.
660        if (p.signatures.mSignatures == null) {
661            p.signatures.assignSignatures(pkg.mSignatures);
662        }
663        // Update flags if needed.
664        if (pkg.applicationInfo.flags != p.pkgFlags) {
665            p.pkgFlags = pkg.applicationInfo.flags;
666        }
667        // If this app defines a shared user id initialize
668        // the shared user signatures as well.
669        if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
670            p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
671        }
672        addPackageSettingLPw(p, pkg.packageName, p.sharedUser);
673    }
674
675    // Utility method that adds a PackageSetting to mPackages and
676    // completes updating the shared user attributes
677    private void addPackageSettingLPw(PackageSetting p, String name,
678            SharedUserSetting sharedUser) {
679        mPackages.put(name, p);
680        if (sharedUser != null) {
681            if (p.sharedUser != null && p.sharedUser != sharedUser) {
682                PackageManagerService.reportSettingsProblem(Log.ERROR,
683                        "Package " + p.name + " was user "
684                        + p.sharedUser + " but is now " + sharedUser
685                        + "; I am not changing its files so it will probably fail!");
686                p.sharedUser.removePackage(p);
687            } else if (p.appId != sharedUser.userId) {
688                PackageManagerService.reportSettingsProblem(Log.ERROR,
689                    "Package " + p.name + " was user id " + p.appId
690                    + " but is now user " + sharedUser
691                    + " with id " + sharedUser.userId
692                    + "; I am not changing its files so it will probably fail!");
693            }
694
695            sharedUser.addPackage(p);
696            p.sharedUser = sharedUser;
697            p.appId = sharedUser.userId;
698        }
699    }
700
701    /*
702     * Update the shared user setting when a package using
703     * specifying the shared user id is removed. The gids
704     * associated with each permission of the deleted package
705     * are removed from the shared user's gid list only if its
706     * not in use by other permissions of packages in the
707     * shared user setting.
708     */
709    void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
710        if ((deletedPs == null) || (deletedPs.pkg == null)) {
711            Slog.i(PackageManagerService.TAG,
712                    "Trying to update info for null package. Just ignoring");
713            return;
714        }
715        // No sharedUserId
716        if (deletedPs.sharedUser == null) {
717            return;
718        }
719        SharedUserSetting sus = deletedPs.sharedUser;
720        // Update permissions
721        for (String eachPerm : deletedPs.pkg.requestedPermissions) {
722            boolean used = false;
723            if (!sus.grantedPermissions.contains(eachPerm)) {
724                continue;
725            }
726            for (PackageSetting pkg:sus.packages) {
727                if (pkg.pkg != null &&
728                        !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
729                        pkg.pkg.requestedPermissions.contains(eachPerm)) {
730                    used = true;
731                    break;
732                }
733            }
734            if (!used) {
735                // can safely delete this permission from list
736                sus.grantedPermissions.remove(eachPerm);
737            }
738        }
739        // Update gids
740        int newGids[] = globalGids;
741        for (String eachPerm : sus.grantedPermissions) {
742            BasePermission bp = mPermissions.get(eachPerm);
743            if (bp != null) {
744                newGids = PackageManagerService.appendInts(newGids, bp.gids);
745            }
746        }
747        sus.gids = newGids;
748    }
749
750    int removePackageLPw(String name) {
751        final PackageSetting p = mPackages.get(name);
752        if (p != null) {
753            mPackages.remove(name);
754            if (p.sharedUser != null) {
755                p.sharedUser.removePackage(p);
756                if (p.sharedUser.packages.size() == 0) {
757                    mSharedUsers.remove(p.sharedUser.name);
758                    removeUserIdLPw(p.sharedUser.userId);
759                    return p.sharedUser.userId;
760                }
761            } else {
762                removeUserIdLPw(p.appId);
763                return p.appId;
764            }
765        }
766        return -1;
767    }
768
769    private void replacePackageLPw(String name, PackageSetting newp) {
770        final PackageSetting p = mPackages.get(name);
771        if (p != null) {
772            if (p.sharedUser != null) {
773                p.sharedUser.removePackage(p);
774                p.sharedUser.addPackage(newp);
775            } else {
776                replaceUserIdLPw(p.appId, newp);
777            }
778        }
779        mPackages.put(name, newp);
780    }
781
782    private boolean addUserIdLPw(int uid, Object obj, Object name) {
783        if (uid > Process.LAST_APPLICATION_UID) {
784            return false;
785        }
786
787        if (uid >= Process.FIRST_APPLICATION_UID) {
788            int N = mUserIds.size();
789            final int index = uid - Process.FIRST_APPLICATION_UID;
790            while (index >= N) {
791                mUserIds.add(null);
792                N++;
793            }
794            if (mUserIds.get(index) != null) {
795                PackageManagerService.reportSettingsProblem(Log.ERROR,
796                        "Adding duplicate user id: " + uid
797                        + " name=" + name);
798                return false;
799            }
800            mUserIds.set(index, obj);
801        } else {
802            if (mOtherUserIds.get(uid) != null) {
803                PackageManagerService.reportSettingsProblem(Log.ERROR,
804                        "Adding duplicate shared id: " + uid
805                        + " name=" + name);
806                return false;
807            }
808            mOtherUserIds.put(uid, obj);
809        }
810        return true;
811    }
812
813    public Object getUserIdLPr(int uid) {
814        if (uid >= Process.FIRST_APPLICATION_UID) {
815            final int N = mUserIds.size();
816            final int index = uid - Process.FIRST_APPLICATION_UID;
817            return index < N ? mUserIds.get(index) : null;
818        } else {
819            return mOtherUserIds.get(uid);
820        }
821    }
822
823    private void removeUserIdLPw(int uid) {
824        if (uid >= Process.FIRST_APPLICATION_UID) {
825            final int N = mUserIds.size();
826            final int index = uid - Process.FIRST_APPLICATION_UID;
827            if (index < N) mUserIds.set(index, null);
828        } else {
829            mOtherUserIds.remove(uid);
830        }
831        setFirstAvailableUid(uid+1);
832    }
833
834    private void replaceUserIdLPw(int uid, Object obj) {
835        if (uid >= Process.FIRST_APPLICATION_UID) {
836            final int N = mUserIds.size();
837            final int index = uid - Process.FIRST_APPLICATION_UID;
838            if (index < N) mUserIds.set(index, obj);
839        } else {
840            mOtherUserIds.put(uid, obj);
841        }
842    }
843
844    PreferredIntentResolver editPreferredActivitiesLPw(int userId) {
845        PreferredIntentResolver pir = mPreferredActivities.get(userId);
846        if (pir == null) {
847            pir = new PreferredIntentResolver();
848            mPreferredActivities.put(userId, pir);
849        }
850        return pir;
851    }
852
853    PersistentPreferredIntentResolver editPersistentPreferredActivitiesLPw(int userId) {
854        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
855        if (ppir == null) {
856            ppir = new PersistentPreferredIntentResolver();
857            mPersistentPreferredActivities.put(userId, ppir);
858        }
859        return ppir;
860    }
861
862    CrossProfileIntentResolver editCrossProfileIntentResolverLPw(int userId) {
863        CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
864        if (cpir == null) {
865            cpir = new CrossProfileIntentResolver();
866            mCrossProfileIntentResolvers.put(userId, cpir);
867        }
868        return cpir;
869    }
870
871    private File getUserPackagesStateFile(int userId) {
872        return new File(Environment.getUserSystemDirectory(userId), "package-restrictions.xml");
873    }
874
875    private File getUserPackagesStateBackupFile(int userId) {
876        return new File(Environment.getUserSystemDirectory(userId),
877                "package-restrictions-backup.xml");
878    }
879
880    void writeAllUsersPackageRestrictionsLPr() {
881        List<UserInfo> users = getAllUsers();
882        if (users == null) return;
883
884        for (UserInfo user : users) {
885            writePackageRestrictionsLPr(user.id);
886        }
887    }
888
889    void readAllUsersPackageRestrictionsLPr() {
890        List<UserInfo> users = getAllUsers();
891        if (users == null) {
892            readPackageRestrictionsLPr(0);
893            return;
894        }
895
896        for (UserInfo user : users) {
897            readPackageRestrictionsLPr(user.id);
898        }
899    }
900
901    /**
902     * Returns whether the current database has is older than {@code version}
903     * for apps on internal storage.
904     */
905    public boolean isInternalDatabaseVersionOlderThan(int version) {
906        return mInternalDatabaseVersion < version;
907    }
908
909    /**
910     * Returns whether the current database has is older than {@code version}
911     * for apps on external storage.
912     */
913    public boolean isExternalDatabaseVersionOlderThan(int version) {
914        return mExternalDatabaseVersion < version;
915    }
916
917    /**
918     * Updates the database version for apps on internal storage. Called after
919     * call the updates to the database format are done for apps on internal
920     * storage after the initial start-up scan.
921     */
922    public void updateInternalDatabaseVersion() {
923        mInternalDatabaseVersion = CURRENT_DATABASE_VERSION;
924    }
925
926    /**
927     * Updates the database version for apps on internal storage. Called after
928     * call the updates to the database format are done for apps on internal
929     * storage after the initial start-up scan.
930     */
931    public void updateExternalDatabaseVersion() {
932        mExternalDatabaseVersion = CURRENT_DATABASE_VERSION;
933    }
934
935    private void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
936            throws XmlPullParserException, IOException {
937        int outerDepth = parser.getDepth();
938        int type;
939        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
940                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
941            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
942                continue;
943            }
944
945            String tagName = parser.getName();
946            if (tagName.equals(TAG_ITEM)) {
947                PreferredActivity pa = new PreferredActivity(parser);
948                if (pa.mPref.getParseError() == null) {
949                    editPreferredActivitiesLPw(userId).addFilter(pa);
950                } else {
951                    PackageManagerService.reportSettingsProblem(Log.WARN,
952                            "Error in package manager settings: <preferred-activity> "
953                                    + pa.mPref.getParseError() + " at "
954                                    + parser.getPositionDescription());
955                }
956            } else {
957                PackageManagerService.reportSettingsProblem(Log.WARN,
958                        "Unknown element under <preferred-activities>: " + parser.getName());
959                XmlUtils.skipCurrentTag(parser);
960            }
961        }
962    }
963
964    private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)
965            throws XmlPullParserException, IOException {
966        int outerDepth = parser.getDepth();
967        int type;
968        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
969                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
970            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
971                continue;
972            }
973            String tagName = parser.getName();
974            if (tagName.equals(TAG_ITEM)) {
975                PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
976                editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
977            } else {
978                PackageManagerService.reportSettingsProblem(Log.WARN,
979                        "Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: "
980                        + parser.getName());
981                XmlUtils.skipCurrentTag(parser);
982            }
983        }
984    }
985
986    private void readCrossProfileIntentFiltersLPw(XmlPullParser parser, int userId)
987            throws XmlPullParserException, IOException {
988        int outerDepth = parser.getDepth();
989        int type;
990        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
991                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
992            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
993                continue;
994            }
995            String tagName = parser.getName();
996            if (tagName.equals(TAG_ITEM)) {
997                CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
998                editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
999            } else {
1000                String msg = "Unknown element under " +  TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
1001                        parser.getName();
1002                PackageManagerService.reportSettingsProblem(Log.WARN, msg);
1003                XmlUtils.skipCurrentTag(parser);
1004            }
1005        }
1006    }
1007
1008    void readPackageRestrictionsLPr(int userId) {
1009        if (DEBUG_MU) {
1010            Log.i(TAG, "Reading package restrictions for user=" + userId);
1011        }
1012        FileInputStream str = null;
1013        File userPackagesStateFile = getUserPackagesStateFile(userId);
1014        File backupFile = getUserPackagesStateBackupFile(userId);
1015        if (backupFile.exists()) {
1016            try {
1017                str = new FileInputStream(backupFile);
1018                mReadMessages.append("Reading from backup stopped packages file\n");
1019                PackageManagerService.reportSettingsProblem(Log.INFO,
1020                        "Need to read from backup stopped packages file");
1021                if (userPackagesStateFile.exists()) {
1022                    // If both the backup and normal file exist, we
1023                    // ignore the normal one since it might have been
1024                    // corrupted.
1025                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1026                            + userPackagesStateFile);
1027                    userPackagesStateFile.delete();
1028                }
1029            } catch (java.io.IOException e) {
1030                // We'll try for the normal settings file.
1031            }
1032        }
1033
1034        try {
1035            if (str == null) {
1036                if (!userPackagesStateFile.exists()) {
1037                    mReadMessages.append("No stopped packages file found\n");
1038                    PackageManagerService.reportSettingsProblem(Log.INFO,
1039                            "No stopped packages file; "
1040                            + "assuming all started");
1041                    // At first boot, make sure no packages are stopped.
1042                    // We usually want to have third party apps initialize
1043                    // in the stopped state, but not at first boot.  Also
1044                    // consider all applications to be installed.
1045                    for (PackageSetting pkg : mPackages.values()) {
1046                        pkg.setUserState(userId, COMPONENT_ENABLED_STATE_DEFAULT,
1047                                true,   // installed
1048                                false,  // stopped
1049                                false,  // notLaunched
1050                                false,  // blocked
1051                                null, null, null);
1052                    }
1053                    return;
1054                }
1055                str = new FileInputStream(userPackagesStateFile);
1056            }
1057            final XmlPullParser parser = Xml.newPullParser();
1058            parser.setInput(str, null);
1059
1060            int type;
1061            while ((type=parser.next()) != XmlPullParser.START_TAG
1062                       && type != XmlPullParser.END_DOCUMENT) {
1063                ;
1064            }
1065
1066            if (type != XmlPullParser.START_TAG) {
1067                mReadMessages.append("No start tag found in package restrictions file\n");
1068                PackageManagerService.reportSettingsProblem(Log.WARN,
1069                        "No start tag found in package manager stopped packages");
1070                return;
1071            }
1072
1073            int outerDepth = parser.getDepth();
1074            PackageSetting ps = null;
1075            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1076                   && (type != XmlPullParser.END_TAG
1077                           || parser.getDepth() > outerDepth)) {
1078                if (type == XmlPullParser.END_TAG
1079                        || type == XmlPullParser.TEXT) {
1080                    continue;
1081                }
1082
1083                String tagName = parser.getName();
1084                if (tagName.equals(TAG_PACKAGE)) {
1085                    String name = parser.getAttributeValue(null, ATTR_NAME);
1086                    ps = mPackages.get(name);
1087                    if (ps == null) {
1088                        Slog.w(PackageManagerService.TAG, "No package known for stopped package: "
1089                                + name);
1090                        XmlUtils.skipCurrentTag(parser);
1091                        continue;
1092                    }
1093                    final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
1094                    final int enabled = enabledStr == null
1095                            ? COMPONENT_ENABLED_STATE_DEFAULT : Integer.parseInt(enabledStr);
1096                    final String enabledCaller = parser.getAttributeValue(null,
1097                            ATTR_ENABLED_CALLER);
1098                    final String installedStr = parser.getAttributeValue(null, ATTR_INSTALLED);
1099                    final boolean installed = installedStr == null
1100                            ? true : Boolean.parseBoolean(installedStr);
1101                    final String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
1102                    final boolean stopped = stoppedStr == null
1103                            ? false : Boolean.parseBoolean(stoppedStr);
1104                    final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
1105                    final boolean blocked = blockedStr == null
1106                            ? false : Boolean.parseBoolean(blockedStr);
1107                    final String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
1108                    final boolean notLaunched = stoppedStr == null
1109                            ? false : Boolean.parseBoolean(notLaunchedStr);
1110
1111                    HashSet<String> enabledComponents = null;
1112                    HashSet<String> disabledComponents = null;
1113
1114                    int packageDepth = parser.getDepth();
1115                    while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1116                            && (type != XmlPullParser.END_TAG
1117                            || parser.getDepth() > packageDepth)) {
1118                        if (type == XmlPullParser.END_TAG
1119                                || type == XmlPullParser.TEXT) {
1120                            continue;
1121                        }
1122                        tagName = parser.getName();
1123                        if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
1124                            enabledComponents = readComponentsLPr(parser);
1125                        } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
1126                            disabledComponents = readComponentsLPr(parser);
1127                        }
1128                    }
1129
1130                    ps.setUserState(userId, enabled, installed, stopped, notLaunched, blocked,
1131                            enabledCaller, enabledComponents, disabledComponents);
1132                } else if (tagName.equals("preferred-activities")) {
1133                    readPreferredActivitiesLPw(parser, userId);
1134                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1135                    readPersistentPreferredActivitiesLPw(parser, userId);
1136                } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)
1137                        || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
1138                    readCrossProfileIntentFiltersLPw(parser, userId);
1139                } else {
1140                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1141                          + parser.getName());
1142                    XmlUtils.skipCurrentTag(parser);
1143                }
1144            }
1145
1146            str.close();
1147
1148        } catch (XmlPullParserException e) {
1149            mReadMessages.append("Error reading: " + e.toString());
1150            PackageManagerService.reportSettingsProblem(Log.ERROR,
1151                    "Error reading stopped packages: " + e);
1152            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1153
1154        } catch (java.io.IOException e) {
1155            mReadMessages.append("Error reading: " + e.toString());
1156            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1157            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1158        }
1159    }
1160
1161    private HashSet<String> readComponentsLPr(XmlPullParser parser)
1162            throws IOException, XmlPullParserException {
1163        HashSet<String> components = null;
1164        int type;
1165        int outerDepth = parser.getDepth();
1166        String tagName;
1167        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1168                && (type != XmlPullParser.END_TAG
1169                || parser.getDepth() > outerDepth)) {
1170            if (type == XmlPullParser.END_TAG
1171                    || type == XmlPullParser.TEXT) {
1172                continue;
1173            }
1174            tagName = parser.getName();
1175            if (tagName.equals(TAG_ITEM)) {
1176                String componentName = parser.getAttributeValue(null, ATTR_NAME);
1177                if (componentName != null) {
1178                    if (components == null) {
1179                        components = new HashSet<String>();
1180                    }
1181                    components.add(componentName);
1182                }
1183            }
1184        }
1185        return components;
1186    }
1187
1188    void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
1189            throws IllegalArgumentException, IllegalStateException, IOException {
1190        serializer.startTag(null, "preferred-activities");
1191        PreferredIntentResolver pir = mPreferredActivities.get(userId);
1192        if (pir != null) {
1193            for (final PreferredActivity pa : pir.filterSet()) {
1194                serializer.startTag(null, TAG_ITEM);
1195                pa.writeToXml(serializer, full);
1196                serializer.endTag(null, TAG_ITEM);
1197            }
1198        }
1199        serializer.endTag(null, "preferred-activities");
1200    }
1201
1202    void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
1203            throws IllegalArgumentException, IllegalStateException, IOException {
1204        serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1205        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1206        if (ppir != null) {
1207            for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
1208                serializer.startTag(null, TAG_ITEM);
1209                ppa.writeToXml(serializer);
1210                serializer.endTag(null, TAG_ITEM);
1211            }
1212        }
1213        serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1214    }
1215
1216    void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)
1217            throws IllegalArgumentException, IllegalStateException, IOException {
1218        serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1219        CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1220        if (cpir != null) {
1221            for (final CrossProfileIntentFilter cpif : cpir.filterSet()) {
1222                serializer.startTag(null, TAG_ITEM);
1223                cpif.writeToXml(serializer);
1224                serializer.endTag(null, TAG_ITEM);
1225            }
1226        }
1227        serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1228    }
1229
1230    void writePackageRestrictionsLPr(int userId) {
1231        if (DEBUG_MU) {
1232            Log.i(TAG, "Writing package restrictions for user=" + userId);
1233        }
1234        // Keep the old stopped packages around until we know the new ones have
1235        // been successfully written.
1236        File userPackagesStateFile = getUserPackagesStateFile(userId);
1237        File backupFile = getUserPackagesStateBackupFile(userId);
1238        new File(userPackagesStateFile.getParent()).mkdirs();
1239        if (userPackagesStateFile.exists()) {
1240            // Presence of backup settings file indicates that we failed
1241            // to persist packages earlier. So preserve the older
1242            // backup for future reference since the current packages
1243            // might have been corrupted.
1244            if (!backupFile.exists()) {
1245                if (!userPackagesStateFile.renameTo(backupFile)) {
1246                    Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, "
1247                            + "current changes will be lost at reboot");
1248                    return;
1249                }
1250            } else {
1251                userPackagesStateFile.delete();
1252                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
1253            }
1254        }
1255
1256        try {
1257            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
1258            final BufferedOutputStream str = new BufferedOutputStream(fstr);
1259
1260            final XmlSerializer serializer = new FastXmlSerializer();
1261            serializer.setOutput(str, "utf-8");
1262            serializer.startDocument(null, true);
1263            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1264
1265            serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
1266
1267            for (final PackageSetting pkg : mPackages.values()) {
1268                PackageUserState ustate = pkg.readUserState(userId);
1269                if (ustate.stopped || ustate.notLaunched || !ustate.installed
1270                        || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT
1271                        || ustate.blocked
1272                        || (ustate.enabledComponents != null
1273                                && ustate.enabledComponents.size() > 0)
1274                        || (ustate.disabledComponents != null
1275                                && ustate.disabledComponents.size() > 0)) {
1276                    serializer.startTag(null, TAG_PACKAGE);
1277                    serializer.attribute(null, ATTR_NAME, pkg.name);
1278                    if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
1279
1280                    if (!ustate.installed) {
1281                        serializer.attribute(null, ATTR_INSTALLED, "false");
1282                    }
1283                    if (ustate.stopped) {
1284                        serializer.attribute(null, ATTR_STOPPED, "true");
1285                    }
1286                    if (ustate.notLaunched) {
1287                        serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
1288                    }
1289                    if (ustate.blocked) {
1290                        serializer.attribute(null, ATTR_BLOCKED, "true");
1291                    }
1292                    if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
1293                        serializer.attribute(null, ATTR_ENABLED,
1294                                Integer.toString(ustate.enabled));
1295                        if (ustate.lastDisableAppCaller != null) {
1296                            serializer.attribute(null, ATTR_ENABLED_CALLER,
1297                                    ustate.lastDisableAppCaller);
1298                        }
1299                    }
1300                    if (ustate.enabledComponents != null
1301                            && ustate.enabledComponents.size() > 0) {
1302                        serializer.startTag(null, TAG_ENABLED_COMPONENTS);
1303                        for (final String name : ustate.enabledComponents) {
1304                            serializer.startTag(null, TAG_ITEM);
1305                            serializer.attribute(null, ATTR_NAME, name);
1306                            serializer.endTag(null, TAG_ITEM);
1307                        }
1308                        serializer.endTag(null, TAG_ENABLED_COMPONENTS);
1309                    }
1310                    if (ustate.disabledComponents != null
1311                            && ustate.disabledComponents.size() > 0) {
1312                        serializer.startTag(null, TAG_DISABLED_COMPONENTS);
1313                        for (final String name : ustate.disabledComponents) {
1314                            serializer.startTag(null, TAG_ITEM);
1315                            serializer.attribute(null, ATTR_NAME, name);
1316                            serializer.endTag(null, TAG_ITEM);
1317                        }
1318                        serializer.endTag(null, TAG_DISABLED_COMPONENTS);
1319                    }
1320                    serializer.endTag(null, TAG_PACKAGE);
1321                }
1322            }
1323
1324            writePreferredActivitiesLPr(serializer, userId, true);
1325
1326            writePersistentPreferredActivitiesLPr(serializer, userId);
1327
1328            writeCrossProfileIntentFiltersLPr(serializer, userId);
1329
1330            serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
1331
1332            serializer.endDocument();
1333
1334            str.flush();
1335            FileUtils.sync(fstr);
1336            str.close();
1337
1338            // New settings successfully written, old ones are no longer
1339            // needed.
1340            backupFile.delete();
1341            FileUtils.setPermissions(userPackagesStateFile.toString(),
1342                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1343                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1344                    -1, -1);
1345
1346            // Done, all is good!
1347            return;
1348        } catch(java.io.IOException e) {
1349            Log.wtf(PackageManagerService.TAG,
1350                    "Unable to write package manager user packages state, "
1351                    + " current changes will be lost at reboot", e);
1352        }
1353
1354        // Clean up partially written files
1355        if (userPackagesStateFile.exists()) {
1356            if (!userPackagesStateFile.delete()) {
1357                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
1358                        + mStoppedPackagesFilename);
1359            }
1360        }
1361    }
1362
1363    // Note: assumed "stopped" field is already cleared in all packages.
1364    // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
1365    void readStoppedLPw() {
1366        FileInputStream str = null;
1367        if (mBackupStoppedPackagesFilename.exists()) {
1368            try {
1369                str = new FileInputStream(mBackupStoppedPackagesFilename);
1370                mReadMessages.append("Reading from backup stopped packages file\n");
1371                PackageManagerService.reportSettingsProblem(Log.INFO,
1372                        "Need to read from backup stopped packages file");
1373                if (mSettingsFilename.exists()) {
1374                    // If both the backup and normal file exist, we
1375                    // ignore the normal one since it might have been
1376                    // corrupted.
1377                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1378                            + mStoppedPackagesFilename);
1379                    mStoppedPackagesFilename.delete();
1380                }
1381            } catch (java.io.IOException e) {
1382                // We'll try for the normal settings file.
1383            }
1384        }
1385
1386        try {
1387            if (str == null) {
1388                if (!mStoppedPackagesFilename.exists()) {
1389                    mReadMessages.append("No stopped packages file found\n");
1390                    PackageManagerService.reportSettingsProblem(Log.INFO,
1391                            "No stopped packages file file; assuming all started");
1392                    // At first boot, make sure no packages are stopped.
1393                    // We usually want to have third party apps initialize
1394                    // in the stopped state, but not at first boot.
1395                    for (PackageSetting pkg : mPackages.values()) {
1396                        pkg.setStopped(false, 0);
1397                        pkg.setNotLaunched(false, 0);
1398                    }
1399                    return;
1400                }
1401                str = new FileInputStream(mStoppedPackagesFilename);
1402            }
1403            final XmlPullParser parser = Xml.newPullParser();
1404            parser.setInput(str, null);
1405
1406            int type;
1407            while ((type=parser.next()) != XmlPullParser.START_TAG
1408                       && type != XmlPullParser.END_DOCUMENT) {
1409                ;
1410            }
1411
1412            if (type != XmlPullParser.START_TAG) {
1413                mReadMessages.append("No start tag found in stopped packages file\n");
1414                PackageManagerService.reportSettingsProblem(Log.WARN,
1415                        "No start tag found in package manager stopped packages");
1416                return;
1417            }
1418
1419            int outerDepth = parser.getDepth();
1420            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1421                   && (type != XmlPullParser.END_TAG
1422                           || parser.getDepth() > outerDepth)) {
1423                if (type == XmlPullParser.END_TAG
1424                        || type == XmlPullParser.TEXT) {
1425                    continue;
1426                }
1427
1428                String tagName = parser.getName();
1429                if (tagName.equals(TAG_PACKAGE)) {
1430                    String name = parser.getAttributeValue(null, ATTR_NAME);
1431                    PackageSetting ps = mPackages.get(name);
1432                    if (ps != null) {
1433                        ps.setStopped(true, 0);
1434                        if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
1435                            ps.setNotLaunched(true, 0);
1436                        }
1437                    } else {
1438                        Slog.w(PackageManagerService.TAG,
1439                                "No package known for stopped package: " + name);
1440                    }
1441                    XmlUtils.skipCurrentTag(parser);
1442                } else {
1443                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1444                          + parser.getName());
1445                    XmlUtils.skipCurrentTag(parser);
1446                }
1447            }
1448
1449            str.close();
1450
1451        } catch (XmlPullParserException e) {
1452            mReadMessages.append("Error reading: " + e.toString());
1453            PackageManagerService.reportSettingsProblem(Log.ERROR,
1454                    "Error reading stopped packages: " + e);
1455            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1456
1457        } catch (java.io.IOException e) {
1458            mReadMessages.append("Error reading: " + e.toString());
1459            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1460            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1461
1462        }
1463    }
1464
1465    void writeLPr() {
1466        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
1467
1468        // Keep the old settings around until we know the new ones have
1469        // been successfully written.
1470        if (mSettingsFilename.exists()) {
1471            // Presence of backup settings file indicates that we failed
1472            // to persist settings earlier. So preserve the older
1473            // backup for future reference since the current settings
1474            // might have been corrupted.
1475            if (!mBackupSettingsFilename.exists()) {
1476                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
1477                    Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
1478                            + " current changes will be lost at reboot");
1479                    return;
1480                }
1481            } else {
1482                mSettingsFilename.delete();
1483                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
1484            }
1485        }
1486
1487        mPastSignatures.clear();
1488
1489        try {
1490            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
1491            BufferedOutputStream str = new BufferedOutputStream(fstr);
1492
1493            //XmlSerializer serializer = XmlUtils.serializerInstance();
1494            XmlSerializer serializer = new FastXmlSerializer();
1495            serializer.setOutput(str, "utf-8");
1496            serializer.startDocument(null, true);
1497            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1498
1499            serializer.startTag(null, "packages");
1500
1501            serializer.startTag(null, "last-platform-version");
1502            serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
1503            serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
1504            serializer.endTag(null, "last-platform-version");
1505
1506            serializer.startTag(null, "database-version");
1507            serializer.attribute(null, "internal", Integer.toString(mInternalDatabaseVersion));
1508            serializer.attribute(null, "external", Integer.toString(mExternalDatabaseVersion));
1509            serializer.endTag(null, "database-version");
1510
1511            if (mVerifierDeviceIdentity != null) {
1512                serializer.startTag(null, "verifier");
1513                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
1514                serializer.endTag(null, "verifier");
1515            }
1516
1517            if (mReadExternalStorageEnforced != null) {
1518                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
1519                serializer.attribute(
1520                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
1521                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
1522            }
1523
1524            serializer.startTag(null, "permission-trees");
1525            for (BasePermission bp : mPermissionTrees.values()) {
1526                writePermissionLPr(serializer, bp);
1527            }
1528            serializer.endTag(null, "permission-trees");
1529
1530            serializer.startTag(null, "permissions");
1531            for (BasePermission bp : mPermissions.values()) {
1532                writePermissionLPr(serializer, bp);
1533            }
1534            serializer.endTag(null, "permissions");
1535
1536            for (final PackageSetting pkg : mPackages.values()) {
1537                writePackageLPr(serializer, pkg);
1538            }
1539
1540            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
1541                writeDisabledSysPackageLPr(serializer, pkg);
1542            }
1543
1544            for (final SharedUserSetting usr : mSharedUsers.values()) {
1545                serializer.startTag(null, "shared-user");
1546                serializer.attribute(null, ATTR_NAME, usr.name);
1547                serializer.attribute(null, "userId",
1548                        Integer.toString(usr.userId));
1549                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
1550                serializer.startTag(null, "perms");
1551                for (String name : usr.grantedPermissions) {
1552                    serializer.startTag(null, TAG_ITEM);
1553                    serializer.attribute(null, ATTR_NAME, name);
1554                    serializer.endTag(null, TAG_ITEM);
1555                }
1556                serializer.endTag(null, "perms");
1557                serializer.endTag(null, "shared-user");
1558            }
1559
1560            if (mPackagesToBeCleaned.size() > 0) {
1561                for (PackageCleanItem item : mPackagesToBeCleaned) {
1562                    final String userStr = Integer.toString(item.userId);
1563                    serializer.startTag(null, "cleaning-package");
1564                    serializer.attribute(null, ATTR_NAME, item.packageName);
1565                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
1566                    serializer.attribute(null, ATTR_USER, userStr);
1567                    serializer.endTag(null, "cleaning-package");
1568                }
1569            }
1570
1571            if (mRenamedPackages.size() > 0) {
1572                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
1573                    serializer.startTag(null, "renamed-package");
1574                    serializer.attribute(null, "new", e.getKey());
1575                    serializer.attribute(null, "old", e.getValue());
1576                    serializer.endTag(null, "renamed-package");
1577                }
1578            }
1579
1580            mKeySetManager.writeKeySetManagerLPr(serializer);
1581
1582            serializer.endTag(null, "packages");
1583
1584            serializer.endDocument();
1585
1586            str.flush();
1587            FileUtils.sync(fstr);
1588            str.close();
1589
1590            // New settings successfully written, old ones are no longer
1591            // needed.
1592            mBackupSettingsFilename.delete();
1593            FileUtils.setPermissions(mSettingsFilename.toString(),
1594                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1595                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1596                    -1, -1);
1597
1598            // Write package list file now, use a JournaledFile.
1599            File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
1600            JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
1601
1602            final File writeTarget = journal.chooseForWrite();
1603            fstr = new FileOutputStream(writeTarget);
1604            str = new BufferedOutputStream(fstr);
1605            try {
1606                FileUtils.setPermissions(fstr.getFD(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
1607
1608                StringBuilder sb = new StringBuilder();
1609                for (final PackageSetting pkg : mPackages.values()) {
1610                    if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
1611                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
1612                        continue;
1613                    }
1614
1615                    final ApplicationInfo ai = pkg.pkg.applicationInfo;
1616                    final String dataPath = ai.dataDir;
1617                    final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1618                    final int[] gids = pkg.getGids();
1619
1620                    // Avoid any application that has a space in its path.
1621                    if (dataPath.indexOf(" ") >= 0)
1622                        continue;
1623
1624                    // we store on each line the following information for now:
1625                    //
1626                    // pkgName    - package name
1627                    // userId     - application-specific user id
1628                    // debugFlag  - 0 or 1 if the package is debuggable.
1629                    // dataPath   - path to package's data path
1630                    // seinfo     - seinfo label for the app (assigned at install time)
1631                    // gids       - supplementary gids this app launches with
1632                    //
1633                    // NOTE: We prefer not to expose all ApplicationInfo flags for now.
1634                    //
1635                    // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
1636                    // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
1637                    //   system/core/run-as/run-as.c
1638                    //   system/core/sdcard/sdcard.c
1639                    //   external/libselinux/src/android.c:package_info_init()
1640                    //
1641                    sb.setLength(0);
1642                    sb.append(ai.packageName);
1643                    sb.append(" ");
1644                    sb.append((int)ai.uid);
1645                    sb.append(isDebug ? " 1 " : " 0 ");
1646                    sb.append(dataPath);
1647                    sb.append(" ");
1648                    sb.append(ai.seinfo);
1649                    sb.append(" ");
1650                    if (gids != null && gids.length > 0) {
1651                        sb.append(gids[0]);
1652                        for (int i = 1; i < gids.length; i++) {
1653                            sb.append(",");
1654                            sb.append(gids[i]);
1655                        }
1656                    } else {
1657                        sb.append("none");
1658                    }
1659                    sb.append("\n");
1660                    str.write(sb.toString().getBytes());
1661                }
1662                str.flush();
1663                FileUtils.sync(fstr);
1664                str.close();
1665                journal.commit();
1666            } catch (Exception e) {
1667                Log.wtf(TAG, "Failed to write packages.list", e);
1668                IoUtils.closeQuietly(str);
1669                journal.rollback();
1670            }
1671
1672            writeAllUsersPackageRestrictionsLPr();
1673            return;
1674
1675        } catch(XmlPullParserException e) {
1676            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1677                    + "current changes will be lost at reboot", e);
1678        } catch(java.io.IOException e) {
1679            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1680                    + "current changes will be lost at reboot", e);
1681        }
1682        // Clean up partially written files
1683        if (mSettingsFilename.exists()) {
1684            if (!mSettingsFilename.delete()) {
1685                Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
1686                        + mSettingsFilename);
1687            }
1688        }
1689        //Debug.stopMethodTracing();
1690    }
1691
1692    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1693            throws java.io.IOException {
1694        serializer.startTag(null, "updated-package");
1695        serializer.attribute(null, ATTR_NAME, pkg.name);
1696        if (pkg.realName != null) {
1697            serializer.attribute(null, "realName", pkg.realName);
1698        }
1699        serializer.attribute(null, "codePath", pkg.codePathString);
1700        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1701        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1702        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1703        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1704        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1705            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1706        }
1707        if (pkg.nativeLibraryPathString != null) {
1708            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1709        }
1710        if (pkg.cpuAbiString != null) {
1711           serializer.attribute(null, "requiredCpuAbi", pkg.cpuAbiString);
1712        }
1713        if (pkg.sharedUser == null) {
1714            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1715        } else {
1716            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1717        }
1718        serializer.startTag(null, "perms");
1719        if (pkg.sharedUser == null) {
1720            // If this is a shared user, the permissions will
1721            // be written there. We still need to write an
1722            // empty permissions list so permissionsFixed will
1723            // be set.
1724            for (final String name : pkg.grantedPermissions) {
1725                BasePermission bp = mPermissions.get(name);
1726                if (bp != null) {
1727                    // We only need to write signature or system permissions but
1728                    // this wont
1729                    // match the semantics of grantedPermissions. So write all
1730                    // permissions.
1731                    serializer.startTag(null, TAG_ITEM);
1732                    serializer.attribute(null, ATTR_NAME, name);
1733                    serializer.endTag(null, TAG_ITEM);
1734                }
1735            }
1736        }
1737        serializer.endTag(null, "perms");
1738        serializer.endTag(null, "updated-package");
1739    }
1740
1741    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1742            throws java.io.IOException {
1743        serializer.startTag(null, "package");
1744        serializer.attribute(null, ATTR_NAME, pkg.name);
1745        if (pkg.realName != null) {
1746            serializer.attribute(null, "realName", pkg.realName);
1747        }
1748        serializer.attribute(null, "codePath", pkg.codePathString);
1749        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1750            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1751        }
1752        if (pkg.nativeLibraryPathString != null) {
1753            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1754        }
1755        if (pkg.cpuAbiString != null) {
1756           serializer.attribute(null, "requiredCpuAbi", pkg.cpuAbiString);
1757        }
1758        serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1759        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1760        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1761        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1762        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1763        if (pkg.sharedUser == null) {
1764            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1765        } else {
1766            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1767        }
1768        if (pkg.uidError) {
1769            serializer.attribute(null, "uidError", "true");
1770        }
1771        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1772            serializer.attribute(null, "installStatus", "false");
1773        }
1774        if (pkg.installerPackageName != null) {
1775            serializer.attribute(null, "installer", pkg.installerPackageName);
1776        }
1777        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1778        if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1779            serializer.startTag(null, "perms");
1780            if (pkg.sharedUser == null) {
1781                // If this is a shared user, the permissions will
1782                // be written there. We still need to write an
1783                // empty permissions list so permissionsFixed will
1784                // be set.
1785                for (final String name : pkg.grantedPermissions) {
1786                    serializer.startTag(null, TAG_ITEM);
1787                    serializer.attribute(null, ATTR_NAME, name);
1788                    serializer.endTag(null, TAG_ITEM);
1789                }
1790            }
1791            serializer.endTag(null, "perms");
1792        }
1793
1794        writeSigningKeySetsLPr(serializer, pkg.keySetData);
1795        writeKeySetAliasesLPr(serializer, pkg.keySetData);
1796
1797        serializer.endTag(null, "package");
1798    }
1799
1800    void writeSigningKeySetsLPr(XmlSerializer serializer,
1801            PackageKeySetData data) throws IOException {
1802        for (long id : data.getSigningKeySets()) {
1803            serializer.startTag(null, "signing-keyset");
1804            serializer.attribute(null, "identifier", Long.toString(id));
1805            serializer.endTag(null, "signing-keyset");
1806        }
1807    }
1808
1809    void writeKeySetAliasesLPr(XmlSerializer serializer,
1810            PackageKeySetData data) throws IOException {
1811        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
1812            serializer.startTag(null, "defined-keyset");
1813            serializer.attribute(null, "alias", e.getKey());
1814            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
1815            serializer.endTag(null, "defined-keyset");
1816        }
1817    }
1818
1819    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1820            throws XmlPullParserException, java.io.IOException {
1821        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1822            serializer.startTag(null, TAG_ITEM);
1823            serializer.attribute(null, ATTR_NAME, bp.name);
1824            serializer.attribute(null, "package", bp.sourcePackage);
1825            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1826                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1827            }
1828            if (PackageManagerService.DEBUG_SETTINGS)
1829                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1830                        + bp.type);
1831            if (bp.type == BasePermission.TYPE_DYNAMIC) {
1832                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1833                if (pi != null) {
1834                    serializer.attribute(null, "type", "dynamic");
1835                    if (pi.icon != 0) {
1836                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
1837                    }
1838                    if (pi.nonLocalizedLabel != null) {
1839                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1840                    }
1841                }
1842            }
1843            serializer.endTag(null, TAG_ITEM);
1844        }
1845    }
1846
1847    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
1848        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
1849        final Iterator<String> its = kList.iterator();
1850        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
1851        while (its.hasNext()) {
1852            final String key = its.next();
1853            final PackageSetting ps = mPackages.get(key);
1854            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1855                ret.add(ps);
1856            }
1857        }
1858        return ret;
1859    }
1860
1861    void addPackageToCleanLPw(PackageCleanItem pkg) {
1862        if (!mPackagesToBeCleaned.contains(pkg)) {
1863            mPackagesToBeCleaned.add(pkg);
1864        }
1865    }
1866
1867    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
1868            boolean onlyCore) {
1869        FileInputStream str = null;
1870        if (mBackupSettingsFilename.exists()) {
1871            try {
1872                str = new FileInputStream(mBackupSettingsFilename);
1873                mReadMessages.append("Reading from backup settings file\n");
1874                PackageManagerService.reportSettingsProblem(Log.INFO,
1875                        "Need to read from backup settings file");
1876                if (mSettingsFilename.exists()) {
1877                    // If both the backup and settings file exist, we
1878                    // ignore the settings since it might have been
1879                    // corrupted.
1880                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
1881                            + mSettingsFilename);
1882                    mSettingsFilename.delete();
1883                }
1884            } catch (java.io.IOException e) {
1885                // We'll try for the normal settings file.
1886            }
1887        }
1888
1889        mPendingPackages.clear();
1890        mPastSignatures.clear();
1891
1892        try {
1893            if (str == null) {
1894                if (!mSettingsFilename.exists()) {
1895                    mReadMessages.append("No settings file found\n");
1896                    PackageManagerService.reportSettingsProblem(Log.INFO,
1897                            "No settings file; creating initial state");
1898                    mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion;
1899                    return false;
1900                }
1901                str = new FileInputStream(mSettingsFilename);
1902            }
1903            XmlPullParser parser = Xml.newPullParser();
1904            parser.setInput(str, null);
1905
1906            int type;
1907            while ((type = parser.next()) != XmlPullParser.START_TAG
1908                    && type != XmlPullParser.END_DOCUMENT) {
1909                ;
1910            }
1911
1912            if (type != XmlPullParser.START_TAG) {
1913                mReadMessages.append("No start tag found in settings file\n");
1914                PackageManagerService.reportSettingsProblem(Log.WARN,
1915                        "No start tag found in package manager settings");
1916                Log.wtf(PackageManagerService.TAG,
1917                        "No start tag found in package manager settings");
1918                return false;
1919            }
1920
1921            int outerDepth = parser.getDepth();
1922            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1923                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1924                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1925                    continue;
1926                }
1927
1928                String tagName = parser.getName();
1929                if (tagName.equals("package")) {
1930                    readPackageLPw(parser);
1931                } else if (tagName.equals("permissions")) {
1932                    readPermissionsLPw(mPermissions, parser);
1933                } else if (tagName.equals("permission-trees")) {
1934                    readPermissionsLPw(mPermissionTrees, parser);
1935                } else if (tagName.equals("shared-user")) {
1936                    readSharedUserLPw(parser);
1937                } else if (tagName.equals("preferred-packages")) {
1938                    // no longer used.
1939                } else if (tagName.equals("preferred-activities")) {
1940                    // Upgrading from old single-user implementation;
1941                    // these are the preferred activities for user 0.
1942                    readPreferredActivitiesLPw(parser, 0);
1943                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1944                    // TODO: check whether this is okay! as it is very
1945                    // similar to how preferred-activities are treated
1946                    readPersistentPreferredActivitiesLPw(parser, 0);
1947                } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)
1948                        || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
1949                    // TODO: check whether this is okay! as it is very
1950                    // similar to how preferred-activities are treated
1951                    readCrossProfileIntentFiltersLPw(parser, 0);
1952                } else if (tagName.equals("updated-package")) {
1953                    readDisabledSysPackageLPw(parser);
1954                } else if (tagName.equals("cleaning-package")) {
1955                    String name = parser.getAttributeValue(null, ATTR_NAME);
1956                    String userStr = parser.getAttributeValue(null, ATTR_USER);
1957                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
1958                    if (name != null) {
1959                        int userId = 0;
1960                        boolean andCode = true;
1961                        try {
1962                            if (userStr != null) {
1963                                userId = Integer.parseInt(userStr);
1964                            }
1965                        } catch (NumberFormatException e) {
1966                        }
1967                        if (codeStr != null) {
1968                            andCode = Boolean.parseBoolean(codeStr);
1969                        }
1970                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
1971                    }
1972                } else if (tagName.equals("renamed-package")) {
1973                    String nname = parser.getAttributeValue(null, "new");
1974                    String oname = parser.getAttributeValue(null, "old");
1975                    if (nname != null && oname != null) {
1976                        mRenamedPackages.put(nname, oname);
1977                    }
1978                } else if (tagName.equals("last-platform-version")) {
1979                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
1980                    try {
1981                        String internal = parser.getAttributeValue(null, "internal");
1982                        if (internal != null) {
1983                            mInternalSdkPlatform = Integer.parseInt(internal);
1984                        }
1985                        String external = parser.getAttributeValue(null, "external");
1986                        if (external != null) {
1987                            mExternalSdkPlatform = Integer.parseInt(external);
1988                        }
1989                    } catch (NumberFormatException e) {
1990                    }
1991                } else if (tagName.equals("database-version")) {
1992                    mInternalDatabaseVersion = mExternalDatabaseVersion = 0;
1993                    try {
1994                        String internalDbVersionString = parser.getAttributeValue(null, "internal");
1995                        if (internalDbVersionString != null) {
1996                            mInternalDatabaseVersion = Integer.parseInt(internalDbVersionString);
1997                        }
1998                        String externalDbVersionString = parser.getAttributeValue(null, "external");
1999                        if (externalDbVersionString != null) {
2000                            mExternalDatabaseVersion = Integer.parseInt(externalDbVersionString);
2001                        }
2002                    } catch (NumberFormatException ignored) {
2003                    }
2004                } else if (tagName.equals("verifier")) {
2005                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2006                    try {
2007                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2008                    } catch (IllegalArgumentException e) {
2009                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2010                                + e.getMessage());
2011                    }
2012                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2013                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2014                    mReadExternalStorageEnforced = "1".equals(enforcement);
2015                } else if (tagName.equals("keyset-settings")) {
2016                    mKeySetManager.readKeySetsLPw(parser);
2017                } else {
2018                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2019                            + parser.getName());
2020                    XmlUtils.skipCurrentTag(parser);
2021                }
2022            }
2023
2024            str.close();
2025
2026        } catch (XmlPullParserException e) {
2027            mReadMessages.append("Error reading: " + e.toString());
2028            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2029            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2030
2031        } catch (java.io.IOException e) {
2032            mReadMessages.append("Error reading: " + e.toString());
2033            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2034            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2035        }
2036
2037        final int N = mPendingPackages.size();
2038        for (int i = 0; i < N; i++) {
2039            final PendingPackage pp = mPendingPackages.get(i);
2040            Object idObj = getUserIdLPr(pp.sharedId);
2041            if (idObj != null && idObj instanceof SharedUserSetting) {
2042                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
2043                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
2044                        pp.nativeLibraryPathString, pp.cpuAbiString, pp.versionCode, pp.pkgFlags,
2045                        null, true /* add */, false /* allowInstall */);
2046                if (p == null) {
2047                    PackageManagerService.reportSettingsProblem(Log.WARN,
2048                            "Unable to create application package for " + pp.name);
2049                    continue;
2050                }
2051                p.copyFrom(pp);
2052            } else if (idObj != null) {
2053                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2054                        + pp.sharedId + " that is not a shared uid\n";
2055                mReadMessages.append(msg);
2056                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2057            } else {
2058                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2059                        + pp.sharedId + " that is not defined\n";
2060                mReadMessages.append(msg);
2061                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2062            }
2063        }
2064        mPendingPackages.clear();
2065
2066        if (mBackupStoppedPackagesFilename.exists()
2067                || mStoppedPackagesFilename.exists()) {
2068            // Read old file
2069            readStoppedLPw();
2070            mBackupStoppedPackagesFilename.delete();
2071            mStoppedPackagesFilename.delete();
2072            // Migrate to new file format
2073            writePackageRestrictionsLPr(0);
2074        } else {
2075            if (users == null) {
2076                readPackageRestrictionsLPr(0);
2077            } else {
2078                for (UserInfo user : users) {
2079                    readPackageRestrictionsLPr(user.id);
2080                }
2081            }
2082        }
2083
2084        /*
2085         * Make sure all the updated system packages have their shared users
2086         * associated with them.
2087         */
2088        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
2089        while (disabledIt.hasNext()) {
2090            final PackageSetting disabledPs = disabledIt.next();
2091            final Object id = getUserIdLPr(disabledPs.appId);
2092            if (id != null && id instanceof SharedUserSetting) {
2093                disabledPs.sharedUser = (SharedUserSetting) id;
2094            }
2095        }
2096
2097        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
2098                + mSharedUsers.size() + " shared uids\n");
2099
2100        return true;
2101    }
2102
2103    void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
2104        // First pull data from any pre-installed apps.
2105        for (PackageSetting ps : mPackages.values()) {
2106            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
2107                    && ps.pkg.preferredActivityFilters != null) {
2108                ArrayList<PackageParser.ActivityIntentInfo> intents
2109                        = ps.pkg.preferredActivityFilters;
2110                for (int i=0; i<intents.size(); i++) {
2111                    PackageParser.ActivityIntentInfo aii = intents.get(i);
2112                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
2113                            ps.name, aii.activity.className), userId);
2114                }
2115            }
2116        }
2117
2118        // Read preferred apps from .../etc/preferred-apps directory.
2119        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
2120        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
2121            return;
2122        }
2123        if (!preferredDir.canRead()) {
2124            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
2125            return;
2126        }
2127
2128        // Iterate over the files in the directory and scan .xml files
2129        for (File f : preferredDir.listFiles()) {
2130            if (!f.getPath().endsWith(".xml")) {
2131                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
2132                continue;
2133            }
2134            if (!f.canRead()) {
2135                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
2136                continue;
2137            }
2138
2139            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
2140            FileInputStream str = null;
2141            try {
2142                str = new FileInputStream(f);
2143                XmlPullParser parser = Xml.newPullParser();
2144                parser.setInput(str, null);
2145
2146                int type;
2147                while ((type = parser.next()) != XmlPullParser.START_TAG
2148                        && type != XmlPullParser.END_DOCUMENT) {
2149                    ;
2150                }
2151
2152                if (type != XmlPullParser.START_TAG) {
2153                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
2154                    continue;
2155                }
2156                if (!"preferred-activities".equals(parser.getName())) {
2157                    Slog.w(TAG, "Preferred apps file " + f
2158                            + " does not start with 'preferred-activities'");
2159                    continue;
2160                }
2161                readDefaultPreferredActivitiesLPw(service, parser, userId);
2162            } catch (XmlPullParserException e) {
2163                Slog.w(TAG, "Error reading apps file " + f, e);
2164            } catch (IOException e) {
2165                Slog.w(TAG, "Error reading apps file " + f, e);
2166            } finally {
2167                if (str != null) {
2168                    try {
2169                        str.close();
2170                    } catch (IOException e) {
2171                    }
2172                }
2173            }
2174        }
2175    }
2176
2177    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2178            IntentFilter tmpPa, ComponentName cn, int userId) {
2179        // The initial preferences only specify the target activity
2180        // component and intent-filter, not the set of matches.  So we
2181        // now need to query for the matches to build the correct
2182        // preferred activity entry.
2183        if (PackageManagerService.DEBUG_PREFERRED) {
2184            Log.d(TAG, "Processing preferred:");
2185            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
2186        }
2187        Intent intent = new Intent();
2188        int flags = 0;
2189        intent.setAction(tmpPa.getAction(0));
2190        for (int i=0; i<tmpPa.countCategories(); i++) {
2191            String cat = tmpPa.getCategory(i);
2192            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
2193                flags |= PackageManager.MATCH_DEFAULT_ONLY;
2194            } else {
2195                intent.addCategory(cat);
2196            }
2197        }
2198
2199        boolean doNonData = true;
2200        boolean hasSchemes = false;
2201
2202        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2203            boolean doScheme = true;
2204            String scheme = tmpPa.getDataScheme(ischeme);
2205            if (scheme != null && !scheme.isEmpty()) {
2206                hasSchemes = true;
2207            }
2208            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
2209                Uri.Builder builder = new Uri.Builder();
2210                builder.scheme(scheme);
2211                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
2212                builder.opaquePart(ssp.getPath());
2213                Intent finalIntent = new Intent(intent);
2214                finalIntent.setData(builder.build());
2215                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2216                        scheme, ssp, null, null, null, userId);
2217                doScheme = false;
2218            }
2219            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
2220                boolean doAuth = true;
2221                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
2222                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
2223                    Uri.Builder builder = new Uri.Builder();
2224                    builder.scheme(scheme);
2225                    if (auth.getHost() != null) {
2226                        builder.authority(auth.getHost());
2227                    }
2228                    PatternMatcher path = tmpPa.getDataPath(ipath);
2229                    builder.path(path.getPath());
2230                    Intent finalIntent = new Intent(intent);
2231                    finalIntent.setData(builder.build());
2232                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2233                            scheme, null, auth, path, null, userId);
2234                    doAuth = doScheme = false;
2235                }
2236                if (doAuth) {
2237                    Uri.Builder builder = new Uri.Builder();
2238                    builder.scheme(scheme);
2239                    if (auth.getHost() != null) {
2240                        builder.authority(auth.getHost());
2241                    }
2242                    Intent finalIntent = new Intent(intent);
2243                    finalIntent.setData(builder.build());
2244                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2245                            scheme, null, auth, null, null, userId);
2246                    doScheme = false;
2247                }
2248            }
2249            if (doScheme) {
2250                Uri.Builder builder = new Uri.Builder();
2251                builder.scheme(scheme);
2252                Intent finalIntent = new Intent(intent);
2253                finalIntent.setData(builder.build());
2254                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2255                        scheme, null, null, null, null, userId);
2256            }
2257            doNonData = false;
2258        }
2259
2260        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
2261            String mimeType = tmpPa.getDataType(idata);
2262            if (hasSchemes) {
2263                Uri.Builder builder = new Uri.Builder();
2264                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2265                    String scheme = tmpPa.getDataScheme(ischeme);
2266                    if (scheme != null && !scheme.isEmpty()) {
2267                        Intent finalIntent = new Intent(intent);
2268                        builder.scheme(scheme);
2269                        finalIntent.setDataAndType(builder.build(), mimeType);
2270                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2271                                scheme, null, null, null, mimeType, userId);
2272                    }
2273                }
2274            } else {
2275                Intent finalIntent = new Intent(intent);
2276                finalIntent.setType(mimeType);
2277                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2278                        null, null, null, null, mimeType, userId);
2279            }
2280            doNonData = false;
2281        }
2282
2283        if (doNonData) {
2284            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
2285                    null, null, null, null, null, userId);
2286        }
2287    }
2288
2289    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2290            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
2291            IntentFilter.AuthorityEntry auth, PatternMatcher path, String mimeType,
2292            int userId) {
2293        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
2294                intent.getType(), flags, 0);
2295        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
2296                + " results: " + ri);
2297        int match = 0;
2298        if (ri != null && ri.size() > 1) {
2299            boolean haveAct = false;
2300            boolean haveNonSys = false;
2301            ComponentName[] set = new ComponentName[ri.size()];
2302            for (int i=0; i<ri.size(); i++) {
2303                ActivityInfo ai = ri.get(i).activityInfo;
2304                set[i] = new ComponentName(ai.packageName, ai.name);
2305                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
2306                    // If any of the matches are not system apps, then
2307                    // there is a third party app that is now an option...
2308                    // so don't set a default since we don't want to hide it.
2309                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2310                            + ai.packageName + "/" + ai.name + ": non-system!");
2311                    haveNonSys = true;
2312                    break;
2313                } else if (cn.getPackageName().equals(ai.packageName)
2314                        && cn.getClassName().equals(ai.name)) {
2315                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2316                            + ai.packageName + "/" + ai.name + ": default!");
2317                    haveAct = true;
2318                    match = ri.get(i).match;
2319                } else {
2320                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2321                            + ai.packageName + "/" + ai.name + ": skipped");
2322                }
2323            }
2324            if (haveAct && !haveNonSys) {
2325                IntentFilter filter = new IntentFilter();
2326                if (intent.getAction() != null) {
2327                    filter.addAction(intent.getAction());
2328                }
2329                if (intent.getCategories() != null) {
2330                    for (String cat : intent.getCategories()) {
2331                        filter.addCategory(cat);
2332                    }
2333                }
2334                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
2335                    filter.addCategory(Intent.CATEGORY_DEFAULT);
2336                }
2337                if (scheme != null) {
2338                    filter.addDataScheme(scheme);
2339                }
2340                if (ssp != null) {
2341                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
2342                }
2343                if (auth != null) {
2344                    filter.addDataAuthority(auth);
2345                }
2346                if (path != null) {
2347                    filter.addDataPath(path);
2348                }
2349                if (intent.getType() != null) {
2350                    try {
2351                        filter.addDataType(intent.getType());
2352                    } catch (IntentFilter.MalformedMimeTypeException ex) {
2353                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
2354                    }
2355                }
2356                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
2357                editPreferredActivitiesLPw(userId).addFilter(pa);
2358            } else if (!haveNonSys) {
2359                Slog.w(TAG, "No component found for default preferred activity " + cn);
2360            }
2361        }
2362    }
2363
2364    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
2365            XmlPullParser parser, int userId)
2366            throws XmlPullParserException, IOException {
2367        int outerDepth = parser.getDepth();
2368        int type;
2369        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2370                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2371            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2372                continue;
2373            }
2374
2375            String tagName = parser.getName();
2376            if (tagName.equals(TAG_ITEM)) {
2377                PreferredActivity tmpPa = new PreferredActivity(parser);
2378                if (tmpPa.mPref.getParseError() == null) {
2379                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
2380                            userId);
2381                } else {
2382                    PackageManagerService.reportSettingsProblem(Log.WARN,
2383                            "Error in package manager settings: <preferred-activity> "
2384                                    + tmpPa.mPref.getParseError() + " at "
2385                                    + parser.getPositionDescription());
2386                }
2387            } else {
2388                PackageManagerService.reportSettingsProblem(Log.WARN,
2389                        "Unknown element under <preferred-activities>: " + parser.getName());
2390                XmlUtils.skipCurrentTag(parser);
2391            }
2392        }
2393    }
2394
2395    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
2396        String v = parser.getAttributeValue(ns, name);
2397        try {
2398            if (v == null) {
2399                return defValue;
2400            }
2401            return Integer.parseInt(v);
2402        } catch (NumberFormatException e) {
2403            PackageManagerService.reportSettingsProblem(Log.WARN,
2404                    "Error in package manager settings: attribute " + name
2405                            + " has bad integer value " + v + " at "
2406                            + parser.getPositionDescription());
2407        }
2408        return defValue;
2409    }
2410
2411    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
2412            throws IOException, XmlPullParserException {
2413        int outerDepth = parser.getDepth();
2414        int type;
2415        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2416                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2417            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2418                continue;
2419            }
2420
2421            final String tagName = parser.getName();
2422            if (tagName.equals(TAG_ITEM)) {
2423                final String name = parser.getAttributeValue(null, ATTR_NAME);
2424                final String sourcePackage = parser.getAttributeValue(null, "package");
2425                final String ptype = parser.getAttributeValue(null, "type");
2426                if (name != null && sourcePackage != null) {
2427                    final boolean dynamic = "dynamic".equals(ptype);
2428                    final BasePermission bp = new BasePermission(name, sourcePackage,
2429                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
2430                    bp.protectionLevel = readInt(parser, null, "protection",
2431                            PermissionInfo.PROTECTION_NORMAL);
2432                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
2433                    if (dynamic) {
2434                        PermissionInfo pi = new PermissionInfo();
2435                        pi.packageName = sourcePackage.intern();
2436                        pi.name = name.intern();
2437                        pi.icon = readInt(parser, null, "icon", 0);
2438                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
2439                        pi.protectionLevel = bp.protectionLevel;
2440                        bp.pendingInfo = pi;
2441                    }
2442                    out.put(bp.name, bp);
2443                } else {
2444                    PackageManagerService.reportSettingsProblem(Log.WARN,
2445                            "Error in package manager settings: permissions has" + " no name at "
2446                                    + parser.getPositionDescription());
2447                }
2448            } else {
2449                PackageManagerService.reportSettingsProblem(Log.WARN,
2450                        "Unknown element reading permissions: " + parser.getName() + " at "
2451                                + parser.getPositionDescription());
2452            }
2453            XmlUtils.skipCurrentTag(parser);
2454        }
2455    }
2456
2457    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
2458            IOException {
2459        String name = parser.getAttributeValue(null, ATTR_NAME);
2460        String realName = parser.getAttributeValue(null, "realName");
2461        String codePathStr = parser.getAttributeValue(null, "codePath");
2462        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2463        String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2464        String cpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2465
2466        if (resourcePathStr == null) {
2467            resourcePathStr = codePathStr;
2468        }
2469        String version = parser.getAttributeValue(null, "version");
2470        int versionCode = 0;
2471        if (version != null) {
2472            try {
2473                versionCode = Integer.parseInt(version);
2474            } catch (NumberFormatException e) {
2475            }
2476        }
2477
2478        int pkgFlags = 0;
2479        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2480        final File codePathFile = new File(codePathStr);
2481        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
2482            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
2483        }
2484        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
2485                new File(resourcePathStr), nativeLibraryPathStr, cpuAbiString, versionCode, pkgFlags);
2486        String timeStampStr = parser.getAttributeValue(null, "ft");
2487        if (timeStampStr != null) {
2488            try {
2489                long timeStamp = Long.parseLong(timeStampStr, 16);
2490                ps.setTimeStamp(timeStamp);
2491            } catch (NumberFormatException e) {
2492            }
2493        } else {
2494            timeStampStr = parser.getAttributeValue(null, "ts");
2495            if (timeStampStr != null) {
2496                try {
2497                    long timeStamp = Long.parseLong(timeStampStr);
2498                    ps.setTimeStamp(timeStamp);
2499                } catch (NumberFormatException e) {
2500                }
2501            }
2502        }
2503        timeStampStr = parser.getAttributeValue(null, "it");
2504        if (timeStampStr != null) {
2505            try {
2506                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
2507            } catch (NumberFormatException e) {
2508            }
2509        }
2510        timeStampStr = parser.getAttributeValue(null, "ut");
2511        if (timeStampStr != null) {
2512            try {
2513                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
2514            } catch (NumberFormatException e) {
2515            }
2516        }
2517        String idStr = parser.getAttributeValue(null, "userId");
2518        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
2519        if (ps.appId <= 0) {
2520            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2521            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2522        }
2523        int outerDepth = parser.getDepth();
2524        int type;
2525        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2526                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2527            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2528                continue;
2529            }
2530
2531            String tagName = parser.getName();
2532            if (tagName.equals("perms")) {
2533                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
2534            } else {
2535                PackageManagerService.reportSettingsProblem(Log.WARN,
2536                        "Unknown element under <updated-package>: " + parser.getName());
2537                XmlUtils.skipCurrentTag(parser);
2538            }
2539        }
2540
2541        mDisabledSysPackages.put(name, ps);
2542    }
2543
2544    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
2545        String name = null;
2546        String realName = null;
2547        String idStr = null;
2548        String sharedIdStr = null;
2549        String codePathStr = null;
2550        String resourcePathStr = null;
2551        String nativeLibraryPathStr = null;
2552        String cpuAbiString = null;
2553        String systemStr = null;
2554        String installerPackageName = null;
2555        String uidError = null;
2556        int pkgFlags = 0;
2557        long timeStamp = 0;
2558        long firstInstallTime = 0;
2559        long lastUpdateTime = 0;
2560        PackageSettingBase packageSetting = null;
2561        String version = null;
2562        int versionCode = 0;
2563        try {
2564            name = parser.getAttributeValue(null, ATTR_NAME);
2565            realName = parser.getAttributeValue(null, "realName");
2566            idStr = parser.getAttributeValue(null, "userId");
2567            uidError = parser.getAttributeValue(null, "uidError");
2568            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2569            codePathStr = parser.getAttributeValue(null, "codePath");
2570            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2571            nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2572            cpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2573
2574            version = parser.getAttributeValue(null, "version");
2575            if (version != null) {
2576                try {
2577                    versionCode = Integer.parseInt(version);
2578                } catch (NumberFormatException e) {
2579                }
2580            }
2581            installerPackageName = parser.getAttributeValue(null, "installer");
2582
2583            systemStr = parser.getAttributeValue(null, "flags");
2584            if (systemStr != null) {
2585                try {
2586                    pkgFlags = Integer.parseInt(systemStr);
2587                } catch (NumberFormatException e) {
2588                }
2589            } else {
2590                // For backward compatibility
2591                systemStr = parser.getAttributeValue(null, "system");
2592                if (systemStr != null) {
2593                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
2594                            : 0;
2595                } else {
2596                    // Old settings that don't specify system... just treat
2597                    // them as system, good enough.
2598                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2599                }
2600            }
2601            String timeStampStr = parser.getAttributeValue(null, "ft");
2602            if (timeStampStr != null) {
2603                try {
2604                    timeStamp = Long.parseLong(timeStampStr, 16);
2605                } catch (NumberFormatException e) {
2606                }
2607            } else {
2608                timeStampStr = parser.getAttributeValue(null, "ts");
2609                if (timeStampStr != null) {
2610                    try {
2611                        timeStamp = Long.parseLong(timeStampStr);
2612                    } catch (NumberFormatException e) {
2613                    }
2614                }
2615            }
2616            timeStampStr = parser.getAttributeValue(null, "it");
2617            if (timeStampStr != null) {
2618                try {
2619                    firstInstallTime = Long.parseLong(timeStampStr, 16);
2620                } catch (NumberFormatException e) {
2621                }
2622            }
2623            timeStampStr = parser.getAttributeValue(null, "ut");
2624            if (timeStampStr != null) {
2625                try {
2626                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
2627                } catch (NumberFormatException e) {
2628                }
2629            }
2630            if (PackageManagerService.DEBUG_SETTINGS)
2631                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
2632                        + " sharedUserId=" + sharedIdStr);
2633            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2634            if (resourcePathStr == null) {
2635                resourcePathStr = codePathStr;
2636            }
2637            if (realName != null) {
2638                realName = realName.intern();
2639            }
2640            if (name == null) {
2641                PackageManagerService.reportSettingsProblem(Log.WARN,
2642                        "Error in package manager settings: <package> has no name at "
2643                                + parser.getPositionDescription());
2644            } else if (codePathStr == null) {
2645                PackageManagerService.reportSettingsProblem(Log.WARN,
2646                        "Error in package manager settings: <package> has no codePath at "
2647                                + parser.getPositionDescription());
2648            } else if (userId > 0) {
2649                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
2650                        new File(resourcePathStr), nativeLibraryPathStr, cpuAbiString, userId, versionCode,
2651                        pkgFlags);
2652                if (PackageManagerService.DEBUG_SETTINGS)
2653                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
2654                            + userId + " pkg=" + packageSetting);
2655                if (packageSetting == null) {
2656                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
2657                            + userId + " while parsing settings at "
2658                            + parser.getPositionDescription());
2659                } else {
2660                    packageSetting.setTimeStamp(timeStamp);
2661                    packageSetting.firstInstallTime = firstInstallTime;
2662                    packageSetting.lastUpdateTime = lastUpdateTime;
2663                }
2664            } else if (sharedIdStr != null) {
2665                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2666                if (userId > 0) {
2667                    packageSetting = new PendingPackage(name.intern(), realName, new File(
2668                            codePathStr), new File(resourcePathStr), nativeLibraryPathStr, cpuAbiString, userId,
2669                            versionCode, pkgFlags);
2670                    packageSetting.setTimeStamp(timeStamp);
2671                    packageSetting.firstInstallTime = firstInstallTime;
2672                    packageSetting.lastUpdateTime = lastUpdateTime;
2673                    mPendingPackages.add((PendingPackage) packageSetting);
2674                    if (PackageManagerService.DEBUG_SETTINGS)
2675                        Log.i(PackageManagerService.TAG, "Reading package " + name
2676                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
2677                } else {
2678                    PackageManagerService.reportSettingsProblem(Log.WARN,
2679                            "Error in package manager settings: package " + name
2680                                    + " has bad sharedId " + sharedIdStr + " at "
2681                                    + parser.getPositionDescription());
2682                }
2683            } else {
2684                PackageManagerService.reportSettingsProblem(Log.WARN,
2685                        "Error in package manager settings: package " + name + " has bad userId "
2686                                + idStr + " at " + parser.getPositionDescription());
2687            }
2688        } catch (NumberFormatException e) {
2689            PackageManagerService.reportSettingsProblem(Log.WARN,
2690                    "Error in package manager settings: package " + name + " has bad userId "
2691                            + idStr + " at " + parser.getPositionDescription());
2692        }
2693        if (packageSetting != null) {
2694            packageSetting.uidError = "true".equals(uidError);
2695            packageSetting.installerPackageName = installerPackageName;
2696            packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
2697            packageSetting.cpuAbiString = cpuAbiString;
2698            // Handle legacy string here for single-user mode
2699            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
2700            if (enabledStr != null) {
2701                try {
2702                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
2703                } catch (NumberFormatException e) {
2704                    if (enabledStr.equalsIgnoreCase("true")) {
2705                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
2706                    } else if (enabledStr.equalsIgnoreCase("false")) {
2707                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
2708                    } else if (enabledStr.equalsIgnoreCase("default")) {
2709                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2710                    } else {
2711                        PackageManagerService.reportSettingsProblem(Log.WARN,
2712                                "Error in package manager settings: package " + name
2713                                        + " has bad enabled value: " + idStr + " at "
2714                                        + parser.getPositionDescription());
2715                    }
2716                }
2717            } else {
2718                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2719            }
2720
2721            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
2722            if (installStatusStr != null) {
2723                if (installStatusStr.equalsIgnoreCase("false")) {
2724                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
2725                } else {
2726                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
2727                }
2728            }
2729
2730            int outerDepth = parser.getDepth();
2731            int type;
2732            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2733                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2734                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2735                    continue;
2736                }
2737
2738                String tagName = parser.getName();
2739                // Legacy
2740                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
2741                    readDisabledComponentsLPw(packageSetting, parser, 0);
2742                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
2743                    readEnabledComponentsLPw(packageSetting, parser, 0);
2744                } else if (tagName.equals("sigs")) {
2745                    packageSetting.signatures.readXml(parser, mPastSignatures);
2746                } else if (tagName.equals("perms")) {
2747                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
2748                    packageSetting.permissionsFixed = true;
2749                } else if (tagName.equals("signing-keyset")) {
2750                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2751                    packageSetting.keySetData.addSigningKeySet(id);
2752                    if (false) Slog.d(TAG, "Adding signing keyset " + Long.toString(id)
2753                            + " to " + name);
2754                } else if (tagName.equals("defined-keyset")) {
2755                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2756                    String alias = parser.getAttributeValue(null, "alias");
2757                    packageSetting.keySetData.addDefinedKeySet(id, alias);
2758                } else {
2759                    PackageManagerService.reportSettingsProblem(Log.WARN,
2760                            "Unknown element under <package>: " + parser.getName());
2761                    XmlUtils.skipCurrentTag(parser);
2762                }
2763            }
2764
2765
2766        } else {
2767            XmlUtils.skipCurrentTag(parser);
2768        }
2769    }
2770
2771    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2772            int userId) throws IOException, XmlPullParserException {
2773        int outerDepth = parser.getDepth();
2774        int type;
2775        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2776                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2777            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2778                continue;
2779            }
2780
2781            String tagName = parser.getName();
2782            if (tagName.equals(TAG_ITEM)) {
2783                String name = parser.getAttributeValue(null, ATTR_NAME);
2784                if (name != null) {
2785                    packageSetting.addDisabledComponent(name.intern(), userId);
2786                } else {
2787                    PackageManagerService.reportSettingsProblem(Log.WARN,
2788                            "Error in package manager settings: <disabled-components> has"
2789                                    + " no name at " + parser.getPositionDescription());
2790                }
2791            } else {
2792                PackageManagerService.reportSettingsProblem(Log.WARN,
2793                        "Unknown element under <disabled-components>: " + parser.getName());
2794            }
2795            XmlUtils.skipCurrentTag(parser);
2796        }
2797    }
2798
2799    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2800            int userId) throws IOException, XmlPullParserException {
2801        int outerDepth = parser.getDepth();
2802        int type;
2803        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2804                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2805            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2806                continue;
2807            }
2808
2809            String tagName = parser.getName();
2810            if (tagName.equals(TAG_ITEM)) {
2811                String name = parser.getAttributeValue(null, ATTR_NAME);
2812                if (name != null) {
2813                    packageSetting.addEnabledComponent(name.intern(), userId);
2814                } else {
2815                    PackageManagerService.reportSettingsProblem(Log.WARN,
2816                            "Error in package manager settings: <enabled-components> has"
2817                                    + " no name at " + parser.getPositionDescription());
2818                }
2819            } else {
2820                PackageManagerService.reportSettingsProblem(Log.WARN,
2821                        "Unknown element under <enabled-components>: " + parser.getName());
2822            }
2823            XmlUtils.skipCurrentTag(parser);
2824        }
2825    }
2826
2827    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
2828        String name = null;
2829        String idStr = null;
2830        int pkgFlags = 0;
2831        SharedUserSetting su = null;
2832        try {
2833            name = parser.getAttributeValue(null, ATTR_NAME);
2834            idStr = parser.getAttributeValue(null, "userId");
2835            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2836            if ("true".equals(parser.getAttributeValue(null, "system"))) {
2837                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2838            }
2839            if (name == null) {
2840                PackageManagerService.reportSettingsProblem(Log.WARN,
2841                        "Error in package manager settings: <shared-user> has no name at "
2842                                + parser.getPositionDescription());
2843            } else if (userId == 0) {
2844                PackageManagerService.reportSettingsProblem(Log.WARN,
2845                        "Error in package manager settings: shared-user " + name
2846                                + " has bad userId " + idStr + " at "
2847                                + parser.getPositionDescription());
2848            } else {
2849                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
2850                    PackageManagerService
2851                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
2852                                    + parser.getPositionDescription());
2853                }
2854            }
2855        } catch (NumberFormatException e) {
2856            PackageManagerService.reportSettingsProblem(Log.WARN,
2857                    "Error in package manager settings: package " + name + " has bad userId "
2858                            + idStr + " at " + parser.getPositionDescription());
2859        }
2860        ;
2861
2862        if (su != null) {
2863            int outerDepth = parser.getDepth();
2864            int type;
2865            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2866                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2867                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2868                    continue;
2869                }
2870
2871                String tagName = parser.getName();
2872                if (tagName.equals("sigs")) {
2873                    su.signatures.readXml(parser, mPastSignatures);
2874                } else if (tagName.equals("perms")) {
2875                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
2876                } else {
2877                    PackageManagerService.reportSettingsProblem(Log.WARN,
2878                            "Unknown element under <shared-user>: " + parser.getName());
2879                    XmlUtils.skipCurrentTag(parser);
2880                }
2881            }
2882
2883        } else {
2884            XmlUtils.skipCurrentTag(parser);
2885        }
2886    }
2887
2888    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
2889            throws IOException, XmlPullParserException {
2890        int outerDepth = parser.getDepth();
2891        int type;
2892        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2893                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2894            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2895                continue;
2896            }
2897
2898            String tagName = parser.getName();
2899            if (tagName.equals(TAG_ITEM)) {
2900                String name = parser.getAttributeValue(null, ATTR_NAME);
2901                if (name != null) {
2902                    outPerms.add(name.intern());
2903                } else {
2904                    PackageManagerService.reportSettingsProblem(Log.WARN,
2905                            "Error in package manager settings: <perms> has" + " no name at "
2906                                    + parser.getPositionDescription());
2907                }
2908            } else {
2909                PackageManagerService.reportSettingsProblem(Log.WARN,
2910                        "Unknown element under <perms>: " + parser.getName());
2911            }
2912            XmlUtils.skipCurrentTag(parser);
2913        }
2914    }
2915
2916    void createNewUserLILPw(PackageManagerService service, Installer installer,
2917            int userHandle, File path) {
2918        path.mkdir();
2919        FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
2920                | FileUtils.S_IXOTH, -1, -1);
2921        for (PackageSetting ps : mPackages.values()) {
2922            // Only system apps are initially installed.
2923            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
2924            // Need to create a data directory for all apps under this user.
2925            installer.createUserData(ps.name,
2926                    UserHandle.getUid(userHandle, ps.appId), userHandle,
2927                    ps.pkg.applicationInfo.seinfo);
2928        }
2929        readDefaultPreferredAppsLPw(service, userHandle);
2930        writePackageRestrictionsLPr(userHandle);
2931    }
2932
2933    void removeUserLPr(int userId) {
2934        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
2935        for (Entry<String, PackageSetting> entry : entries) {
2936            entry.getValue().removeUser(userId);
2937        }
2938        mPreferredActivities.remove(userId);
2939        File file = getUserPackagesStateFile(userId);
2940        file.delete();
2941        file = getUserPackagesStateBackupFile(userId);
2942        file.delete();
2943    }
2944
2945    // This should be called (at least) whenever an application is removed
2946    private void setFirstAvailableUid(int uid) {
2947        if (uid > mFirstAvailableUid) {
2948            mFirstAvailableUid = uid;
2949        }
2950    }
2951
2952    // Returns -1 if we could not find an available UserId to assign
2953    private int newUserIdLPw(Object obj) {
2954        // Let's be stupidly inefficient for now...
2955        final int N = mUserIds.size();
2956        for (int i = mFirstAvailableUid; i < N; i++) {
2957            if (mUserIds.get(i) == null) {
2958                mUserIds.set(i, obj);
2959                return Process.FIRST_APPLICATION_UID + i;
2960            }
2961        }
2962
2963        // None left?
2964        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
2965            return -1;
2966        }
2967
2968        mUserIds.add(obj);
2969        return Process.FIRST_APPLICATION_UID + N;
2970    }
2971
2972    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
2973        if (mVerifierDeviceIdentity == null) {
2974            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
2975
2976            writeLPr();
2977        }
2978
2979        return mVerifierDeviceIdentity;
2980    }
2981
2982    public PackageSetting getDisabledSystemPkgLPr(String name) {
2983        PackageSetting ps = mDisabledSysPackages.get(name);
2984        return ps;
2985    }
2986
2987    private String compToString(HashSet<String> cmp) {
2988        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
2989    }
2990
2991    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
2992        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
2993            return true;
2994        }
2995        final String pkgName = componentInfo.packageName;
2996        final PackageSetting packageSettings = mPackages.get(pkgName);
2997        if (PackageManagerService.DEBUG_SETTINGS) {
2998            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
2999                    + componentInfo.packageName + " componentName = " + componentInfo.name);
3000            Log.v(PackageManagerService.TAG, "enabledComponents: "
3001                    + compToString(packageSettings.getEnabledComponents(userId)));
3002            Log.v(PackageManagerService.TAG, "disabledComponents: "
3003                    + compToString(packageSettings.getDisabledComponents(userId)));
3004        }
3005        if (packageSettings == null) {
3006            return false;
3007        }
3008        PackageUserState ustate = packageSettings.readUserState(userId);
3009        if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
3010            if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
3011                return true;
3012            }
3013        }
3014        if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
3015                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
3016                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
3017                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
3018                    && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
3019            return false;
3020        }
3021        if (ustate.enabledComponents != null
3022                && ustate.enabledComponents.contains(componentInfo.name)) {
3023            return true;
3024        }
3025        if (ustate.disabledComponents != null
3026                && ustate.disabledComponents.contains(componentInfo.name)) {
3027            return false;
3028        }
3029        return componentInfo.enabled;
3030    }
3031
3032    String getInstallerPackageNameLPr(String packageName) {
3033        final PackageSetting pkg = mPackages.get(packageName);
3034        if (pkg == null) {
3035            throw new IllegalArgumentException("Unknown package: " + packageName);
3036        }
3037        return pkg.installerPackageName;
3038    }
3039
3040    int getApplicationEnabledSettingLPr(String packageName, int userId) {
3041        final PackageSetting pkg = mPackages.get(packageName);
3042        if (pkg == null) {
3043            throw new IllegalArgumentException("Unknown package: " + packageName);
3044        }
3045        return pkg.getEnabled(userId);
3046    }
3047
3048    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
3049        final String packageName = componentName.getPackageName();
3050        final PackageSetting pkg = mPackages.get(packageName);
3051        if (pkg == null) {
3052            throw new IllegalArgumentException("Unknown component: " + componentName);
3053        }
3054        final String classNameStr = componentName.getClassName();
3055        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
3056    }
3057
3058    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
3059            boolean allowedByPermission, int uid, int userId) {
3060        int appId = UserHandle.getAppId(uid);
3061        final PackageSetting pkgSetting = mPackages.get(packageName);
3062        if (pkgSetting == null) {
3063            throw new IllegalArgumentException("Unknown package: " + packageName);
3064        }
3065        if (!allowedByPermission && (appId != pkgSetting.appId)) {
3066            throw new SecurityException(
3067                    "Permission Denial: attempt to change stopped state from pid="
3068                    + Binder.getCallingPid()
3069                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
3070        }
3071        if (DEBUG_STOPPED) {
3072            if (stopped) {
3073                RuntimeException e = new RuntimeException("here");
3074                e.fillInStackTrace();
3075                Slog.i(TAG, "Stopping package " + packageName, e);
3076            }
3077        }
3078        if (pkgSetting.getStopped(userId) != stopped) {
3079            pkgSetting.setStopped(stopped, userId);
3080            // pkgSetting.pkg.mSetStopped = stopped;
3081            if (pkgSetting.getNotLaunched(userId)) {
3082                if (pkgSetting.installerPackageName != null) {
3083                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
3084                            pkgSetting.name, null,
3085                            pkgSetting.installerPackageName, null, new int[] {userId});
3086                }
3087                pkgSetting.setNotLaunched(false, userId);
3088            }
3089            return true;
3090        }
3091        return false;
3092    }
3093
3094    private List<UserInfo> getAllUsers() {
3095        long id = Binder.clearCallingIdentity();
3096        try {
3097            return UserManagerService.getInstance().getUsers(false);
3098        } catch (NullPointerException npe) {
3099            // packagemanager not yet initialized
3100        } finally {
3101            Binder.restoreCallingIdentity(id);
3102        }
3103        return null;
3104    }
3105
3106    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
3107        pw.print("[ ");
3108        for (int i=0; i<spec.length; i+=2) {
3109            int mask = (Integer)spec[i];
3110            if ((val & mask) != 0) {
3111                pw.print(spec[i+1]);
3112                pw.print(" ");
3113            }
3114        }
3115        pw.print("]");
3116    }
3117
3118    static final Object[] FLAG_DUMP_SPEC = new Object[] {
3119        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
3120        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
3121        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
3122        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
3123        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
3124        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
3125        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
3126        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
3127        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
3128        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
3129        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
3130        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
3131        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
3132        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
3133        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
3134        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
3135        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
3136        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
3137    };
3138
3139    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
3140            SimpleDateFormat sdf, Date date, List<UserInfo> users) {
3141        if (checkinTag != null) {
3142            pw.print(checkinTag);
3143            pw.print(",");
3144            pw.print(ps.realName != null ? ps.realName : ps.name);
3145            pw.print(",");
3146            pw.print(ps.appId);
3147            pw.print(",");
3148            pw.print(ps.versionCode);
3149            pw.print(",");
3150            pw.print(ps.firstInstallTime);
3151            pw.print(",");
3152            pw.print(ps.lastUpdateTime);
3153            pw.print(",");
3154            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
3155            pw.println();
3156            for (UserInfo user : users) {
3157                pw.print(checkinTag);
3158                pw.print("-");
3159                pw.print("usr");
3160                pw.print(",");
3161                pw.print(user.id);
3162                pw.print(",");
3163                pw.print(ps.getInstalled(user.id) ? "I" : "i");
3164                pw.print(ps.getBlocked(user.id) ? "B" : "b");
3165                pw.print(ps.getStopped(user.id) ? "S" : "s");
3166                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
3167                pw.print(",");
3168                pw.print(ps.getEnabled(user.id));
3169                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3170                pw.print(",");
3171                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
3172                pw.println();
3173            }
3174            return;
3175        }
3176
3177        pw.print(prefix); pw.print("Package [");
3178            pw.print(ps.realName != null ? ps.realName : ps.name);
3179            pw.print("] (");
3180            pw.print(Integer.toHexString(System.identityHashCode(ps)));
3181            pw.println("):");
3182
3183        if (ps.realName != null) {
3184            pw.print(prefix); pw.print("  compat name=");
3185            pw.println(ps.name);
3186        }
3187
3188        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
3189                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
3190        if (ps.sharedUser != null) {
3191            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
3192        }
3193        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
3194        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
3195        pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
3196        pw.print(prefix); pw.print("  nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
3197        pw.print(prefix); pw.print("  requiredCpuAbi="); pw.println(ps.cpuAbiString);
3198        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
3199        if (ps.pkg != null) {
3200            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
3201        }
3202        pw.println();
3203        if (ps.pkg != null) {
3204            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
3205            pw.print(prefix); pw.print("  applicationInfo=");
3206                pw.println(ps.pkg.applicationInfo.toString());
3207            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
3208                    FLAG_DUMP_SPEC); pw.println();
3209            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
3210            if (ps.pkg.mOperationPending) {
3211                pw.print(prefix); pw.println("  mOperationPending=true");
3212            }
3213            pw.print(prefix); pw.print("  supportsScreens=[");
3214            boolean first = true;
3215            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
3216                if (!first)
3217                    pw.print(", ");
3218                first = false;
3219                pw.print("small");
3220            }
3221            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
3222                if (!first)
3223                    pw.print(", ");
3224                first = false;
3225                pw.print("medium");
3226            }
3227            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
3228                if (!first)
3229                    pw.print(", ");
3230                first = false;
3231                pw.print("large");
3232            }
3233            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
3234                if (!first)
3235                    pw.print(", ");
3236                first = false;
3237                pw.print("xlarge");
3238            }
3239            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
3240                if (!first)
3241                    pw.print(", ");
3242                first = false;
3243                pw.print("resizeable");
3244            }
3245            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
3246                if (!first)
3247                    pw.print(", ");
3248                first = false;
3249                pw.print("anyDensity");
3250            }
3251            pw.println("]");
3252            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
3253                pw.print(prefix); pw.println("  libraries:");
3254                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
3255                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
3256                }
3257            }
3258            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
3259                pw.print(prefix); pw.println("  usesLibraries:");
3260                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
3261                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
3262                }
3263            }
3264            if (ps.pkg.usesOptionalLibraries != null
3265                    && ps.pkg.usesOptionalLibraries.size() > 0) {
3266                pw.print(prefix); pw.println("  usesOptionalLibraries:");
3267                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
3268                    pw.print(prefix); pw.print("    ");
3269                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
3270                }
3271            }
3272            if (ps.pkg.usesLibraryFiles != null
3273                    && ps.pkg.usesLibraryFiles.length > 0) {
3274                pw.print(prefix); pw.println("  usesLibraryFiles:");
3275                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
3276                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
3277                }
3278            }
3279        }
3280        pw.print(prefix); pw.print("  timeStamp=");
3281            date.setTime(ps.timeStamp);
3282            pw.println(sdf.format(date));
3283        pw.print(prefix); pw.print("  firstInstallTime=");
3284            date.setTime(ps.firstInstallTime);
3285            pw.println(sdf.format(date));
3286        pw.print(prefix); pw.print("  lastUpdateTime=");
3287            date.setTime(ps.lastUpdateTime);
3288            pw.println(sdf.format(date));
3289        if (ps.installerPackageName != null) {
3290            pw.print(prefix); pw.print("  installerPackageName=");
3291                    pw.println(ps.installerPackageName);
3292        }
3293        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
3294        pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
3295                pw.print(" haveGids="); pw.print(ps.haveGids);
3296                pw.print(" installStatus="); pw.println(ps.installStatus);
3297        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
3298                pw.println();
3299        for (UserInfo user : users) {
3300            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
3301            pw.print(" installed=");
3302            pw.print(ps.getInstalled(user.id));
3303            pw.print(" blocked=");
3304            pw.print(ps.getBlocked(user.id));
3305            pw.print(" stopped=");
3306            pw.print(ps.getStopped(user.id));
3307            pw.print(" notLaunched=");
3308            pw.print(ps.getNotLaunched(user.id));
3309            pw.print(" enabled=");
3310            pw.println(ps.getEnabled(user.id));
3311            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3312            if (lastDisabledAppCaller != null) {
3313                pw.print(prefix); pw.print("    lastDisabledCaller: ");
3314                        pw.println(lastDisabledAppCaller);
3315            }
3316            HashSet<String> cmp = ps.getDisabledComponents(user.id);
3317            if (cmp != null && cmp.size() > 0) {
3318                pw.print(prefix); pw.println("    disabledComponents:");
3319                for (String s : cmp) {
3320                    pw.print(prefix); pw.print("    "); pw.println(s);
3321                }
3322            }
3323            cmp = ps.getEnabledComponents(user.id);
3324            if (cmp != null && cmp.size() > 0) {
3325                pw.print(prefix); pw.println("    enabledComponents:");
3326                for (String s : cmp) {
3327                    pw.print(prefix); pw.print("    "); pw.println(s);
3328                }
3329            }
3330        }
3331        if (ps.grantedPermissions.size() > 0) {
3332            pw.print(prefix); pw.println("  grantedPermissions:");
3333            for (String s : ps.grantedPermissions) {
3334                pw.print(prefix); pw.print("    "); pw.println(s);
3335            }
3336        }
3337    }
3338
3339    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
3340        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3341        final Date date = new Date();
3342        boolean printedSomething = false;
3343        List<UserInfo> users = getAllUsers();
3344        for (final PackageSetting ps : mPackages.values()) {
3345            if (packageName != null && !packageName.equals(ps.realName)
3346                    && !packageName.equals(ps.name)) {
3347                continue;
3348            }
3349
3350            if (!checkin && packageName != null) {
3351                dumpState.setSharedUser(ps.sharedUser);
3352            }
3353
3354            if (!checkin && !printedSomething) {
3355                if (dumpState.onTitlePrinted())
3356                    pw.println();
3357                pw.println("Packages:");
3358                printedSomething = true;
3359            }
3360            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, ps, sdf, date, users);
3361        }
3362
3363        printedSomething = false;
3364        if (!checkin && mRenamedPackages.size() > 0) {
3365            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
3366                if (packageName != null && !packageName.equals(e.getKey())
3367                        && !packageName.equals(e.getValue())) {
3368                    continue;
3369                }
3370                if (!checkin) {
3371                    if (!printedSomething) {
3372                        if (dumpState.onTitlePrinted())
3373                            pw.println();
3374                        pw.println("Renamed packages:");
3375                        printedSomething = true;
3376                    }
3377                    pw.print("  ");
3378                } else {
3379                    pw.print("ren,");
3380                }
3381                pw.print(e.getKey());
3382                pw.print(checkin ? " -> " : ",");
3383                pw.println(e.getValue());
3384            }
3385        }
3386
3387        printedSomething = false;
3388        if (mDisabledSysPackages.size() > 0) {
3389            for (final PackageSetting ps : mDisabledSysPackages.values()) {
3390                if (packageName != null && !packageName.equals(ps.realName)
3391                        && !packageName.equals(ps.name)) {
3392                    continue;
3393                }
3394                if (!checkin && !printedSomething) {
3395                    if (dumpState.onTitlePrinted())
3396                        pw.println();
3397                    pw.println("Hidden system packages:");
3398                    printedSomething = true;
3399                }
3400                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, ps, sdf, date, users);
3401            }
3402        }
3403    }
3404
3405    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3406        boolean printedSomething = false;
3407        for (BasePermission p : mPermissions.values()) {
3408            if (packageName != null && !packageName.equals(p.sourcePackage)) {
3409                continue;
3410            }
3411            if (!printedSomething) {
3412                if (dumpState.onTitlePrinted())
3413                    pw.println();
3414                pw.println("Permissions:");
3415                printedSomething = true;
3416            }
3417            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
3418                    pw.print(Integer.toHexString(System.identityHashCode(p)));
3419                    pw.println("):");
3420            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
3421            pw.print("    uid="); pw.print(p.uid);
3422                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
3423                    pw.print(" type="); pw.print(p.type);
3424                    pw.print(" prot=");
3425                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
3426            if (p.packageSetting != null) {
3427                pw.print("    packageSetting="); pw.println(p.packageSetting);
3428            }
3429            if (p.perm != null) {
3430                pw.print("    perm="); pw.println(p.perm);
3431            }
3432            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
3433                pw.print("    enforced=");
3434                pw.println(mReadExternalStorageEnforced);
3435            }
3436        }
3437    }
3438
3439    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3440        boolean printedSomething = false;
3441        for (SharedUserSetting su : mSharedUsers.values()) {
3442            if (packageName != null && su != dumpState.getSharedUser()) {
3443                continue;
3444            }
3445            if (!printedSomething) {
3446                if (dumpState.onTitlePrinted())
3447                    pw.println();
3448                pw.println("Shared users:");
3449                printedSomething = true;
3450            }
3451            pw.print("  SharedUser [");
3452            pw.print(su.name);
3453            pw.print("] (");
3454            pw.print(Integer.toHexString(System.identityHashCode(su)));
3455                    pw.println("):");
3456            pw.print("    userId=");
3457            pw.print(su.userId);
3458            pw.print(" gids=");
3459            pw.println(PackageManagerService.arrayToString(su.gids));
3460            pw.println("    grantedPermissions:");
3461            for (String s : su.grantedPermissions) {
3462                pw.print("      ");
3463                pw.println(s);
3464            }
3465        }
3466    }
3467
3468    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
3469        pw.println("Settings parse messages:");
3470        pw.print(mReadMessages.toString());
3471    }
3472}
3473