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