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