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