Settings.java revision 55b1078e2a1b56daa85edfd5000a5844d3c7914b
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 KeySetManagerService mKeySetManagerService = new KeySetManagerService(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            mKeySetManagerService.writeKeySetManagerServiceLPr(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        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
1940        writeKeySetAliasesLPr(serializer, pkg.keySetData);
1941
1942        serializer.endTag(null, "package");
1943    }
1944
1945    void writeSigningKeySetsLPr(XmlSerializer serializer,
1946            PackageKeySetData data) throws IOException {
1947        if (data.getSigningKeySets() != null) {
1948            for (long id : data.getSigningKeySets()) {
1949                serializer.startTag(null, "signing-keyset");
1950                serializer.attribute(null, "identifier", Long.toString(id));
1951                serializer.endTag(null, "signing-keyset");
1952            }
1953        }
1954    }
1955
1956    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
1957            PackageKeySetData data) throws IOException {
1958        if (data.isUsingUpgradeKeySets()) {
1959            for (long id : data.getUpgradeKeySets()) {
1960                serializer.startTag(null, "upgrade-keyset");
1961                serializer.attribute(null, "identifier", Long.toString(id));
1962                serializer.endTag(null, "upgrade-keyset");
1963            }
1964        }
1965    }
1966
1967    void writeKeySetAliasesLPr(XmlSerializer serializer,
1968            PackageKeySetData data) throws IOException {
1969        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
1970            serializer.startTag(null, "defined-keyset");
1971            serializer.attribute(null, "alias", e.getKey());
1972            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
1973            serializer.endTag(null, "defined-keyset");
1974        }
1975    }
1976
1977    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1978            throws XmlPullParserException, java.io.IOException {
1979        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1980            serializer.startTag(null, TAG_ITEM);
1981            serializer.attribute(null, ATTR_NAME, bp.name);
1982            serializer.attribute(null, "package", bp.sourcePackage);
1983            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1984                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1985            }
1986            if (PackageManagerService.DEBUG_SETTINGS)
1987                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1988                        + bp.type);
1989            if (bp.type == BasePermission.TYPE_DYNAMIC) {
1990                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1991                if (pi != null) {
1992                    serializer.attribute(null, "type", "dynamic");
1993                    if (pi.icon != 0) {
1994                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
1995                    }
1996                    if (pi.nonLocalizedLabel != null) {
1997                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1998                    }
1999                }
2000            }
2001            serializer.endTag(null, TAG_ITEM);
2002        }
2003    }
2004
2005    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
2006        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
2007        final Iterator<String> its = kList.iterator();
2008        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
2009        while (its.hasNext()) {
2010            final String key = its.next();
2011            final PackageSetting ps = mPackages.get(key);
2012            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
2013                ret.add(ps);
2014            }
2015        }
2016        return ret;
2017    }
2018
2019    void addPackageToCleanLPw(PackageCleanItem pkg) {
2020        if (!mPackagesToBeCleaned.contains(pkg)) {
2021            mPackagesToBeCleaned.add(pkg);
2022        }
2023    }
2024
2025    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
2026            boolean onlyCore) {
2027        FileInputStream str = null;
2028        if (mBackupSettingsFilename.exists()) {
2029            try {
2030                str = new FileInputStream(mBackupSettingsFilename);
2031                mReadMessages.append("Reading from backup settings file\n");
2032                PackageManagerService.reportSettingsProblem(Log.INFO,
2033                        "Need to read from backup settings file");
2034                if (mSettingsFilename.exists()) {
2035                    // If both the backup and settings file exist, we
2036                    // ignore the settings since it might have been
2037                    // corrupted.
2038                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
2039                            + mSettingsFilename);
2040                    mSettingsFilename.delete();
2041                }
2042            } catch (java.io.IOException e) {
2043                // We'll try for the normal settings file.
2044            }
2045        }
2046
2047        mPendingPackages.clear();
2048        mPastSignatures.clear();
2049
2050        try {
2051            if (str == null) {
2052                if (!mSettingsFilename.exists()) {
2053                    mReadMessages.append("No settings file found\n");
2054                    PackageManagerService.reportSettingsProblem(Log.INFO,
2055                            "No settings file; creating initial state");
2056                    mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion;
2057                    return false;
2058                }
2059                str = new FileInputStream(mSettingsFilename);
2060            }
2061            XmlPullParser parser = Xml.newPullParser();
2062            parser.setInput(str, null);
2063
2064            int type;
2065            while ((type = parser.next()) != XmlPullParser.START_TAG
2066                    && type != XmlPullParser.END_DOCUMENT) {
2067                ;
2068            }
2069
2070            if (type != XmlPullParser.START_TAG) {
2071                mReadMessages.append("No start tag found in settings file\n");
2072                PackageManagerService.reportSettingsProblem(Log.WARN,
2073                        "No start tag found in package manager settings");
2074                Log.wtf(PackageManagerService.TAG,
2075                        "No start tag found in package manager settings");
2076                return false;
2077            }
2078
2079            int outerDepth = parser.getDepth();
2080            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2081                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2082                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2083                    continue;
2084                }
2085
2086                String tagName = parser.getName();
2087                if (tagName.equals("package")) {
2088                    readPackageLPw(parser);
2089                } else if (tagName.equals("permissions")) {
2090                    readPermissionsLPw(mPermissions, parser);
2091                } else if (tagName.equals("permission-trees")) {
2092                    readPermissionsLPw(mPermissionTrees, parser);
2093                } else if (tagName.equals("shared-user")) {
2094                    readSharedUserLPw(parser);
2095                } else if (tagName.equals("preferred-packages")) {
2096                    // no longer used.
2097                } else if (tagName.equals("preferred-activities")) {
2098                    // Upgrading from old single-user implementation;
2099                    // these are the preferred activities for user 0.
2100                    readPreferredActivitiesLPw(parser, 0);
2101                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2102                    // TODO: check whether this is okay! as it is very
2103                    // similar to how preferred-activities are treated
2104                    readPersistentPreferredActivitiesLPw(parser, 0);
2105                } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS)
2106                        || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2107                    // TODO: check whether this is okay! as it is very
2108                    // similar to how preferred-activities are treated
2109                    readCrossProfileIntentFiltersLPw(parser, 0);
2110                } else if (tagName.equals("updated-package")) {
2111                    readDisabledSysPackageLPw(parser);
2112                } else if (tagName.equals("cleaning-package")) {
2113                    String name = parser.getAttributeValue(null, ATTR_NAME);
2114                    String userStr = parser.getAttributeValue(null, ATTR_USER);
2115                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
2116                    if (name != null) {
2117                        int userId = 0;
2118                        boolean andCode = true;
2119                        try {
2120                            if (userStr != null) {
2121                                userId = Integer.parseInt(userStr);
2122                            }
2123                        } catch (NumberFormatException e) {
2124                        }
2125                        if (codeStr != null) {
2126                            andCode = Boolean.parseBoolean(codeStr);
2127                        }
2128                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
2129                    }
2130                } else if (tagName.equals("renamed-package")) {
2131                    String nname = parser.getAttributeValue(null, "new");
2132                    String oname = parser.getAttributeValue(null, "old");
2133                    if (nname != null && oname != null) {
2134                        mRenamedPackages.put(nname, oname);
2135                    }
2136                } else if (tagName.equals("last-platform-version")) {
2137                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
2138                    try {
2139                        String internal = parser.getAttributeValue(null, "internal");
2140                        if (internal != null) {
2141                            mInternalSdkPlatform = Integer.parseInt(internal);
2142                        }
2143                        String external = parser.getAttributeValue(null, "external");
2144                        if (external != null) {
2145                            mExternalSdkPlatform = Integer.parseInt(external);
2146                        }
2147                    } catch (NumberFormatException e) {
2148                    }
2149                } else if (tagName.equals("database-version")) {
2150                    mInternalDatabaseVersion = mExternalDatabaseVersion = 0;
2151                    try {
2152                        String internalDbVersionString = parser.getAttributeValue(null, "internal");
2153                        if (internalDbVersionString != null) {
2154                            mInternalDatabaseVersion = Integer.parseInt(internalDbVersionString);
2155                        }
2156                        String externalDbVersionString = parser.getAttributeValue(null, "external");
2157                        if (externalDbVersionString != null) {
2158                            mExternalDatabaseVersion = Integer.parseInt(externalDbVersionString);
2159                        }
2160                    } catch (NumberFormatException ignored) {
2161                    }
2162                } else if (tagName.equals("verifier")) {
2163                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2164                    try {
2165                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2166                    } catch (IllegalArgumentException e) {
2167                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2168                                + e.getMessage());
2169                    }
2170                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2171                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2172                    mReadExternalStorageEnforced = "1".equals(enforcement);
2173                } else if (tagName.equals("keyset-settings")) {
2174                    mKeySetManagerService.readKeySetsLPw(parser);
2175                } else {
2176                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2177                            + parser.getName());
2178                    XmlUtils.skipCurrentTag(parser);
2179                }
2180            }
2181
2182            str.close();
2183
2184        } catch (XmlPullParserException e) {
2185            mReadMessages.append("Error reading: " + e.toString());
2186            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2187            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2188
2189        } catch (java.io.IOException e) {
2190            mReadMessages.append("Error reading: " + e.toString());
2191            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2192            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2193        }
2194
2195        final int N = mPendingPackages.size();
2196        for (int i = 0; i < N; i++) {
2197            final PendingPackage pp = mPendingPackages.get(i);
2198            Object idObj = getUserIdLPr(pp.sharedId);
2199            if (idObj != null && idObj instanceof SharedUserSetting) {
2200                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
2201                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
2202                        pp.nativeLibraryPathString, pp.cpuAbiString, pp.versionCode, pp.pkgFlags,
2203                        null, true /* add */, false /* allowInstall */);
2204                if (p == null) {
2205                    PackageManagerService.reportSettingsProblem(Log.WARN,
2206                            "Unable to create application package for " + pp.name);
2207                    continue;
2208                }
2209                p.copyFrom(pp);
2210            } else if (idObj != null) {
2211                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2212                        + pp.sharedId + " that is not a shared uid\n";
2213                mReadMessages.append(msg);
2214                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2215            } else {
2216                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2217                        + pp.sharedId + " that is not defined\n";
2218                mReadMessages.append(msg);
2219                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2220            }
2221        }
2222        mPendingPackages.clear();
2223
2224        if (mBackupStoppedPackagesFilename.exists()
2225                || mStoppedPackagesFilename.exists()) {
2226            // Read old file
2227            readStoppedLPw();
2228            mBackupStoppedPackagesFilename.delete();
2229            mStoppedPackagesFilename.delete();
2230            // Migrate to new file format
2231            writePackageRestrictionsLPr(0);
2232        } else {
2233            if (users == null) {
2234                readPackageRestrictionsLPr(0);
2235            } else {
2236                for (UserInfo user : users) {
2237                    readPackageRestrictionsLPr(user.id);
2238                }
2239            }
2240        }
2241
2242        /*
2243         * Make sure all the updated system packages have their shared users
2244         * associated with them.
2245         */
2246        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
2247        while (disabledIt.hasNext()) {
2248            final PackageSetting disabledPs = disabledIt.next();
2249            final Object id = getUserIdLPr(disabledPs.appId);
2250            if (id != null && id instanceof SharedUserSetting) {
2251                disabledPs.sharedUser = (SharedUserSetting) id;
2252            }
2253        }
2254
2255        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
2256                + mSharedUsers.size() + " shared uids\n");
2257
2258        return true;
2259    }
2260
2261    void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
2262        // First pull data from any pre-installed apps.
2263        for (PackageSetting ps : mPackages.values()) {
2264            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
2265                    && ps.pkg.preferredActivityFilters != null) {
2266                ArrayList<PackageParser.ActivityIntentInfo> intents
2267                        = ps.pkg.preferredActivityFilters;
2268                for (int i=0; i<intents.size(); i++) {
2269                    PackageParser.ActivityIntentInfo aii = intents.get(i);
2270                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
2271                            ps.name, aii.activity.className), userId);
2272                }
2273            }
2274        }
2275
2276        // Read preferred apps from .../etc/preferred-apps directory.
2277        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
2278        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
2279            return;
2280        }
2281        if (!preferredDir.canRead()) {
2282            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
2283            return;
2284        }
2285
2286        // Iterate over the files in the directory and scan .xml files
2287        for (File f : preferredDir.listFiles()) {
2288            if (!f.getPath().endsWith(".xml")) {
2289                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
2290                continue;
2291            }
2292            if (!f.canRead()) {
2293                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
2294                continue;
2295            }
2296
2297            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
2298            FileInputStream str = null;
2299            try {
2300                str = new FileInputStream(f);
2301                XmlPullParser parser = Xml.newPullParser();
2302                parser.setInput(str, null);
2303
2304                int type;
2305                while ((type = parser.next()) != XmlPullParser.START_TAG
2306                        && type != XmlPullParser.END_DOCUMENT) {
2307                    ;
2308                }
2309
2310                if (type != XmlPullParser.START_TAG) {
2311                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
2312                    continue;
2313                }
2314                if (!"preferred-activities".equals(parser.getName())) {
2315                    Slog.w(TAG, "Preferred apps file " + f
2316                            + " does not start with 'preferred-activities'");
2317                    continue;
2318                }
2319                readDefaultPreferredActivitiesLPw(service, parser, userId);
2320            } catch (XmlPullParserException e) {
2321                Slog.w(TAG, "Error reading apps file " + f, e);
2322            } catch (IOException e) {
2323                Slog.w(TAG, "Error reading apps file " + f, e);
2324            } finally {
2325                if (str != null) {
2326                    try {
2327                        str.close();
2328                    } catch (IOException e) {
2329                    }
2330                }
2331            }
2332        }
2333    }
2334
2335    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2336            IntentFilter tmpPa, ComponentName cn, int userId) {
2337        // The initial preferences only specify the target activity
2338        // component and intent-filter, not the set of matches.  So we
2339        // now need to query for the matches to build the correct
2340        // preferred activity entry.
2341        if (PackageManagerService.DEBUG_PREFERRED) {
2342            Log.d(TAG, "Processing preferred:");
2343            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
2344        }
2345        Intent intent = new Intent();
2346        int flags = 0;
2347        intent.setAction(tmpPa.getAction(0));
2348        for (int i=0; i<tmpPa.countCategories(); i++) {
2349            String cat = tmpPa.getCategory(i);
2350            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
2351                flags |= PackageManager.MATCH_DEFAULT_ONLY;
2352            } else {
2353                intent.addCategory(cat);
2354            }
2355        }
2356
2357        boolean doNonData = true;
2358        boolean hasSchemes = false;
2359
2360        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2361            boolean doScheme = true;
2362            String scheme = tmpPa.getDataScheme(ischeme);
2363            if (scheme != null && !scheme.isEmpty()) {
2364                hasSchemes = true;
2365            }
2366            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
2367                Uri.Builder builder = new Uri.Builder();
2368                builder.scheme(scheme);
2369                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
2370                builder.opaquePart(ssp.getPath());
2371                Intent finalIntent = new Intent(intent);
2372                finalIntent.setData(builder.build());
2373                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2374                        scheme, ssp, null, null, null, userId);
2375                doScheme = false;
2376            }
2377            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
2378                boolean doAuth = true;
2379                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
2380                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
2381                    Uri.Builder builder = new Uri.Builder();
2382                    builder.scheme(scheme);
2383                    if (auth.getHost() != null) {
2384                        builder.authority(auth.getHost());
2385                    }
2386                    PatternMatcher path = tmpPa.getDataPath(ipath);
2387                    builder.path(path.getPath());
2388                    Intent finalIntent = new Intent(intent);
2389                    finalIntent.setData(builder.build());
2390                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2391                            scheme, null, auth, path, null, userId);
2392                    doAuth = doScheme = false;
2393                }
2394                if (doAuth) {
2395                    Uri.Builder builder = new Uri.Builder();
2396                    builder.scheme(scheme);
2397                    if (auth.getHost() != null) {
2398                        builder.authority(auth.getHost());
2399                    }
2400                    Intent finalIntent = new Intent(intent);
2401                    finalIntent.setData(builder.build());
2402                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2403                            scheme, null, auth, null, null, userId);
2404                    doScheme = false;
2405                }
2406            }
2407            if (doScheme) {
2408                Uri.Builder builder = new Uri.Builder();
2409                builder.scheme(scheme);
2410                Intent finalIntent = new Intent(intent);
2411                finalIntent.setData(builder.build());
2412                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2413                        scheme, null, null, null, null, userId);
2414            }
2415            doNonData = false;
2416        }
2417
2418        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
2419            String mimeType = tmpPa.getDataType(idata);
2420            if (hasSchemes) {
2421                Uri.Builder builder = new Uri.Builder();
2422                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2423                    String scheme = tmpPa.getDataScheme(ischeme);
2424                    if (scheme != null && !scheme.isEmpty()) {
2425                        Intent finalIntent = new Intent(intent);
2426                        builder.scheme(scheme);
2427                        finalIntent.setDataAndType(builder.build(), mimeType);
2428                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2429                                scheme, null, null, null, mimeType, userId);
2430                    }
2431                }
2432            } else {
2433                Intent finalIntent = new Intent(intent);
2434                finalIntent.setType(mimeType);
2435                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2436                        null, null, null, null, mimeType, userId);
2437            }
2438            doNonData = false;
2439        }
2440
2441        if (doNonData) {
2442            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
2443                    null, null, null, null, null, userId);
2444        }
2445    }
2446
2447    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2448            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
2449            IntentFilter.AuthorityEntry auth, PatternMatcher path, String mimeType,
2450            int userId) {
2451        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
2452                intent.getType(), flags, 0);
2453        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
2454                + " results: " + ri);
2455        int match = 0;
2456        if (ri != null && ri.size() > 1) {
2457            boolean haveAct = false;
2458            boolean haveNonSys = false;
2459            ComponentName[] set = new ComponentName[ri.size()];
2460            for (int i=0; i<ri.size(); i++) {
2461                ActivityInfo ai = ri.get(i).activityInfo;
2462                set[i] = new ComponentName(ai.packageName, ai.name);
2463                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
2464                    // If any of the matches are not system apps, then
2465                    // there is a third party app that is now an option...
2466                    // so don't set a default since we don't want to hide it.
2467                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2468                            + ai.packageName + "/" + ai.name + ": non-system!");
2469                    haveNonSys = true;
2470                    break;
2471                } else if (cn.getPackageName().equals(ai.packageName)
2472                        && cn.getClassName().equals(ai.name)) {
2473                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2474                            + ai.packageName + "/" + ai.name + ": default!");
2475                    haveAct = true;
2476                    match = ri.get(i).match;
2477                } else {
2478                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2479                            + ai.packageName + "/" + ai.name + ": skipped");
2480                }
2481            }
2482            if (haveAct && !haveNonSys) {
2483                IntentFilter filter = new IntentFilter();
2484                if (intent.getAction() != null) {
2485                    filter.addAction(intent.getAction());
2486                }
2487                if (intent.getCategories() != null) {
2488                    for (String cat : intent.getCategories()) {
2489                        filter.addCategory(cat);
2490                    }
2491                }
2492                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
2493                    filter.addCategory(Intent.CATEGORY_DEFAULT);
2494                }
2495                if (scheme != null) {
2496                    filter.addDataScheme(scheme);
2497                }
2498                if (ssp != null) {
2499                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
2500                }
2501                if (auth != null) {
2502                    filter.addDataAuthority(auth);
2503                }
2504                if (path != null) {
2505                    filter.addDataPath(path);
2506                }
2507                if (intent.getType() != null) {
2508                    try {
2509                        filter.addDataType(intent.getType());
2510                    } catch (IntentFilter.MalformedMimeTypeException ex) {
2511                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
2512                    }
2513                }
2514                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
2515                editPreferredActivitiesLPw(userId).addFilter(pa);
2516            } else if (!haveNonSys) {
2517                Slog.w(TAG, "No component found for default preferred activity " + cn);
2518            }
2519        }
2520    }
2521
2522    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
2523            XmlPullParser parser, int userId)
2524            throws XmlPullParserException, IOException {
2525        int outerDepth = parser.getDepth();
2526        int type;
2527        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2528                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2529            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2530                continue;
2531            }
2532
2533            String tagName = parser.getName();
2534            if (tagName.equals(TAG_ITEM)) {
2535                PreferredActivity tmpPa = new PreferredActivity(parser);
2536                if (tmpPa.mPref.getParseError() == null) {
2537                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
2538                            userId);
2539                } else {
2540                    PackageManagerService.reportSettingsProblem(Log.WARN,
2541                            "Error in package manager settings: <preferred-activity> "
2542                                    + tmpPa.mPref.getParseError() + " at "
2543                                    + parser.getPositionDescription());
2544                }
2545            } else {
2546                PackageManagerService.reportSettingsProblem(Log.WARN,
2547                        "Unknown element under <preferred-activities>: " + parser.getName());
2548                XmlUtils.skipCurrentTag(parser);
2549            }
2550        }
2551    }
2552
2553    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
2554        String v = parser.getAttributeValue(ns, name);
2555        try {
2556            if (v == null) {
2557                return defValue;
2558            }
2559            return Integer.parseInt(v);
2560        } catch (NumberFormatException e) {
2561            PackageManagerService.reportSettingsProblem(Log.WARN,
2562                    "Error in package manager settings: attribute " + name
2563                            + " has bad integer value " + v + " at "
2564                            + parser.getPositionDescription());
2565        }
2566        return defValue;
2567    }
2568
2569    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
2570            throws IOException, XmlPullParserException {
2571        int outerDepth = parser.getDepth();
2572        int type;
2573        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2574                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2575            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2576                continue;
2577            }
2578
2579            final String tagName = parser.getName();
2580            if (tagName.equals(TAG_ITEM)) {
2581                final String name = parser.getAttributeValue(null, ATTR_NAME);
2582                final String sourcePackage = parser.getAttributeValue(null, "package");
2583                final String ptype = parser.getAttributeValue(null, "type");
2584                if (name != null && sourcePackage != null) {
2585                    final boolean dynamic = "dynamic".equals(ptype);
2586                    final BasePermission bp = new BasePermission(name, sourcePackage,
2587                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
2588                    bp.protectionLevel = readInt(parser, null, "protection",
2589                            PermissionInfo.PROTECTION_NORMAL);
2590                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
2591                    if (dynamic) {
2592                        PermissionInfo pi = new PermissionInfo();
2593                        pi.packageName = sourcePackage.intern();
2594                        pi.name = name.intern();
2595                        pi.icon = readInt(parser, null, "icon", 0);
2596                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
2597                        pi.protectionLevel = bp.protectionLevel;
2598                        bp.pendingInfo = pi;
2599                    }
2600                    out.put(bp.name, bp);
2601                } else {
2602                    PackageManagerService.reportSettingsProblem(Log.WARN,
2603                            "Error in package manager settings: permissions has" + " no name at "
2604                                    + parser.getPositionDescription());
2605                }
2606            } else {
2607                PackageManagerService.reportSettingsProblem(Log.WARN,
2608                        "Unknown element reading permissions: " + parser.getName() + " at "
2609                                + parser.getPositionDescription());
2610            }
2611            XmlUtils.skipCurrentTag(parser);
2612        }
2613    }
2614
2615    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
2616            IOException {
2617        String name = parser.getAttributeValue(null, ATTR_NAME);
2618        String realName = parser.getAttributeValue(null, "realName");
2619        String codePathStr = parser.getAttributeValue(null, "codePath");
2620        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2621        String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2622        String cpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2623
2624        if (resourcePathStr == null) {
2625            resourcePathStr = codePathStr;
2626        }
2627        String version = parser.getAttributeValue(null, "version");
2628        int versionCode = 0;
2629        if (version != null) {
2630            try {
2631                versionCode = Integer.parseInt(version);
2632            } catch (NumberFormatException e) {
2633            }
2634        }
2635
2636        int pkgFlags = 0;
2637        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2638        final File codePathFile = new File(codePathStr);
2639        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
2640            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
2641        }
2642        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
2643                new File(resourcePathStr), nativeLibraryPathStr, cpuAbiString, versionCode, pkgFlags);
2644        String timeStampStr = parser.getAttributeValue(null, "ft");
2645        if (timeStampStr != null) {
2646            try {
2647                long timeStamp = Long.parseLong(timeStampStr, 16);
2648                ps.setTimeStamp(timeStamp);
2649            } catch (NumberFormatException e) {
2650            }
2651        } else {
2652            timeStampStr = parser.getAttributeValue(null, "ts");
2653            if (timeStampStr != null) {
2654                try {
2655                    long timeStamp = Long.parseLong(timeStampStr);
2656                    ps.setTimeStamp(timeStamp);
2657                } catch (NumberFormatException e) {
2658                }
2659            }
2660        }
2661        timeStampStr = parser.getAttributeValue(null, "it");
2662        if (timeStampStr != null) {
2663            try {
2664                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
2665            } catch (NumberFormatException e) {
2666            }
2667        }
2668        timeStampStr = parser.getAttributeValue(null, "ut");
2669        if (timeStampStr != null) {
2670            try {
2671                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
2672            } catch (NumberFormatException e) {
2673            }
2674        }
2675        String idStr = parser.getAttributeValue(null, "userId");
2676        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
2677        if (ps.appId <= 0) {
2678            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2679            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2680        }
2681        int outerDepth = parser.getDepth();
2682        int type;
2683        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2684                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2685            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2686                continue;
2687            }
2688
2689            String tagName = parser.getName();
2690            if (tagName.equals("perms")) {
2691                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
2692            } else {
2693                PackageManagerService.reportSettingsProblem(Log.WARN,
2694                        "Unknown element under <updated-package>: " + parser.getName());
2695                XmlUtils.skipCurrentTag(parser);
2696            }
2697        }
2698
2699        mDisabledSysPackages.put(name, ps);
2700    }
2701
2702    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
2703        String name = null;
2704        String realName = null;
2705        String idStr = null;
2706        String sharedIdStr = null;
2707        String codePathStr = null;
2708        String resourcePathStr = null;
2709        String nativeLibraryPathStr = null;
2710        String cpuAbiString = null;
2711        String systemStr = null;
2712        String installerPackageName = null;
2713        String uidError = null;
2714        int pkgFlags = 0;
2715        long timeStamp = 0;
2716        long firstInstallTime = 0;
2717        long lastUpdateTime = 0;
2718        PackageSettingBase packageSetting = null;
2719        String version = null;
2720        int versionCode = 0;
2721        try {
2722            name = parser.getAttributeValue(null, ATTR_NAME);
2723            realName = parser.getAttributeValue(null, "realName");
2724            idStr = parser.getAttributeValue(null, "userId");
2725            uidError = parser.getAttributeValue(null, "uidError");
2726            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2727            codePathStr = parser.getAttributeValue(null, "codePath");
2728            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2729            nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2730            cpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2731
2732            version = parser.getAttributeValue(null, "version");
2733            if (version != null) {
2734                try {
2735                    versionCode = Integer.parseInt(version);
2736                } catch (NumberFormatException e) {
2737                }
2738            }
2739            installerPackageName = parser.getAttributeValue(null, "installer");
2740
2741            systemStr = parser.getAttributeValue(null, "flags");
2742            if (systemStr != null) {
2743                try {
2744                    pkgFlags = Integer.parseInt(systemStr);
2745                } catch (NumberFormatException e) {
2746                }
2747            } else {
2748                // For backward compatibility
2749                systemStr = parser.getAttributeValue(null, "system");
2750                if (systemStr != null) {
2751                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
2752                            : 0;
2753                } else {
2754                    // Old settings that don't specify system... just treat
2755                    // them as system, good enough.
2756                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2757                }
2758            }
2759            String timeStampStr = parser.getAttributeValue(null, "ft");
2760            if (timeStampStr != null) {
2761                try {
2762                    timeStamp = Long.parseLong(timeStampStr, 16);
2763                } catch (NumberFormatException e) {
2764                }
2765            } else {
2766                timeStampStr = parser.getAttributeValue(null, "ts");
2767                if (timeStampStr != null) {
2768                    try {
2769                        timeStamp = Long.parseLong(timeStampStr);
2770                    } catch (NumberFormatException e) {
2771                    }
2772                }
2773            }
2774            timeStampStr = parser.getAttributeValue(null, "it");
2775            if (timeStampStr != null) {
2776                try {
2777                    firstInstallTime = Long.parseLong(timeStampStr, 16);
2778                } catch (NumberFormatException e) {
2779                }
2780            }
2781            timeStampStr = parser.getAttributeValue(null, "ut");
2782            if (timeStampStr != null) {
2783                try {
2784                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
2785                } catch (NumberFormatException e) {
2786                }
2787            }
2788            if (PackageManagerService.DEBUG_SETTINGS)
2789                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
2790                        + " sharedUserId=" + sharedIdStr);
2791            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2792            if (resourcePathStr == null) {
2793                resourcePathStr = codePathStr;
2794            }
2795            if (realName != null) {
2796                realName = realName.intern();
2797            }
2798            if (name == null) {
2799                PackageManagerService.reportSettingsProblem(Log.WARN,
2800                        "Error in package manager settings: <package> has no name at "
2801                                + parser.getPositionDescription());
2802            } else if (codePathStr == null) {
2803                PackageManagerService.reportSettingsProblem(Log.WARN,
2804                        "Error in package manager settings: <package> has no codePath at "
2805                                + parser.getPositionDescription());
2806            } else if (userId > 0) {
2807                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
2808                        new File(resourcePathStr), nativeLibraryPathStr, cpuAbiString, userId, versionCode,
2809                        pkgFlags);
2810                if (PackageManagerService.DEBUG_SETTINGS)
2811                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
2812                            + userId + " pkg=" + packageSetting);
2813                if (packageSetting == null) {
2814                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
2815                            + userId + " while parsing settings at "
2816                            + parser.getPositionDescription());
2817                } else {
2818                    packageSetting.setTimeStamp(timeStamp);
2819                    packageSetting.firstInstallTime = firstInstallTime;
2820                    packageSetting.lastUpdateTime = lastUpdateTime;
2821                }
2822            } else if (sharedIdStr != null) {
2823                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2824                if (userId > 0) {
2825                    packageSetting = new PendingPackage(name.intern(), realName, new File(
2826                            codePathStr), new File(resourcePathStr), nativeLibraryPathStr, cpuAbiString, userId,
2827                            versionCode, pkgFlags);
2828                    packageSetting.setTimeStamp(timeStamp);
2829                    packageSetting.firstInstallTime = firstInstallTime;
2830                    packageSetting.lastUpdateTime = lastUpdateTime;
2831                    mPendingPackages.add((PendingPackage) packageSetting);
2832                    if (PackageManagerService.DEBUG_SETTINGS)
2833                        Log.i(PackageManagerService.TAG, "Reading package " + name
2834                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
2835                } else {
2836                    PackageManagerService.reportSettingsProblem(Log.WARN,
2837                            "Error in package manager settings: package " + name
2838                                    + " has bad sharedId " + sharedIdStr + " at "
2839                                    + parser.getPositionDescription());
2840                }
2841            } else {
2842                PackageManagerService.reportSettingsProblem(Log.WARN,
2843                        "Error in package manager settings: package " + name + " has bad userId "
2844                                + idStr + " at " + parser.getPositionDescription());
2845            }
2846        } catch (NumberFormatException e) {
2847            PackageManagerService.reportSettingsProblem(Log.WARN,
2848                    "Error in package manager settings: package " + name + " has bad userId "
2849                            + idStr + " at " + parser.getPositionDescription());
2850        }
2851        if (packageSetting != null) {
2852            packageSetting.uidError = "true".equals(uidError);
2853            packageSetting.installerPackageName = installerPackageName;
2854            packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
2855            packageSetting.cpuAbiString = cpuAbiString;
2856            // Handle legacy string here for single-user mode
2857            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
2858            if (enabledStr != null) {
2859                try {
2860                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
2861                } catch (NumberFormatException e) {
2862                    if (enabledStr.equalsIgnoreCase("true")) {
2863                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
2864                    } else if (enabledStr.equalsIgnoreCase("false")) {
2865                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
2866                    } else if (enabledStr.equalsIgnoreCase("default")) {
2867                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2868                    } else {
2869                        PackageManagerService.reportSettingsProblem(Log.WARN,
2870                                "Error in package manager settings: package " + name
2871                                        + " has bad enabled value: " + idStr + " at "
2872                                        + parser.getPositionDescription());
2873                    }
2874                }
2875            } else {
2876                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2877            }
2878
2879            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
2880            if (installStatusStr != null) {
2881                if (installStatusStr.equalsIgnoreCase("false")) {
2882                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
2883                } else {
2884                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
2885                }
2886            }
2887
2888            int outerDepth = parser.getDepth();
2889            int type;
2890            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2891                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2892                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2893                    continue;
2894                }
2895
2896                String tagName = parser.getName();
2897                // Legacy
2898                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
2899                    readDisabledComponentsLPw(packageSetting, parser, 0);
2900                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
2901                    readEnabledComponentsLPw(packageSetting, parser, 0);
2902                } else if (tagName.equals("sigs")) {
2903                    packageSetting.signatures.readXml(parser, mPastSignatures);
2904                } else if (tagName.equals("perms")) {
2905                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
2906                    packageSetting.permissionsFixed = true;
2907                } else if (tagName.equals("signing-keyset")) {
2908                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2909                    packageSetting.keySetData.addSigningKeySet(id);
2910                } else if (tagName.equals("upgrade-keyset")) {
2911                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2912                    packageSetting.keySetData.addUpgradeKeySetById(id);
2913                } else if (tagName.equals("defined-keyset")) {
2914                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2915                    String alias = parser.getAttributeValue(null, "alias");
2916                    packageSetting.keySetData.addDefinedKeySet(id, alias);
2917                } else {
2918                    PackageManagerService.reportSettingsProblem(Log.WARN,
2919                            "Unknown element under <package>: " + parser.getName());
2920                    XmlUtils.skipCurrentTag(parser);
2921                }
2922            }
2923
2924
2925        } else {
2926            XmlUtils.skipCurrentTag(parser);
2927        }
2928    }
2929
2930    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2931            int userId) throws IOException, XmlPullParserException {
2932        int outerDepth = parser.getDepth();
2933        int type;
2934        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2935                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2936            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2937                continue;
2938            }
2939
2940            String tagName = parser.getName();
2941            if (tagName.equals(TAG_ITEM)) {
2942                String name = parser.getAttributeValue(null, ATTR_NAME);
2943                if (name != null) {
2944                    packageSetting.addDisabledComponent(name.intern(), userId);
2945                } else {
2946                    PackageManagerService.reportSettingsProblem(Log.WARN,
2947                            "Error in package manager settings: <disabled-components> has"
2948                                    + " no name at " + parser.getPositionDescription());
2949                }
2950            } else {
2951                PackageManagerService.reportSettingsProblem(Log.WARN,
2952                        "Unknown element under <disabled-components>: " + parser.getName());
2953            }
2954            XmlUtils.skipCurrentTag(parser);
2955        }
2956    }
2957
2958    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2959            int userId) throws IOException, XmlPullParserException {
2960        int outerDepth = parser.getDepth();
2961        int type;
2962        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2963                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2964            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2965                continue;
2966            }
2967
2968            String tagName = parser.getName();
2969            if (tagName.equals(TAG_ITEM)) {
2970                String name = parser.getAttributeValue(null, ATTR_NAME);
2971                if (name != null) {
2972                    packageSetting.addEnabledComponent(name.intern(), userId);
2973                } else {
2974                    PackageManagerService.reportSettingsProblem(Log.WARN,
2975                            "Error in package manager settings: <enabled-components> has"
2976                                    + " no name at " + parser.getPositionDescription());
2977                }
2978            } else {
2979                PackageManagerService.reportSettingsProblem(Log.WARN,
2980                        "Unknown element under <enabled-components>: " + parser.getName());
2981            }
2982            XmlUtils.skipCurrentTag(parser);
2983        }
2984    }
2985
2986    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
2987        String name = null;
2988        String idStr = null;
2989        int pkgFlags = 0;
2990        SharedUserSetting su = null;
2991        try {
2992            name = parser.getAttributeValue(null, ATTR_NAME);
2993            idStr = parser.getAttributeValue(null, "userId");
2994            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2995            if ("true".equals(parser.getAttributeValue(null, "system"))) {
2996                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2997            }
2998            if (name == null) {
2999                PackageManagerService.reportSettingsProblem(Log.WARN,
3000                        "Error in package manager settings: <shared-user> has no name at "
3001                                + parser.getPositionDescription());
3002            } else if (userId == 0) {
3003                PackageManagerService.reportSettingsProblem(Log.WARN,
3004                        "Error in package manager settings: shared-user " + name
3005                                + " has bad userId " + idStr + " at "
3006                                + parser.getPositionDescription());
3007            } else {
3008                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
3009                    PackageManagerService
3010                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
3011                                    + parser.getPositionDescription());
3012                }
3013            }
3014        } catch (NumberFormatException e) {
3015            PackageManagerService.reportSettingsProblem(Log.WARN,
3016                    "Error in package manager settings: package " + name + " has bad userId "
3017                            + idStr + " at " + parser.getPositionDescription());
3018        }
3019        ;
3020
3021        if (su != null) {
3022            int outerDepth = parser.getDepth();
3023            int type;
3024            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3025                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3026                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3027                    continue;
3028                }
3029
3030                String tagName = parser.getName();
3031                if (tagName.equals("sigs")) {
3032                    su.signatures.readXml(parser, mPastSignatures);
3033                } else if (tagName.equals("perms")) {
3034                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
3035                } else {
3036                    PackageManagerService.reportSettingsProblem(Log.WARN,
3037                            "Unknown element under <shared-user>: " + parser.getName());
3038                    XmlUtils.skipCurrentTag(parser);
3039                }
3040            }
3041
3042        } else {
3043            XmlUtils.skipCurrentTag(parser);
3044        }
3045    }
3046
3047    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
3048            throws IOException, XmlPullParserException {
3049        int outerDepth = parser.getDepth();
3050        int type;
3051        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3052                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3053            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3054                continue;
3055            }
3056
3057            String tagName = parser.getName();
3058            if (tagName.equals(TAG_ITEM)) {
3059                String name = parser.getAttributeValue(null, ATTR_NAME);
3060                if (name != null) {
3061                    outPerms.add(name.intern());
3062                } else {
3063                    PackageManagerService.reportSettingsProblem(Log.WARN,
3064                            "Error in package manager settings: <perms> has" + " no name at "
3065                                    + parser.getPositionDescription());
3066                }
3067            } else {
3068                PackageManagerService.reportSettingsProblem(Log.WARN,
3069                        "Unknown element under <perms>: " + parser.getName());
3070            }
3071            XmlUtils.skipCurrentTag(parser);
3072        }
3073    }
3074
3075    void createNewUserLILPw(PackageManagerService service, Installer installer,
3076            int userHandle, File path) {
3077        path.mkdir();
3078        FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
3079                | FileUtils.S_IXOTH, -1, -1);
3080        for (PackageSetting ps : mPackages.values()) {
3081            // Only system apps are initially installed.
3082            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
3083            // Need to create a data directory for all apps under this user.
3084            installer.createUserData(ps.name,
3085                    UserHandle.getUid(userHandle, ps.appId), userHandle,
3086                    ps.pkg.applicationInfo.seinfo);
3087        }
3088        readDefaultPreferredAppsLPw(service, userHandle);
3089        writePackageRestrictionsLPr(userHandle);
3090    }
3091
3092    void removeUserLPr(int userId) {
3093        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
3094        for (Entry<String, PackageSetting> entry : entries) {
3095            entry.getValue().removeUser(userId);
3096        }
3097        mPreferredActivities.remove(userId);
3098        File file = getUserPackagesStateFile(userId);
3099        file.delete();
3100        file = getUserPackagesStateBackupFile(userId);
3101        file.delete();
3102        removeCrossProfileIntentFiltersToUserLPr(userId);
3103    }
3104
3105    void removeCrossProfileIntentFiltersToUserLPr(int targetUserId) {
3106        for (int i = 0; i < mCrossProfileIntentResolvers.size(); i++) {
3107            int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
3108            CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
3109            boolean needsWriting = false;
3110            HashSet<CrossProfileIntentFilter> cpifs =
3111                    new HashSet<CrossProfileIntentFilter>(cpir.filterSet());
3112            for (CrossProfileIntentFilter cpif : cpifs) {
3113                if (cpif.getTargetUserId() == targetUserId) {
3114                    needsWriting = true;
3115                    cpir.removeFilter(cpif);
3116                }
3117            }
3118            if (needsWriting) {
3119                writePackageRestrictionsLPr(sourceUserId);
3120            }
3121        }
3122    }
3123
3124    // This should be called (at least) whenever an application is removed
3125    private void setFirstAvailableUid(int uid) {
3126        if (uid > mFirstAvailableUid) {
3127            mFirstAvailableUid = uid;
3128        }
3129    }
3130
3131    // Returns -1 if we could not find an available UserId to assign
3132    private int newUserIdLPw(Object obj) {
3133        // Let's be stupidly inefficient for now...
3134        final int N = mUserIds.size();
3135        for (int i = mFirstAvailableUid; i < N; i++) {
3136            if (mUserIds.get(i) == null) {
3137                mUserIds.set(i, obj);
3138                return Process.FIRST_APPLICATION_UID + i;
3139            }
3140        }
3141
3142        // None left?
3143        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
3144            return -1;
3145        }
3146
3147        mUserIds.add(obj);
3148        return Process.FIRST_APPLICATION_UID + N;
3149    }
3150
3151    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
3152        if (mVerifierDeviceIdentity == null) {
3153            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
3154
3155            writeLPr();
3156        }
3157
3158        return mVerifierDeviceIdentity;
3159    }
3160
3161    public PackageSetting getDisabledSystemPkgLPr(String name) {
3162        PackageSetting ps = mDisabledSysPackages.get(name);
3163        return ps;
3164    }
3165
3166    private String compToString(HashSet<String> cmp) {
3167        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
3168    }
3169
3170    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
3171        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
3172            return true;
3173        }
3174        final String pkgName = componentInfo.packageName;
3175        final PackageSetting packageSettings = mPackages.get(pkgName);
3176        if (PackageManagerService.DEBUG_SETTINGS) {
3177            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
3178                    + componentInfo.packageName + " componentName = " + componentInfo.name);
3179            Log.v(PackageManagerService.TAG, "enabledComponents: "
3180                    + compToString(packageSettings.getEnabledComponents(userId)));
3181            Log.v(PackageManagerService.TAG, "disabledComponents: "
3182                    + compToString(packageSettings.getDisabledComponents(userId)));
3183        }
3184        if (packageSettings == null) {
3185            return false;
3186        }
3187        PackageUserState ustate = packageSettings.readUserState(userId);
3188        if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
3189            if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
3190                return true;
3191            }
3192        }
3193        if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
3194                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
3195                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
3196                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
3197                    && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
3198            return false;
3199        }
3200        if (ustate.enabledComponents != null
3201                && ustate.enabledComponents.contains(componentInfo.name)) {
3202            return true;
3203        }
3204        if (ustate.disabledComponents != null
3205                && ustate.disabledComponents.contains(componentInfo.name)) {
3206            return false;
3207        }
3208        return componentInfo.enabled;
3209    }
3210
3211    String getInstallerPackageNameLPr(String packageName) {
3212        final PackageSetting pkg = mPackages.get(packageName);
3213        if (pkg == null) {
3214            throw new IllegalArgumentException("Unknown package: " + packageName);
3215        }
3216        return pkg.installerPackageName;
3217    }
3218
3219    int getApplicationEnabledSettingLPr(String packageName, int userId) {
3220        final PackageSetting pkg = mPackages.get(packageName);
3221        if (pkg == null) {
3222            throw new IllegalArgumentException("Unknown package: " + packageName);
3223        }
3224        return pkg.getEnabled(userId);
3225    }
3226
3227    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
3228        final String packageName = componentName.getPackageName();
3229        final PackageSetting pkg = mPackages.get(packageName);
3230        if (pkg == null) {
3231            throw new IllegalArgumentException("Unknown component: " + componentName);
3232        }
3233        final String classNameStr = componentName.getClassName();
3234        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
3235    }
3236
3237    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
3238            boolean allowedByPermission, int uid, int userId) {
3239        int appId = UserHandle.getAppId(uid);
3240        final PackageSetting pkgSetting = mPackages.get(packageName);
3241        if (pkgSetting == null) {
3242            throw new IllegalArgumentException("Unknown package: " + packageName);
3243        }
3244        if (!allowedByPermission && (appId != pkgSetting.appId)) {
3245            throw new SecurityException(
3246                    "Permission Denial: attempt to change stopped state from pid="
3247                    + Binder.getCallingPid()
3248                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
3249        }
3250        if (DEBUG_STOPPED) {
3251            if (stopped) {
3252                RuntimeException e = new RuntimeException("here");
3253                e.fillInStackTrace();
3254                Slog.i(TAG, "Stopping package " + packageName, e);
3255            }
3256        }
3257        if (pkgSetting.getStopped(userId) != stopped) {
3258            pkgSetting.setStopped(stopped, userId);
3259            // pkgSetting.pkg.mSetStopped = stopped;
3260            if (pkgSetting.getNotLaunched(userId)) {
3261                if (pkgSetting.installerPackageName != null) {
3262                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
3263                            pkgSetting.name, null,
3264                            pkgSetting.installerPackageName, null, new int[] {userId});
3265                }
3266                pkgSetting.setNotLaunched(false, userId);
3267            }
3268            return true;
3269        }
3270        return false;
3271    }
3272
3273    private List<UserInfo> getAllUsers() {
3274        long id = Binder.clearCallingIdentity();
3275        try {
3276            return UserManagerService.getInstance().getUsers(false);
3277        } catch (NullPointerException npe) {
3278            // packagemanager not yet initialized
3279        } finally {
3280            Binder.restoreCallingIdentity(id);
3281        }
3282        return null;
3283    }
3284
3285    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
3286        pw.print("[ ");
3287        for (int i=0; i<spec.length; i+=2) {
3288            int mask = (Integer)spec[i];
3289            if ((val & mask) != 0) {
3290                pw.print(spec[i+1]);
3291                pw.print(" ");
3292            }
3293        }
3294        pw.print("]");
3295    }
3296
3297    static final Object[] FLAG_DUMP_SPEC = new Object[] {
3298        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
3299        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
3300        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
3301        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
3302        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
3303        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
3304        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
3305        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
3306        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
3307        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
3308        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
3309        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
3310        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
3311        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
3312        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
3313        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
3314        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
3315        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
3316    };
3317
3318    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
3319            SimpleDateFormat sdf, Date date, List<UserInfo> users) {
3320        if (checkinTag != null) {
3321            pw.print(checkinTag);
3322            pw.print(",");
3323            pw.print(ps.realName != null ? ps.realName : ps.name);
3324            pw.print(",");
3325            pw.print(ps.appId);
3326            pw.print(",");
3327            pw.print(ps.versionCode);
3328            pw.print(",");
3329            pw.print(ps.firstInstallTime);
3330            pw.print(",");
3331            pw.print(ps.lastUpdateTime);
3332            pw.print(",");
3333            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
3334            pw.println();
3335            for (UserInfo user : users) {
3336                pw.print(checkinTag);
3337                pw.print("-");
3338                pw.print("usr");
3339                pw.print(",");
3340                pw.print(user.id);
3341                pw.print(",");
3342                pw.print(ps.getInstalled(user.id) ? "I" : "i");
3343                pw.print(ps.getBlocked(user.id) ? "B" : "b");
3344                pw.print(ps.getStopped(user.id) ? "S" : "s");
3345                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
3346                pw.print(",");
3347                pw.print(ps.getEnabled(user.id));
3348                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3349                pw.print(",");
3350                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
3351                pw.println();
3352            }
3353            return;
3354        }
3355
3356        pw.print(prefix); pw.print("Package [");
3357            pw.print(ps.realName != null ? ps.realName : ps.name);
3358            pw.print("] (");
3359            pw.print(Integer.toHexString(System.identityHashCode(ps)));
3360            pw.println("):");
3361
3362        if (ps.realName != null) {
3363            pw.print(prefix); pw.print("  compat name=");
3364            pw.println(ps.name);
3365        }
3366
3367        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
3368                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
3369        if (ps.sharedUser != null) {
3370            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
3371        }
3372        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
3373        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
3374        pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
3375        pw.print(prefix); pw.print("  nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
3376        pw.print(prefix); pw.print("  requiredCpuAbi="); pw.println(ps.cpuAbiString);
3377        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
3378        if (ps.pkg != null) {
3379            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
3380        }
3381        pw.println();
3382        if (ps.pkg != null) {
3383            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
3384            pw.print(prefix); pw.print("  applicationInfo=");
3385                pw.println(ps.pkg.applicationInfo.toString());
3386            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
3387                    FLAG_DUMP_SPEC); pw.println();
3388            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
3389            if (ps.pkg.mOperationPending) {
3390                pw.print(prefix); pw.println("  mOperationPending=true");
3391            }
3392            pw.print(prefix); pw.print("  supportsScreens=[");
3393            boolean first = true;
3394            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
3395                if (!first)
3396                    pw.print(", ");
3397                first = false;
3398                pw.print("small");
3399            }
3400            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
3401                if (!first)
3402                    pw.print(", ");
3403                first = false;
3404                pw.print("medium");
3405            }
3406            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
3407                if (!first)
3408                    pw.print(", ");
3409                first = false;
3410                pw.print("large");
3411            }
3412            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
3413                if (!first)
3414                    pw.print(", ");
3415                first = false;
3416                pw.print("xlarge");
3417            }
3418            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
3419                if (!first)
3420                    pw.print(", ");
3421                first = false;
3422                pw.print("resizeable");
3423            }
3424            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
3425                if (!first)
3426                    pw.print(", ");
3427                first = false;
3428                pw.print("anyDensity");
3429            }
3430            pw.println("]");
3431            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
3432                pw.print(prefix); pw.println("  libraries:");
3433                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
3434                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
3435                }
3436            }
3437            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
3438                pw.print(prefix); pw.println("  usesLibraries:");
3439                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
3440                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
3441                }
3442            }
3443            if (ps.pkg.usesOptionalLibraries != null
3444                    && ps.pkg.usesOptionalLibraries.size() > 0) {
3445                pw.print(prefix); pw.println("  usesOptionalLibraries:");
3446                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
3447                    pw.print(prefix); pw.print("    ");
3448                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
3449                }
3450            }
3451            if (ps.pkg.usesLibraryFiles != null
3452                    && ps.pkg.usesLibraryFiles.length > 0) {
3453                pw.print(prefix); pw.println("  usesLibraryFiles:");
3454                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
3455                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
3456                }
3457            }
3458        }
3459        pw.print(prefix); pw.print("  timeStamp=");
3460            date.setTime(ps.timeStamp);
3461            pw.println(sdf.format(date));
3462        pw.print(prefix); pw.print("  firstInstallTime=");
3463            date.setTime(ps.firstInstallTime);
3464            pw.println(sdf.format(date));
3465        pw.print(prefix); pw.print("  lastUpdateTime=");
3466            date.setTime(ps.lastUpdateTime);
3467            pw.println(sdf.format(date));
3468        if (ps.installerPackageName != null) {
3469            pw.print(prefix); pw.print("  installerPackageName=");
3470                    pw.println(ps.installerPackageName);
3471        }
3472        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
3473        pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
3474                pw.print(" haveGids="); pw.print(ps.haveGids);
3475                pw.print(" installStatus="); pw.println(ps.installStatus);
3476        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
3477                pw.println();
3478        for (UserInfo user : users) {
3479            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
3480            pw.print(" installed=");
3481            pw.print(ps.getInstalled(user.id));
3482            pw.print(" blocked=");
3483            pw.print(ps.getBlocked(user.id));
3484            pw.print(" stopped=");
3485            pw.print(ps.getStopped(user.id));
3486            pw.print(" notLaunched=");
3487            pw.print(ps.getNotLaunched(user.id));
3488            pw.print(" enabled=");
3489            pw.println(ps.getEnabled(user.id));
3490            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3491            if (lastDisabledAppCaller != null) {
3492                pw.print(prefix); pw.print("    lastDisabledCaller: ");
3493                        pw.println(lastDisabledAppCaller);
3494            }
3495            HashSet<String> cmp = ps.getDisabledComponents(user.id);
3496            if (cmp != null && cmp.size() > 0) {
3497                pw.print(prefix); pw.println("    disabledComponents:");
3498                for (String s : cmp) {
3499                    pw.print(prefix); pw.print("    "); pw.println(s);
3500                }
3501            }
3502            cmp = ps.getEnabledComponents(user.id);
3503            if (cmp != null && cmp.size() > 0) {
3504                pw.print(prefix); pw.println("    enabledComponents:");
3505                for (String s : cmp) {
3506                    pw.print(prefix); pw.print("    "); pw.println(s);
3507                }
3508            }
3509        }
3510        if (ps.grantedPermissions.size() > 0) {
3511            pw.print(prefix); pw.println("  grantedPermissions:");
3512            for (String s : ps.grantedPermissions) {
3513                pw.print(prefix); pw.print("    "); pw.println(s);
3514            }
3515        }
3516    }
3517
3518    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
3519        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3520        final Date date = new Date();
3521        boolean printedSomething = false;
3522        List<UserInfo> users = getAllUsers();
3523        for (final PackageSetting ps : mPackages.values()) {
3524            if (packageName != null && !packageName.equals(ps.realName)
3525                    && !packageName.equals(ps.name)) {
3526                continue;
3527            }
3528
3529            if (!checkin && packageName != null) {
3530                dumpState.setSharedUser(ps.sharedUser);
3531            }
3532
3533            if (!checkin && !printedSomething) {
3534                if (dumpState.onTitlePrinted())
3535                    pw.println();
3536                pw.println("Packages:");
3537                printedSomething = true;
3538            }
3539            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, ps, sdf, date, users);
3540        }
3541
3542        printedSomething = false;
3543        if (!checkin && mRenamedPackages.size() > 0) {
3544            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
3545                if (packageName != null && !packageName.equals(e.getKey())
3546                        && !packageName.equals(e.getValue())) {
3547                    continue;
3548                }
3549                if (!checkin) {
3550                    if (!printedSomething) {
3551                        if (dumpState.onTitlePrinted())
3552                            pw.println();
3553                        pw.println("Renamed packages:");
3554                        printedSomething = true;
3555                    }
3556                    pw.print("  ");
3557                } else {
3558                    pw.print("ren,");
3559                }
3560                pw.print(e.getKey());
3561                pw.print(checkin ? " -> " : ",");
3562                pw.println(e.getValue());
3563            }
3564        }
3565
3566        printedSomething = false;
3567        if (mDisabledSysPackages.size() > 0) {
3568            for (final PackageSetting ps : mDisabledSysPackages.values()) {
3569                if (packageName != null && !packageName.equals(ps.realName)
3570                        && !packageName.equals(ps.name)) {
3571                    continue;
3572                }
3573                if (!checkin && !printedSomething) {
3574                    if (dumpState.onTitlePrinted())
3575                        pw.println();
3576                    pw.println("Hidden system packages:");
3577                    printedSomething = true;
3578                }
3579                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, ps, sdf, date, users);
3580            }
3581        }
3582    }
3583
3584    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3585        boolean printedSomething = false;
3586        for (BasePermission p : mPermissions.values()) {
3587            if (packageName != null && !packageName.equals(p.sourcePackage)) {
3588                continue;
3589            }
3590            if (!printedSomething) {
3591                if (dumpState.onTitlePrinted())
3592                    pw.println();
3593                pw.println("Permissions:");
3594                printedSomething = true;
3595            }
3596            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
3597                    pw.print(Integer.toHexString(System.identityHashCode(p)));
3598                    pw.println("):");
3599            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
3600            pw.print("    uid="); pw.print(p.uid);
3601                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
3602                    pw.print(" type="); pw.print(p.type);
3603                    pw.print(" prot=");
3604                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
3605            if (p.packageSetting != null) {
3606                pw.print("    packageSetting="); pw.println(p.packageSetting);
3607            }
3608            if (p.perm != null) {
3609                pw.print("    perm="); pw.println(p.perm);
3610            }
3611            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
3612                pw.print("    enforced=");
3613                pw.println(mReadExternalStorageEnforced);
3614            }
3615        }
3616    }
3617
3618    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3619        boolean printedSomething = false;
3620        for (SharedUserSetting su : mSharedUsers.values()) {
3621            if (packageName != null && su != dumpState.getSharedUser()) {
3622                continue;
3623            }
3624            if (!printedSomething) {
3625                if (dumpState.onTitlePrinted())
3626                    pw.println();
3627                pw.println("Shared users:");
3628                printedSomething = true;
3629            }
3630            pw.print("  SharedUser [");
3631            pw.print(su.name);
3632            pw.print("] (");
3633            pw.print(Integer.toHexString(System.identityHashCode(su)));
3634                    pw.println("):");
3635            pw.print("    userId=");
3636            pw.print(su.userId);
3637            pw.print(" gids=");
3638            pw.println(PackageManagerService.arrayToString(su.gids));
3639            pw.println("    grantedPermissions:");
3640            for (String s : su.grantedPermissions) {
3641                pw.print("      ");
3642                pw.println(s);
3643            }
3644        }
3645    }
3646
3647    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
3648        pw.println("Settings parse messages:");
3649        pw.print(mReadMessages.toString());
3650    }
3651}
3652