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