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