Settings.java revision bf65cc3bb6f17e4e11418b1ae17f7b7a0f29fd57
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_USER;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
23import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
24
25import com.android.internal.util.FastXmlSerializer;
26import com.android.internal.util.JournaledFile;
27import com.android.internal.util.XmlUtils;
28import com.android.server.IntentResolver;
29import com.android.server.pm.PackageManagerService.DumpState;
30
31import org.xmlpull.v1.XmlPullParser;
32import org.xmlpull.v1.XmlPullParserException;
33import org.xmlpull.v1.XmlSerializer;
34
35import android.app.AppGlobals;
36import android.content.ComponentName;
37import android.content.Intent;
38import android.content.pm.ApplicationInfo;
39import android.content.pm.ComponentInfo;
40import android.content.pm.PackageManager;
41import android.content.pm.PackageParser;
42import android.content.pm.PermissionInfo;
43import android.content.pm.Signature;
44import android.content.pm.UserInfo;
45import android.content.pm.VerifierDeviceIdentity;
46import android.os.Binder;
47import android.os.Environment;
48import android.os.FileUtils;
49import android.os.Process;
50import android.os.RemoteException;
51import android.os.UserId;
52import android.util.Log;
53import android.util.Slog;
54import android.util.SparseArray;
55import android.util.Xml;
56
57import java.io.BufferedOutputStream;
58import java.io.File;
59import java.io.FileInputStream;
60import java.io.FileOutputStream;
61import java.io.IOException;
62import java.io.PrintWriter;
63import java.text.SimpleDateFormat;
64import java.util.ArrayList;
65import java.util.Arrays;
66import java.util.Date;
67import java.util.HashMap;
68import java.util.HashSet;
69import java.util.Iterator;
70import java.util.List;
71import java.util.Map;
72
73import libcore.io.IoUtils;
74
75/**
76 * Holds information about dynamic settings.
77 */
78final class Settings {
79    private static final String TAG = "PackageSettings";
80
81    private static final boolean DEBUG_STOPPED = false;
82
83    private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
84    private static final String ATTR_ENFORCEMENT = "enforcement";
85
86    private static final String TAG_ITEM = "item";
87    private static final String TAG_DISABLED_COMPONENTS = "disabled-components";
88    private static final String TAG_ENABLED_COMPONENTS = "enabled-components";
89    private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions";
90    private static final String TAG_PACKAGE = "pkg";
91
92    private static final String ATTR_NAME = "name";
93    private static final String ATTR_NOT_LAUNCHED = "nl";
94    private static final String ATTR_ENABLED = "enabled";
95    private static final String ATTR_STOPPED = "stopped";
96
97    private final File mSettingsFilename;
98    private final File mBackupSettingsFilename;
99    private final File mPackageListFilename;
100    private final File mStoppedPackagesFilename;
101    private final File mBackupStoppedPackagesFilename;
102    final HashMap<String, PackageSetting> mPackages =
103            new HashMap<String, PackageSetting>();
104    // List of replaced system applications
105    final HashMap<String, PackageSetting> mDisabledSysPackages =
106        new HashMap<String, PackageSetting>();
107
108    // These are the last platform API version we were using for
109    // the apps installed on internal and external storage.  It is
110    // used to grant newer permissions one time during a system upgrade.
111    int mInternalSdkPlatform;
112    int mExternalSdkPlatform;
113
114    boolean mReadExternalStorageEnforced = PackageManager.DEFAULT_ENFORCE_READ_EXTERNAL_STORAGE;
115
116    /** Device identity for the purpose of package verification. */
117    private VerifierDeviceIdentity mVerifierDeviceIdentity;
118
119    // The user's preferred activities associated with particular intent
120    // filters.
121    final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities =
122                new IntentResolver<PreferredActivity, PreferredActivity>() {
123        @Override
124        protected String packageForFilter(PreferredActivity filter) {
125            return filter.mPref.mComponent.getPackageName();
126        }
127        @Override
128        protected void dumpFilter(PrintWriter out, String prefix,
129                PreferredActivity filter) {
130            filter.mPref.dump(out, prefix, filter);
131        }
132    };
133    final HashMap<String, SharedUserSetting> mSharedUsers =
134            new HashMap<String, SharedUserSetting>();
135    private final ArrayList<Object> mUserIds = new ArrayList<Object>();
136    private final SparseArray<Object> mOtherUserIds =
137            new SparseArray<Object>();
138
139    // For reading/writing settings file.
140    private final ArrayList<Signature> mPastSignatures =
141            new ArrayList<Signature>();
142
143    // Mapping from permission names to info about them.
144    final HashMap<String, BasePermission> mPermissions =
145            new HashMap<String, BasePermission>();
146
147    // Mapping from permission tree names to info about them.
148    final HashMap<String, BasePermission> mPermissionTrees =
149            new HashMap<String, BasePermission>();
150
151    // Packages that have been uninstalled and still need their external
152    // storage data deleted.
153    final ArrayList<String> mPackagesToBeCleaned = new ArrayList<String>();
154
155    // Packages that have been renamed since they were first installed.
156    // Keys are the new names of the packages, values are the original
157    // names.  The packages appear everwhere else under their original
158    // names.
159    final HashMap<String, String> mRenamedPackages = new HashMap<String, String>();
160
161    final StringBuilder mReadMessages = new StringBuilder();
162
163    /**
164     * Used to track packages that have a shared user ID that hasn't been read
165     * in yet.
166     * <p>
167     * TODO: make this just a local variable that is passed in during package
168     * scanning to make it less confusing.
169     */
170    private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
171
172    private final File mSystemDir;
173    Settings() {
174        this(Environment.getDataDirectory());
175    }
176
177    Settings(File dataDir) {
178        mSystemDir = new File(dataDir, "system");
179        mSystemDir.mkdirs();
180        FileUtils.setPermissions(mSystemDir.toString(),
181                FileUtils.S_IRWXU|FileUtils.S_IRWXG
182                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
183                -1, -1);
184        mSettingsFilename = new File(mSystemDir, "packages.xml");
185        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
186        mPackageListFilename = new File(mSystemDir, "packages.list");
187        // Deprecated: Needed for migration
188        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
189        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
190    }
191
192    PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
193            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
194            String nativeLibraryPathString, int pkgFlags, boolean create, boolean add) {
195        final String name = pkg.packageName;
196        PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
197                resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, create, add);
198        return p;
199    }
200
201    PackageSetting peekPackageLPr(String name) {
202        return mPackages.get(name);
203    }
204
205    void setInstallStatus(String pkgName, int status) {
206        PackageSetting p = mPackages.get(pkgName);
207        if(p != null) {
208            if(p.getInstallStatus() != status) {
209                p.setInstallStatus(status);
210            }
211        }
212    }
213
214    void setInstallerPackageName(String pkgName,
215            String installerPkgName) {
216        PackageSetting p = mPackages.get(pkgName);
217        if(p != null) {
218            p.setInstallerPackageName(installerPkgName);
219        }
220    }
221
222    SharedUserSetting getSharedUserLPw(String name,
223            int pkgFlags, boolean create) {
224        SharedUserSetting s = mSharedUsers.get(name);
225        if (s == null) {
226            if (!create) {
227                return null;
228            }
229            s = new SharedUserSetting(name, pkgFlags);
230            s.userId = newUserIdLPw(s);
231            Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
232            // < 0 means we couldn't assign a userid; fall out and return
233            // s, which is currently null
234            if (s.userId >= 0) {
235                mSharedUsers.put(name, s);
236            }
237        }
238
239        return s;
240    }
241
242    boolean disableSystemPackageLPw(String name) {
243        final PackageSetting p = mPackages.get(name);
244        if(p == null) {
245            Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
246            return false;
247        }
248        final PackageSetting dp = mDisabledSysPackages.get(name);
249        // always make sure the system package code and resource paths dont change
250        if (dp == null) {
251            if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
252                p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
253            }
254            mDisabledSysPackages.put(name, p);
255
256            // a little trick...  when we install the new package, we don't
257            // want to modify the existing PackageSetting for the built-in
258            // version.  so at this point we need a new PackageSetting that
259            // is okay to muck with.
260            PackageSetting newp = new PackageSetting(p);
261            replacePackageLPw(name, newp);
262            return true;
263        }
264        return false;
265    }
266
267    PackageSetting enableSystemPackageLPw(String name) {
268        PackageSetting p = mDisabledSysPackages.get(name);
269        if(p == null) {
270            Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
271            return null;
272        }
273        // Reset flag in ApplicationInfo object
274        if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
275            p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
276        }
277        PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
278                p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
279        mDisabledSysPackages.remove(name);
280        return ret;
281    }
282
283    PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
284            String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
285        PackageSetting p = mPackages.get(name);
286        if (p != null) {
287            if (p.appId == uid) {
288                return p;
289            }
290            PackageManagerService.reportSettingsProblem(Log.ERROR,
291                    "Adding duplicate package, keeping first: " + name);
292            return null;
293        }
294        p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
295                vc, pkgFlags);
296        p.appId = uid;
297        if (addUserIdLPw(uid, p, name)) {
298            mPackages.put(name, p);
299            return p;
300        }
301        return null;
302    }
303
304    SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
305        SharedUserSetting s = mSharedUsers.get(name);
306        if (s != null) {
307            if (s.userId == uid) {
308                return s;
309            }
310            PackageManagerService.reportSettingsProblem(Log.ERROR,
311                    "Adding duplicate shared user, keeping first: " + name);
312            return null;
313        }
314        s = new SharedUserSetting(name, pkgFlags);
315        s.userId = uid;
316        if (addUserIdLPw(uid, s, name)) {
317            mSharedUsers.put(name, s);
318            return s;
319        }
320        return null;
321    }
322
323    // Transfer ownership of permissions from one package to another.
324    void transferPermissionsLPw(String origPkg, String newPkg) {
325        // Transfer ownership of permissions to the new package.
326        for (int i=0; i<2; i++) {
327            HashMap<String, BasePermission> permissions =
328                    i == 0 ? mPermissionTrees : mPermissions;
329            for (BasePermission bp : permissions.values()) {
330                if (origPkg.equals(bp.sourcePackage)) {
331                    if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG,
332                            "Moving permission " + bp.name
333                            + " from pkg " + bp.sourcePackage
334                            + " to " + newPkg);
335                    bp.sourcePackage = newPkg;
336                    bp.packageSetting = null;
337                    bp.perm = null;
338                    if (bp.pendingInfo != null) {
339                        bp.pendingInfo.packageName = newPkg;
340                    }
341                    bp.uid = 0;
342                    bp.gids = null;
343                }
344            }
345        }
346    }
347
348    private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
349            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
350            String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) {
351        PackageSetting p = mPackages.get(name);
352        if (p != null) {
353            if (!p.codePath.equals(codePath)) {
354                // Check to see if its a disabled system app
355                if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
356                    // This is an updated system app with versions in both system
357                    // and data partition. Just let the most recent version
358                    // take precedence.
359                    Slog.w(PackageManagerService.TAG, "Trying to update system app code path from "
360                            + p.codePathString + " to " + codePath.toString());
361                } else {
362                    // Just a change in the code path is not an issue, but
363                    // let's log a message about it.
364                    Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from "
365                            + p.codePath + " to " + codePath + "; Retaining data and using new");
366                    /*
367                     * Since we've changed paths, we need to prefer the new
368                     * native library path over the one stored in the
369                     * package settings since we might have moved from
370                     * internal to external storage or vice versa.
371                     */
372                    p.nativeLibraryPathString = nativeLibraryPathString;
373                }
374            }
375            if (p.sharedUser != sharedUser) {
376                PackageManagerService.reportSettingsProblem(Log.WARN,
377                        "Package " + name + " shared user changed from "
378                        + (p.sharedUser != null ? p.sharedUser.name : "<nothing>")
379                        + " to "
380                        + (sharedUser != null ? sharedUser.name : "<nothing>")
381                        + "; replacing with new");
382                p = null;
383            } else {
384                if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
385                    // If what we are scanning is a system package, then
386                    // make it so, regardless of whether it was previously
387                    // installed only in the data partition.
388                    p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
389                }
390            }
391        }
392        if (p == null) {
393            // Create a new PackageSettings entry. this can end up here because
394            // of code path mismatch or user id mismatch of an updated system partition
395            if (!create) {
396                return null;
397            }
398            if (origPackage != null) {
399                // We are consuming the data from an existing package.
400                p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
401                        nativeLibraryPathString, vc, pkgFlags);
402                if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
403                        + name + " is adopting original package " + origPackage.name);
404                // Note that we will retain the new package's signature so
405                // that we can keep its data.
406                PackageSignatures s = p.signatures;
407                p.copyFrom(origPackage);
408                p.signatures = s;
409                p.sharedUser = origPackage.sharedUser;
410                p.appId = origPackage.appId;
411                p.origPackage = origPackage;
412                mRenamedPackages.put(name, origPackage.name);
413                name = origPackage.name;
414                // Update new package state.
415                p.setTimeStamp(codePath.lastModified());
416            } else {
417                p = new PackageSetting(name, realName, codePath, resourcePath,
418                        nativeLibraryPathString, vc, pkgFlags);
419                p.setTimeStamp(codePath.lastModified());
420                p.sharedUser = sharedUser;
421                // If this is not a system app, it starts out stopped.
422                if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
423                    if (DEBUG_STOPPED) {
424                        RuntimeException e = new RuntimeException("here");
425                        e.fillInStackTrace();
426                        Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
427                    }
428                    List<UserInfo> users = getAllUsers();
429                    if (users != null) {
430                        for (UserInfo user : users) {
431                            p.setStopped(true, user.id);
432                            p.setNotLaunched(true, user.id);
433                            writePackageRestrictionsLPr(user.id);
434                        }
435                    }
436                }
437                if (sharedUser != null) {
438                    p.appId = sharedUser.userId;
439                } else {
440                    // Clone the setting here for disabled system packages
441                    PackageSetting dis = mDisabledSysPackages.get(name);
442                    if (dis != null) {
443                        // For disabled packages a new setting is created
444                        // from the existing user id. This still has to be
445                        // added to list of user id's
446                        // Copy signatures from previous setting
447                        if (dis.signatures.mSignatures != null) {
448                            p.signatures.mSignatures = dis.signatures.mSignatures.clone();
449                        }
450                        p.appId = dis.appId;
451                        // Clone permissions
452                        p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
453                        // Clone component info
454                        List<UserInfo> users = getAllUsers();
455                        if (users != null) {
456                            for (UserInfo user : users) {
457                                int userId = user.id;
458                                p.setDisabledComponents(
459                                        new HashSet<String>(dis.getDisabledComponents(userId)),
460                                        userId);
461                                p.setEnabledComponents(
462                                        new HashSet<String>(dis.getEnabledComponents(userId)),
463                                        userId);
464                            }
465                        }
466                        // Add new setting to list of user ids
467                        addUserIdLPw(p.appId, p, name);
468                    } else {
469                        // Assign new user id
470                        p.appId = newUserIdLPw(p);
471                    }
472                }
473            }
474            if (p.appId < 0) {
475                PackageManagerService.reportSettingsProblem(Log.WARN,
476                        "Package " + name + " could not be assigned a valid uid");
477                return null;
478            }
479            if (add) {
480                // Finish adding new package by adding it and updating shared
481                // user preferences
482                addPackageSettingLPw(p, name, sharedUser);
483            }
484        }
485        return p;
486    }
487
488    void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
489        p.pkg = pkg;
490        // pkg.mSetEnabled = p.getEnabled(userId);
491        // pkg.mSetStopped = p.getStopped(userId);
492        final String codePath = pkg.applicationInfo.sourceDir;
493        final String resourcePath = pkg.applicationInfo.publicSourceDir;
494        // Update code path if needed
495        if (!codePath.equalsIgnoreCase(p.codePathString)) {
496            Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName +
497                    " changing from " + p.codePathString + " to " + codePath);
498            p.codePath = new File(codePath);
499            p.codePathString = codePath;
500        }
501        //Update resource path if needed
502        if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) {
503            Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName +
504                    " changing from " + p.resourcePathString + " to " + resourcePath);
505            p.resourcePath = new File(resourcePath);
506            p.resourcePathString = resourcePath;
507        }
508        // Update the native library path if needed
509        final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
510        if (nativeLibraryPath != null
511                && !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
512            p.nativeLibraryPathString = nativeLibraryPath;
513        }
514        // Update version code if needed
515        if (pkg.mVersionCode != p.versionCode) {
516            p.versionCode = pkg.mVersionCode;
517        }
518        // Update signatures if needed.
519        if (p.signatures.mSignatures == null) {
520            p.signatures.assignSignatures(pkg.mSignatures);
521        }
522        // If this app defines a shared user id initialize
523        // the shared user signatures as well.
524        if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
525            p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
526        }
527        addPackageSettingLPw(p, pkg.packageName, p.sharedUser);
528    }
529
530    // Utility method that adds a PackageSetting to mPackages and
531    // completes updating the shared user attributes
532    private void addPackageSettingLPw(PackageSetting p, String name,
533            SharedUserSetting sharedUser) {
534        mPackages.put(name, p);
535        if (sharedUser != null) {
536            if (p.sharedUser != null && p.sharedUser != sharedUser) {
537                PackageManagerService.reportSettingsProblem(Log.ERROR,
538                        "Package " + p.name + " was user "
539                        + p.sharedUser + " but is now " + sharedUser
540                        + "; I am not changing its files so it will probably fail!");
541                p.sharedUser.packages.remove(p);
542            } else if (p.appId != sharedUser.userId) {
543                PackageManagerService.reportSettingsProblem(Log.ERROR,
544                    "Package " + p.name + " was user id " + p.appId
545                    + " but is now user " + sharedUser
546                    + " with id " + sharedUser.userId
547                    + "; I am not changing its files so it will probably fail!");
548            }
549
550            sharedUser.packages.add(p);
551            p.sharedUser = sharedUser;
552            p.appId = sharedUser.userId;
553        }
554    }
555
556    /*
557     * Update the shared user setting when a package using
558     * specifying the shared user id is removed. The gids
559     * associated with each permission of the deleted package
560     * are removed from the shared user's gid list only if its
561     * not in use by other permissions of packages in the
562     * shared user setting.
563     */
564    void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
565        if ((deletedPs == null) || (deletedPs.pkg == null)) {
566            Slog.i(PackageManagerService.TAG,
567                    "Trying to update info for null package. Just ignoring");
568            return;
569        }
570        // No sharedUserId
571        if (deletedPs.sharedUser == null) {
572            return;
573        }
574        SharedUserSetting sus = deletedPs.sharedUser;
575        // Update permissions
576        for (String eachPerm : deletedPs.pkg.requestedPermissions) {
577            boolean used = false;
578            if (!sus.grantedPermissions.contains(eachPerm)) {
579                continue;
580            }
581            for (PackageSetting pkg:sus.packages) {
582                if (pkg.pkg != null &&
583                        !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
584                        pkg.pkg.requestedPermissions.contains(eachPerm)) {
585                    used = true;
586                    break;
587                }
588            }
589            if (!used) {
590                // can safely delete this permission from list
591                sus.grantedPermissions.remove(eachPerm);
592            }
593        }
594        // Update gids
595        int newGids[] = globalGids;
596        for (String eachPerm : sus.grantedPermissions) {
597            BasePermission bp = mPermissions.get(eachPerm);
598            if (bp != null) {
599                newGids = PackageManagerService.appendInts(newGids, bp.gids);
600            }
601        }
602        sus.gids = newGids;
603    }
604
605    int removePackageLPw(String name) {
606        final PackageSetting p = mPackages.get(name);
607        if (p != null) {
608            mPackages.remove(name);
609            if (p.sharedUser != null) {
610                p.sharedUser.packages.remove(p);
611                if (p.sharedUser.packages.size() == 0) {
612                    mSharedUsers.remove(p.sharedUser.name);
613                    removeUserIdLPw(p.sharedUser.userId);
614                    return p.sharedUser.userId;
615                }
616            } else {
617                removeUserIdLPw(p.appId);
618                return p.appId;
619            }
620        }
621        return -1;
622    }
623
624    private void replacePackageLPw(String name, PackageSetting newp) {
625        final PackageSetting p = mPackages.get(name);
626        if (p != null) {
627            if (p.sharedUser != null) {
628                p.sharedUser.packages.remove(p);
629                p.sharedUser.packages.add(newp);
630            } else {
631                replaceUserIdLPw(p.appId, newp);
632            }
633        }
634        mPackages.put(name, newp);
635    }
636
637    private boolean addUserIdLPw(int uid, Object obj, Object name) {
638        if (uid > Process.LAST_APPLICATION_UID) {
639            return false;
640        }
641
642        if (uid >= Process.FIRST_APPLICATION_UID) {
643            int N = mUserIds.size();
644            final int index = uid - Process.FIRST_APPLICATION_UID;
645            while (index >= N) {
646                mUserIds.add(null);
647                N++;
648            }
649            if (mUserIds.get(index) != null) {
650                PackageManagerService.reportSettingsProblem(Log.ERROR,
651                        "Adding duplicate user id: " + uid
652                        + " name=" + name);
653                return false;
654            }
655            mUserIds.set(index, obj);
656        } else {
657            if (mOtherUserIds.get(uid) != null) {
658                PackageManagerService.reportSettingsProblem(Log.ERROR,
659                        "Adding duplicate shared id: " + uid
660                        + " name=" + name);
661                return false;
662            }
663            mOtherUserIds.put(uid, obj);
664        }
665        return true;
666    }
667
668    public Object getUserIdLPr(int uid) {
669        if (uid >= Process.FIRST_APPLICATION_UID) {
670            final int N = mUserIds.size();
671            final int index = uid - Process.FIRST_APPLICATION_UID;
672            return index < N ? mUserIds.get(index) : null;
673        } else {
674            return mOtherUserIds.get(uid);
675        }
676    }
677
678    private void removeUserIdLPw(int uid) {
679        if (uid >= Process.FIRST_APPLICATION_UID) {
680            final int N = mUserIds.size();
681            final int index = uid - Process.FIRST_APPLICATION_UID;
682            if (index < N) mUserIds.set(index, null);
683        } else {
684            mOtherUserIds.remove(uid);
685        }
686    }
687
688    private void replaceUserIdLPw(int uid, Object obj) {
689        if (uid >= Process.FIRST_APPLICATION_UID) {
690            final int N = mUserIds.size();
691            final int index = uid - Process.FIRST_APPLICATION_UID;
692            if (index < N) mUserIds.set(index, obj);
693        } else {
694            mOtherUserIds.put(uid, obj);
695        }
696    }
697
698    private File getUserPackagesStateFile(int userId) {
699        return new File(mSystemDir,
700                "users/" + userId + "/package-restrictions.xml");
701    }
702
703    private File getUserPackagesStateBackupFile(int userId) {
704        return new File(mSystemDir,
705                "users/" + userId + "/package-restrictions-backup.xml");
706    }
707
708    void writeAllUsersPackageRestrictionsLPr() {
709        List<UserInfo> users = getAllUsers();
710        if (users == null) return;
711
712        for (UserInfo user : users) {
713            writePackageRestrictionsLPr(user.id);
714        }
715    }
716
717    void readAllUsersPackageRestrictionsLPr() {
718        List<UserInfo> users = getAllUsers();
719        if (users == null) {
720            readPackageRestrictionsLPr(0);
721            return;
722        }
723
724        for (UserInfo user : users) {
725            readPackageRestrictionsLPr(user.id);
726        }
727    }
728
729    void readPackageRestrictionsLPr(int userId) {
730        FileInputStream str = null;
731        File userPackagesStateFile = getUserPackagesStateFile(userId);
732        File backupFile = getUserPackagesStateBackupFile(userId);
733        if (backupFile.exists()) {
734            try {
735                str = new FileInputStream(backupFile);
736                mReadMessages.append("Reading from backup stopped packages file\n");
737                PackageManagerService.reportSettingsProblem(Log.INFO,
738                        "Need to read from backup stopped packages file");
739                if (userPackagesStateFile.exists()) {
740                    // If both the backup and normal file exist, we
741                    // ignore the normal one since it might have been
742                    // corrupted.
743                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
744                            + userPackagesStateFile);
745                    userPackagesStateFile.delete();
746                }
747            } catch (java.io.IOException e) {
748                // We'll try for the normal settings file.
749            }
750        }
751
752        try {
753            if (str == null) {
754                if (!userPackagesStateFile.exists()) {
755                    mReadMessages.append("No stopped packages file found\n");
756                    PackageManagerService.reportSettingsProblem(Log.INFO,
757                            "No stopped packages file; "
758                            + "assuming all started");
759                    // At first boot, make sure no packages are stopped.
760                    // We usually want to have third party apps initialize
761                    // in the stopped state, but not at first boot.
762                    for (PackageSetting pkg : mPackages.values()) {
763                        pkg.setStopped(false, userId);
764                        pkg.setNotLaunched(false, userId);
765                    }
766                    return;
767                }
768                str = new FileInputStream(userPackagesStateFile);
769            }
770            final XmlPullParser parser = Xml.newPullParser();
771            parser.setInput(str, null);
772
773            int type;
774            while ((type=parser.next()) != XmlPullParser.START_TAG
775                       && type != XmlPullParser.END_DOCUMENT) {
776                ;
777            }
778
779            if (type != XmlPullParser.START_TAG) {
780                mReadMessages.append("No start tag found in package restrictions file\n");
781                PackageManagerService.reportSettingsProblem(Log.WARN,
782                        "No start tag found in package manager stopped packages");
783                return;
784            }
785
786            int outerDepth = parser.getDepth();
787            PackageSetting ps = null;
788            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
789                   && (type != XmlPullParser.END_TAG
790                           || parser.getDepth() > outerDepth)) {
791                if (type == XmlPullParser.END_TAG
792                        || type == XmlPullParser.TEXT) {
793                    continue;
794                }
795
796                String tagName = parser.getName();
797                if (tagName.equals(TAG_PACKAGE)) {
798                    String name = parser.getAttributeValue(null, ATTR_NAME);
799                    ps = mPackages.get(name);
800                    if (ps == null) {
801                        Slog.w(PackageManagerService.TAG, "No package known for stopped package: "
802                                + name);
803                        XmlUtils.skipCurrentTag(parser);
804                        continue;
805                    }
806                    String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
807                    int enabled = enabledStr == null ? COMPONENT_ENABLED_STATE_DEFAULT
808                            : Integer.parseInt(enabledStr);
809                    ps.setEnabled(enabled, userId);
810                    String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
811                    boolean stopped = stoppedStr == null ? false : Boolean.parseBoolean(stoppedStr);
812                    ps.setStopped(stopped, userId);
813                    String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
814                    boolean notLaunched = stoppedStr == null ? false
815                            : Boolean.parseBoolean(notLaunchedStr);
816                    ps.setNotLaunched(notLaunched, userId);
817
818                    int packageDepth = parser.getDepth();
819                    while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
820                            && (type != XmlPullParser.END_TAG
821                            || parser.getDepth() > packageDepth)) {
822                        if (type == XmlPullParser.END_TAG
823                                || type == XmlPullParser.TEXT) {
824                            continue;
825                        }
826                        tagName = parser.getName();
827                        if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
828                            HashSet<String> components = readComponentsLPr(parser);
829                            ps.setEnabledComponents(components, userId);
830                        } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
831                            HashSet<String> components = readComponentsLPr(parser);
832                            ps.setDisabledComponents(components, userId);
833                        }
834                    }
835                } else {
836                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
837                          + parser.getName());
838                    XmlUtils.skipCurrentTag(parser);
839                }
840            }
841
842            str.close();
843
844        } catch (XmlPullParserException e) {
845            mReadMessages.append("Error reading: " + e.toString());
846            PackageManagerService.reportSettingsProblem(Log.ERROR,
847                    "Error reading stopped packages: " + e);
848            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
849
850        } catch (java.io.IOException e) {
851            mReadMessages.append("Error reading: " + e.toString());
852            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
853            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
854        }
855    }
856
857    private HashSet<String> readComponentsLPr(XmlPullParser parser)
858            throws IOException, XmlPullParserException {
859        HashSet<String> components = new HashSet<String>();
860        int type;
861        int outerDepth = parser.getDepth();
862        String tagName;
863        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
864                && (type != XmlPullParser.END_TAG
865                || parser.getDepth() > outerDepth)) {
866            if (type == XmlPullParser.END_TAG
867                    || type == XmlPullParser.TEXT) {
868                continue;
869            }
870            tagName = parser.getName();
871            if (tagName.equals(TAG_ITEM)) {
872                String componentName = parser.getAttributeValue(null, ATTR_NAME);
873                if (componentName != null) {
874                    components.add(componentName);
875                }
876            }
877        }
878        return components;
879    }
880
881    void writePackageRestrictionsLPr(int userId) {
882        // Keep the old stopped packages around until we know the new ones have
883        // been successfully written.
884        File userPackagesStateFile = getUserPackagesStateFile(userId);
885        File backupFile = getUserPackagesStateBackupFile(userId);
886        new File(userPackagesStateFile.getParent()).mkdirs();
887        if (userPackagesStateFile.exists()) {
888            // Presence of backup settings file indicates that we failed
889            // to persist packages earlier. So preserve the older
890            // backup for future reference since the current packages
891            // might have been corrupted.
892            if (!backupFile.exists()) {
893                if (!userPackagesStateFile.renameTo(backupFile)) {
894                    Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, "
895                            + "current changes will be lost at reboot");
896                    return;
897                }
898            } else {
899                userPackagesStateFile.delete();
900                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
901            }
902        }
903
904        try {
905            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
906            final BufferedOutputStream str = new BufferedOutputStream(fstr);
907
908            final XmlSerializer serializer = new FastXmlSerializer();
909            serializer.setOutput(str, "utf-8");
910            serializer.startDocument(null, true);
911            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
912
913            serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
914
915            for (final PackageSetting pkg : mPackages.values()) {
916                if (pkg.getStopped(userId)
917                        || pkg.getNotLaunched(userId)
918                        || pkg.getEnabled(userId) != COMPONENT_ENABLED_STATE_DEFAULT
919                        || pkg.getEnabledComponents(userId).size() > 0
920                        || pkg.getDisabledComponents(userId).size() > 0) {
921                    serializer.startTag(null, TAG_PACKAGE);
922                    serializer.attribute(null, ATTR_NAME, pkg.name);
923                    boolean stopped = pkg.getStopped(userId);
924                    boolean notLaunched = pkg.getNotLaunched(userId);
925                    int enabled = pkg.getEnabled(userId);
926                    HashSet<String> enabledComponents = pkg.getEnabledComponents(userId);
927                    HashSet<String> disabledComponents = pkg.getDisabledComponents(userId);
928
929                    if (stopped) {
930                        serializer.attribute(null, ATTR_STOPPED, "true");
931                    }
932                    if (notLaunched) {
933                        serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
934                    }
935                    if (enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
936                        serializer.attribute(null, ATTR_ENABLED, Integer.toString(enabled));
937                    }
938                    if (enabledComponents.size() > 0) {
939                        serializer.startTag(null, TAG_ENABLED_COMPONENTS);
940                        for (final String name : enabledComponents) {
941                            serializer.startTag(null, TAG_ITEM);
942                            serializer.attribute(null, ATTR_NAME, name);
943                            serializer.endTag(null, TAG_ITEM);
944                        }
945                        serializer.endTag(null, TAG_ENABLED_COMPONENTS);
946                    }
947                    if (disabledComponents.size() > 0) {
948                        serializer.startTag(null, TAG_DISABLED_COMPONENTS);
949                        for (final String name : disabledComponents) {
950                            serializer.startTag(null, TAG_ITEM);
951                            serializer.attribute(null, ATTR_NAME, name);
952                            serializer.endTag(null, TAG_ITEM);
953                        }
954                        serializer.endTag(null, TAG_DISABLED_COMPONENTS);
955                    }
956                    serializer.endTag(null, TAG_PACKAGE);
957                }
958            }
959
960            serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
961
962            serializer.endDocument();
963
964            str.flush();
965            FileUtils.sync(fstr);
966            str.close();
967
968            // New settings successfully written, old ones are no longer
969            // needed.
970            backupFile.delete();
971            FileUtils.setPermissions(userPackagesStateFile.toString(),
972                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
973                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
974                    -1, -1);
975
976            // Done, all is good!
977            return;
978        } catch(java.io.IOException e) {
979            Log.wtf(PackageManagerService.TAG,
980                    "Unable to write package manager user packages state, "
981                    + " current changes will be lost at reboot", e);
982        }
983
984        // Clean up partially written files
985        if (userPackagesStateFile.exists()) {
986            if (!userPackagesStateFile.delete()) {
987                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
988                        + mStoppedPackagesFilename);
989            }
990        }
991    }
992
993    // Note: assumed "stopped" field is already cleared in all packages.
994    // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
995    void readStoppedLPw() {
996        FileInputStream str = null;
997        if (mBackupStoppedPackagesFilename.exists()) {
998            try {
999                str = new FileInputStream(mBackupStoppedPackagesFilename);
1000                mReadMessages.append("Reading from backup stopped packages file\n");
1001                PackageManagerService.reportSettingsProblem(Log.INFO,
1002                        "Need to read from backup stopped packages file");
1003                if (mSettingsFilename.exists()) {
1004                    // If both the backup and normal file exist, we
1005                    // ignore the normal one since it might have been
1006                    // corrupted.
1007                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1008                            + mStoppedPackagesFilename);
1009                    mStoppedPackagesFilename.delete();
1010                }
1011            } catch (java.io.IOException e) {
1012                // We'll try for the normal settings file.
1013            }
1014        }
1015
1016        try {
1017            if (str == null) {
1018                if (!mStoppedPackagesFilename.exists()) {
1019                    mReadMessages.append("No stopped packages file found\n");
1020                    PackageManagerService.reportSettingsProblem(Log.INFO,
1021                            "No stopped packages file file; assuming all started");
1022                    // At first boot, make sure no packages are stopped.
1023                    // We usually want to have third party apps initialize
1024                    // in the stopped state, but not at first boot.
1025                    for (PackageSetting pkg : mPackages.values()) {
1026                        pkg.setStopped(false, 0);
1027                        pkg.setNotLaunched(false, 0);
1028                    }
1029                    return;
1030                }
1031                str = new FileInputStream(mStoppedPackagesFilename);
1032            }
1033            final XmlPullParser parser = Xml.newPullParser();
1034            parser.setInput(str, null);
1035
1036            int type;
1037            while ((type=parser.next()) != XmlPullParser.START_TAG
1038                       && type != XmlPullParser.END_DOCUMENT) {
1039                ;
1040            }
1041
1042            if (type != XmlPullParser.START_TAG) {
1043                mReadMessages.append("No start tag found in stopped packages file\n");
1044                PackageManagerService.reportSettingsProblem(Log.WARN,
1045                        "No start tag found in package manager stopped packages");
1046                return;
1047            }
1048
1049            int outerDepth = parser.getDepth();
1050            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1051                   && (type != XmlPullParser.END_TAG
1052                           || parser.getDepth() > outerDepth)) {
1053                if (type == XmlPullParser.END_TAG
1054                        || type == XmlPullParser.TEXT) {
1055                    continue;
1056                }
1057
1058                String tagName = parser.getName();
1059                if (tagName.equals(TAG_PACKAGE)) {
1060                    String name = parser.getAttributeValue(null, ATTR_NAME);
1061                    PackageSetting ps = mPackages.get(name);
1062                    if (ps != null) {
1063                        ps.setStopped(true, 0);
1064                        if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
1065                            ps.setNotLaunched(true, 0);
1066                        }
1067                    } else {
1068                        Slog.w(PackageManagerService.TAG,
1069                                "No package known for stopped package: " + name);
1070                    }
1071                    XmlUtils.skipCurrentTag(parser);
1072                } else {
1073                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1074                          + parser.getName());
1075                    XmlUtils.skipCurrentTag(parser);
1076                }
1077            }
1078
1079            str.close();
1080
1081        } catch (XmlPullParserException e) {
1082            mReadMessages.append("Error reading: " + e.toString());
1083            PackageManagerService.reportSettingsProblem(Log.ERROR,
1084                    "Error reading stopped packages: " + e);
1085            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1086
1087        } catch (java.io.IOException e) {
1088            mReadMessages.append("Error reading: " + e.toString());
1089            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1090            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
1091
1092        }
1093    }
1094
1095    void writeLPr() {
1096        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
1097
1098        // Keep the old settings around until we know the new ones have
1099        // been successfully written.
1100        if (mSettingsFilename.exists()) {
1101            // Presence of backup settings file indicates that we failed
1102            // to persist settings earlier. So preserve the older
1103            // backup for future reference since the current settings
1104            // might have been corrupted.
1105            if (!mBackupSettingsFilename.exists()) {
1106                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
1107                    Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
1108                            + " current changes will be lost at reboot");
1109                    return;
1110                }
1111            } else {
1112                mSettingsFilename.delete();
1113                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
1114            }
1115        }
1116
1117        mPastSignatures.clear();
1118
1119        try {
1120            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
1121            BufferedOutputStream str = new BufferedOutputStream(fstr);
1122
1123            //XmlSerializer serializer = XmlUtils.serializerInstance();
1124            XmlSerializer serializer = new FastXmlSerializer();
1125            serializer.setOutput(str, "utf-8");
1126            serializer.startDocument(null, true);
1127            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1128
1129            serializer.startTag(null, "packages");
1130
1131            serializer.startTag(null, "last-platform-version");
1132            serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
1133            serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
1134            serializer.endTag(null, "last-platform-version");
1135
1136            if (mVerifierDeviceIdentity != null) {
1137                serializer.startTag(null, "verifier");
1138                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
1139                serializer.endTag(null, "verifier");
1140            }
1141
1142            if (mReadExternalStorageEnforced
1143                    != PackageManager.DEFAULT_ENFORCE_READ_EXTERNAL_STORAGE) {
1144                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
1145                serializer.attribute(
1146                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
1147                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
1148            }
1149
1150            serializer.startTag(null, "permission-trees");
1151            for (BasePermission bp : mPermissionTrees.values()) {
1152                writePermissionLPr(serializer, bp);
1153            }
1154            serializer.endTag(null, "permission-trees");
1155
1156            serializer.startTag(null, "permissions");
1157            for (BasePermission bp : mPermissions.values()) {
1158                writePermissionLPr(serializer, bp);
1159            }
1160            serializer.endTag(null, "permissions");
1161
1162            for (final PackageSetting pkg : mPackages.values()) {
1163                writePackageLPr(serializer, pkg);
1164            }
1165
1166            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
1167                writeDisabledSysPackageLPr(serializer, pkg);
1168            }
1169
1170            serializer.startTag(null, "preferred-activities");
1171            for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
1172                serializer.startTag(null, TAG_ITEM);
1173                pa.writeToXml(serializer);
1174                serializer.endTag(null, TAG_ITEM);
1175            }
1176            serializer.endTag(null, "preferred-activities");
1177
1178            for (final SharedUserSetting usr : mSharedUsers.values()) {
1179                serializer.startTag(null, "shared-user");
1180                serializer.attribute(null, ATTR_NAME, usr.name);
1181                serializer.attribute(null, "userId",
1182                        Integer.toString(usr.userId));
1183                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
1184                serializer.startTag(null, "perms");
1185                for (String name : usr.grantedPermissions) {
1186                    serializer.startTag(null, TAG_ITEM);
1187                    serializer.attribute(null, ATTR_NAME, name);
1188                    serializer.endTag(null, TAG_ITEM);
1189                }
1190                serializer.endTag(null, "perms");
1191                serializer.endTag(null, "shared-user");
1192            }
1193
1194            if (mPackagesToBeCleaned.size() > 0) {
1195                for (int i=0; i<mPackagesToBeCleaned.size(); i++) {
1196                    serializer.startTag(null, "cleaning-package");
1197                    serializer.attribute(null, ATTR_NAME, mPackagesToBeCleaned.get(i));
1198                    serializer.endTag(null, "cleaning-package");
1199                }
1200            }
1201
1202            if (mRenamedPackages.size() > 0) {
1203                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
1204                    serializer.startTag(null, "renamed-package");
1205                    serializer.attribute(null, "new", e.getKey());
1206                    serializer.attribute(null, "old", e.getValue());
1207                    serializer.endTag(null, "renamed-package");
1208                }
1209            }
1210
1211            serializer.endTag(null, "packages");
1212
1213            serializer.endDocument();
1214
1215            str.flush();
1216            FileUtils.sync(fstr);
1217            str.close();
1218
1219            // New settings successfully written, old ones are no longer
1220            // needed.
1221            mBackupSettingsFilename.delete();
1222            FileUtils.setPermissions(mSettingsFilename.toString(),
1223                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1224                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1225                    -1, -1);
1226
1227            // Write package list file now, use a JournaledFile.
1228            //
1229            File tempFile = new File(mPackageListFilename.toString() + ".tmp");
1230            JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
1231
1232            fstr = new FileOutputStream(journal.chooseForWrite());
1233            str = new BufferedOutputStream(fstr);
1234            try {
1235                StringBuilder sb = new StringBuilder();
1236                for (final PackageSetting pkg : mPackages.values()) {
1237                    ApplicationInfo ai = pkg.pkg.applicationInfo;
1238                    String dataPath = ai.dataDir;
1239                    boolean isDebug  = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1240
1241                    // Avoid any application that has a space in its path
1242                    // or that is handled by the system.
1243                    if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID)
1244                        continue;
1245
1246                    // we store on each line the following information for now:
1247                    //
1248                    // pkgName    - package name
1249                    // userId     - application-specific user id
1250                    // debugFlag  - 0 or 1 if the package is debuggable.
1251                    // dataPath   - path to package's data path
1252                    //
1253                    // NOTE: We prefer not to expose all ApplicationInfo flags for now.
1254                    //
1255                    // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
1256                    // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
1257                    //   system/core/run-as/run-as.c
1258                    //
1259                    sb.setLength(0);
1260                    sb.append(ai.packageName);
1261                    sb.append(" ");
1262                    sb.append((int)ai.uid);
1263                    sb.append(isDebug ? " 1 " : " 0 ");
1264                    sb.append(dataPath);
1265                    sb.append("\n");
1266                    str.write(sb.toString().getBytes());
1267                }
1268                str.flush();
1269                FileUtils.sync(fstr);
1270                str.close();
1271                journal.commit();
1272            } catch (Exception e) {
1273                IoUtils.closeQuietly(str);
1274                journal.rollback();
1275            }
1276
1277            FileUtils.setPermissions(mPackageListFilename.toString(),
1278                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1279                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1280                    -1, -1);
1281
1282            writeAllUsersPackageRestrictionsLPr();
1283            return;
1284
1285        } catch(XmlPullParserException e) {
1286            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1287                    + "current changes will be lost at reboot", e);
1288        } catch(java.io.IOException e) {
1289            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1290                    + "current changes will be lost at reboot", e);
1291        }
1292        // Clean up partially written files
1293        if (mSettingsFilename.exists()) {
1294            if (!mSettingsFilename.delete()) {
1295                Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
1296                        + mSettingsFilename);
1297            }
1298        }
1299        //Debug.stopMethodTracing();
1300    }
1301
1302    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1303            throws java.io.IOException {
1304        serializer.startTag(null, "updated-package");
1305        serializer.attribute(null, ATTR_NAME, pkg.name);
1306        if (pkg.realName != null) {
1307            serializer.attribute(null, "realName", pkg.realName);
1308        }
1309        serializer.attribute(null, "codePath", pkg.codePathString);
1310        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1311        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1312        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1313        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1314        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1315            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1316        }
1317        if (pkg.nativeLibraryPathString != null) {
1318            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1319        }
1320        if (pkg.sharedUser == null) {
1321            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1322        } else {
1323            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1324        }
1325        serializer.startTag(null, "perms");
1326        if (pkg.sharedUser == null) {
1327            // If this is a shared user, the permissions will
1328            // be written there. We still need to write an
1329            // empty permissions list so permissionsFixed will
1330            // be set.
1331            for (final String name : pkg.grantedPermissions) {
1332                BasePermission bp = mPermissions.get(name);
1333                if (bp != null) {
1334                    // We only need to write signature or system permissions but
1335                    // this wont
1336                    // match the semantics of grantedPermissions. So write all
1337                    // permissions.
1338                    serializer.startTag(null, TAG_ITEM);
1339                    serializer.attribute(null, ATTR_NAME, name);
1340                    serializer.endTag(null, TAG_ITEM);
1341                }
1342            }
1343        }
1344        serializer.endTag(null, "perms");
1345        serializer.endTag(null, "updated-package");
1346    }
1347
1348    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1349            throws java.io.IOException {
1350        serializer.startTag(null, "package");
1351        serializer.attribute(null, ATTR_NAME, pkg.name);
1352        if (pkg.realName != null) {
1353            serializer.attribute(null, "realName", pkg.realName);
1354        }
1355        serializer.attribute(null, "codePath", pkg.codePathString);
1356        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1357            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1358        }
1359        if (pkg.nativeLibraryPathString != null) {
1360            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1361        }
1362        serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1363        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1364        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1365        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1366        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1367        if (pkg.sharedUser == null) {
1368            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1369        } else {
1370            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1371        }
1372        if (pkg.uidError) {
1373            serializer.attribute(null, "uidError", "true");
1374        }
1375        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1376            serializer.attribute(null, "installStatus", "false");
1377        }
1378        if (pkg.installerPackageName != null) {
1379            serializer.attribute(null, "installer", pkg.installerPackageName);
1380        }
1381        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1382        if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1383            serializer.startTag(null, "perms");
1384            if (pkg.sharedUser == null) {
1385                // If this is a shared user, the permissions will
1386                // be written there. We still need to write an
1387                // empty permissions list so permissionsFixed will
1388                // be set.
1389                for (final String name : pkg.grantedPermissions) {
1390                    serializer.startTag(null, TAG_ITEM);
1391                    serializer.attribute(null, ATTR_NAME, name);
1392                    serializer.endTag(null, TAG_ITEM);
1393                }
1394            }
1395            serializer.endTag(null, "perms");
1396        }
1397
1398        serializer.endTag(null, "package");
1399    }
1400
1401    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1402            throws XmlPullParserException, java.io.IOException {
1403        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1404            serializer.startTag(null, TAG_ITEM);
1405            serializer.attribute(null, ATTR_NAME, bp.name);
1406            serializer.attribute(null, "package", bp.sourcePackage);
1407            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1408                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1409            }
1410            if (PackageManagerService.DEBUG_SETTINGS)
1411                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1412                        + bp.type);
1413            if (bp.type == BasePermission.TYPE_DYNAMIC) {
1414                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1415                if (pi != null) {
1416                    serializer.attribute(null, "type", "dynamic");
1417                    if (pi.icon != 0) {
1418                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
1419                    }
1420                    if (pi.nonLocalizedLabel != null) {
1421                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1422                    }
1423                }
1424            }
1425            serializer.endTag(null, TAG_ITEM);
1426        }
1427    }
1428
1429    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
1430        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
1431        final Iterator<String> its = kList.iterator();
1432        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
1433        while (its.hasNext()) {
1434            final String key = its.next();
1435            final PackageSetting ps = mPackages.get(key);
1436            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1437                ret.add(ps);
1438            }
1439        }
1440        return ret;
1441    }
1442
1443    boolean readLPw(List<UserInfo> users) {
1444        FileInputStream str = null;
1445        if (mBackupSettingsFilename.exists()) {
1446            try {
1447                str = new FileInputStream(mBackupSettingsFilename);
1448                mReadMessages.append("Reading from backup settings file\n");
1449                PackageManagerService.reportSettingsProblem(Log.INFO,
1450                        "Need to read from backup settings file");
1451                if (mSettingsFilename.exists()) {
1452                    // If both the backup and settings file exist, we
1453                    // ignore the settings since it might have been
1454                    // corrupted.
1455                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
1456                            + mSettingsFilename);
1457                    mSettingsFilename.delete();
1458                }
1459            } catch (java.io.IOException e) {
1460                // We'll try for the normal settings file.
1461            }
1462        }
1463
1464        mPendingPackages.clear();
1465        mPastSignatures.clear();
1466
1467        try {
1468            if (str == null) {
1469                if (!mSettingsFilename.exists()) {
1470                    mReadMessages.append("No settings file found\n");
1471                    PackageManagerService.reportSettingsProblem(Log.INFO,
1472                            "No settings file; creating initial state");
1473                    return false;
1474                }
1475                str = new FileInputStream(mSettingsFilename);
1476            }
1477            XmlPullParser parser = Xml.newPullParser();
1478            parser.setInput(str, null);
1479
1480            int type;
1481            while ((type = parser.next()) != XmlPullParser.START_TAG
1482                    && type != XmlPullParser.END_DOCUMENT) {
1483                ;
1484            }
1485
1486            if (type != XmlPullParser.START_TAG) {
1487                mReadMessages.append("No start tag found in settings file\n");
1488                PackageManagerService.reportSettingsProblem(Log.WARN,
1489                        "No start tag found in package manager settings");
1490                Log.wtf(PackageManagerService.TAG,
1491                        "No start tag found in package manager settings");
1492                return false;
1493            }
1494
1495            int outerDepth = parser.getDepth();
1496            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1497                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1498                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1499                    continue;
1500                }
1501
1502                String tagName = parser.getName();
1503                if (tagName.equals("package")) {
1504                    readPackageLPw(parser);
1505                } else if (tagName.equals("permissions")) {
1506                    readPermissionsLPw(mPermissions, parser);
1507                } else if (tagName.equals("permission-trees")) {
1508                    readPermissionsLPw(mPermissionTrees, parser);
1509                } else if (tagName.equals("shared-user")) {
1510                    readSharedUserLPw(parser);
1511                } else if (tagName.equals("preferred-packages")) {
1512                    // no longer used.
1513                } else if (tagName.equals("preferred-activities")) {
1514                    readPreferredActivitiesLPw(parser);
1515                } else if (tagName.equals("updated-package")) {
1516                    readDisabledSysPackageLPw(parser);
1517                } else if (tagName.equals("cleaning-package")) {
1518                    String name = parser.getAttributeValue(null, ATTR_NAME);
1519                    if (name != null) {
1520                        mPackagesToBeCleaned.add(name);
1521                    }
1522                } else if (tagName.equals("renamed-package")) {
1523                    String nname = parser.getAttributeValue(null, "new");
1524                    String oname = parser.getAttributeValue(null, "old");
1525                    if (nname != null && oname != null) {
1526                        mRenamedPackages.put(nname, oname);
1527                    }
1528                } else if (tagName.equals("last-platform-version")) {
1529                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
1530                    try {
1531                        String internal = parser.getAttributeValue(null, "internal");
1532                        if (internal != null) {
1533                            mInternalSdkPlatform = Integer.parseInt(internal);
1534                        }
1535                        String external = parser.getAttributeValue(null, "external");
1536                        if (external != null) {
1537                            mExternalSdkPlatform = Integer.parseInt(external);
1538                        }
1539                    } catch (NumberFormatException e) {
1540                    }
1541                } else if (tagName.equals("verifier")) {
1542                    final String deviceIdentity = parser.getAttributeValue(null, "device");
1543                    try {
1544                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
1545                    } catch (IllegalArgumentException e) {
1546                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
1547                                + e.getMessage());
1548                    }
1549                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
1550                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
1551                    mReadExternalStorageEnforced = "1".equals(enforcement);
1552                } else {
1553                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
1554                            + parser.getName());
1555                    XmlUtils.skipCurrentTag(parser);
1556                }
1557            }
1558
1559            str.close();
1560
1561        } catch (XmlPullParserException e) {
1562            mReadMessages.append("Error reading: " + e.toString());
1563            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1564            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1565
1566        } catch (java.io.IOException e) {
1567            mReadMessages.append("Error reading: " + e.toString());
1568            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1569            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1570
1571        }
1572
1573        final int N = mPendingPackages.size();
1574        for (int i = 0; i < N; i++) {
1575            final PendingPackage pp = mPendingPackages.get(i);
1576            Object idObj = getUserIdLPr(pp.sharedId);
1577            if (idObj != null && idObj instanceof SharedUserSetting) {
1578                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
1579                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
1580                        pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags, true, true);
1581                if (p == null) {
1582                    PackageManagerService.reportSettingsProblem(Log.WARN,
1583                            "Unable to create application package for " + pp.name);
1584                    continue;
1585                }
1586                p.copyFrom(pp);
1587            } else if (idObj != null) {
1588                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1589                        + pp.sharedId + " that is not a shared uid\n";
1590                mReadMessages.append(msg);
1591                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1592            } else {
1593                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1594                        + pp.sharedId + " that is not defined\n";
1595                mReadMessages.append(msg);
1596                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1597            }
1598        }
1599        mPendingPackages.clear();
1600
1601        /*
1602         * Make sure all the updated system packages have their shared users
1603         * associated with them.
1604         */
1605        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
1606        while (disabledIt.hasNext()) {
1607            final PackageSetting disabledPs = disabledIt.next();
1608            final Object id = getUserIdLPr(disabledPs.appId);
1609            if (id != null && id instanceof SharedUserSetting) {
1610                disabledPs.sharedUser = (SharedUserSetting) id;
1611            }
1612        }
1613
1614        if (mBackupStoppedPackagesFilename.exists()
1615                || mStoppedPackagesFilename.exists()) {
1616            // Read old file
1617            readStoppedLPw();
1618            mBackupStoppedPackagesFilename.delete();
1619            mStoppedPackagesFilename.delete();
1620            // Migrate to new file format
1621            writePackageRestrictionsLPr(0);
1622        } else {
1623            if (users == null) {
1624                readPackageRestrictionsLPr(0);
1625            } else {
1626                for (UserInfo user : users) {
1627                    readPackageRestrictionsLPr(user.id);
1628                }
1629            }
1630        }
1631        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
1632                + mSharedUsers.size() + " shared uids\n");
1633
1634        return true;
1635    }
1636
1637    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
1638        String v = parser.getAttributeValue(ns, name);
1639        try {
1640            if (v == null) {
1641                return defValue;
1642            }
1643            return Integer.parseInt(v);
1644        } catch (NumberFormatException e) {
1645            PackageManagerService.reportSettingsProblem(Log.WARN,
1646                    "Error in package manager settings: attribute " + name
1647                            + " has bad integer value " + v + " at "
1648                            + parser.getPositionDescription());
1649        }
1650        return defValue;
1651    }
1652
1653    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
1654            throws IOException, XmlPullParserException {
1655        int outerDepth = parser.getDepth();
1656        int type;
1657        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1658                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1659            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1660                continue;
1661            }
1662
1663            final String tagName = parser.getName();
1664            if (tagName.equals(TAG_ITEM)) {
1665                final String name = parser.getAttributeValue(null, ATTR_NAME);
1666                final String sourcePackage = parser.getAttributeValue(null, "package");
1667                final String ptype = parser.getAttributeValue(null, "type");
1668                if (name != null && sourcePackage != null) {
1669                    final boolean dynamic = "dynamic".equals(ptype);
1670                    final BasePermission bp = new BasePermission(name, sourcePackage,
1671                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
1672                    bp.protectionLevel = readInt(parser, null, "protection",
1673                            PermissionInfo.PROTECTION_NORMAL);
1674                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
1675                    if (dynamic) {
1676                        PermissionInfo pi = new PermissionInfo();
1677                        pi.packageName = sourcePackage.intern();
1678                        pi.name = name.intern();
1679                        pi.icon = readInt(parser, null, "icon", 0);
1680                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
1681                        pi.protectionLevel = bp.protectionLevel;
1682                        bp.pendingInfo = pi;
1683                    }
1684                    out.put(bp.name, bp);
1685                } else {
1686                    PackageManagerService.reportSettingsProblem(Log.WARN,
1687                            "Error in package manager settings: permissions has" + " no name at "
1688                                    + parser.getPositionDescription());
1689                }
1690            } else {
1691                PackageManagerService.reportSettingsProblem(Log.WARN,
1692                        "Unknown element reading permissions: " + parser.getName() + " at "
1693                                + parser.getPositionDescription());
1694            }
1695            XmlUtils.skipCurrentTag(parser);
1696        }
1697    }
1698
1699    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
1700            IOException {
1701        String name = parser.getAttributeValue(null, ATTR_NAME);
1702        String realName = parser.getAttributeValue(null, "realName");
1703        String codePathStr = parser.getAttributeValue(null, "codePath");
1704        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
1705        String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
1706        if (resourcePathStr == null) {
1707            resourcePathStr = codePathStr;
1708        }
1709        String version = parser.getAttributeValue(null, "version");
1710        int versionCode = 0;
1711        if (version != null) {
1712            try {
1713                versionCode = Integer.parseInt(version);
1714            } catch (NumberFormatException e) {
1715            }
1716        }
1717
1718        int pkgFlags = 0;
1719        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1720        PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
1721                new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
1722        String timeStampStr = parser.getAttributeValue(null, "ft");
1723        if (timeStampStr != null) {
1724            try {
1725                long timeStamp = Long.parseLong(timeStampStr, 16);
1726                ps.setTimeStamp(timeStamp);
1727            } catch (NumberFormatException e) {
1728            }
1729        } else {
1730            timeStampStr = parser.getAttributeValue(null, "ts");
1731            if (timeStampStr != null) {
1732                try {
1733                    long timeStamp = Long.parseLong(timeStampStr);
1734                    ps.setTimeStamp(timeStamp);
1735                } catch (NumberFormatException e) {
1736                }
1737            }
1738        }
1739        timeStampStr = parser.getAttributeValue(null, "it");
1740        if (timeStampStr != null) {
1741            try {
1742                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
1743            } catch (NumberFormatException e) {
1744            }
1745        }
1746        timeStampStr = parser.getAttributeValue(null, "ut");
1747        if (timeStampStr != null) {
1748            try {
1749                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
1750            } catch (NumberFormatException e) {
1751            }
1752        }
1753        String idStr = parser.getAttributeValue(null, "userId");
1754        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
1755        if (ps.appId <= 0) {
1756            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
1757            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
1758        }
1759        int outerDepth = parser.getDepth();
1760        int type;
1761        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1762                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1763            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1764                continue;
1765            }
1766
1767            String tagName = parser.getName();
1768            if (tagName.equals("perms")) {
1769                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
1770            } else {
1771                PackageManagerService.reportSettingsProblem(Log.WARN,
1772                        "Unknown element under <updated-package>: " + parser.getName());
1773                XmlUtils.skipCurrentTag(parser);
1774            }
1775        }
1776        mDisabledSysPackages.put(name, ps);
1777    }
1778
1779    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
1780        String name = null;
1781        String realName = null;
1782        String idStr = null;
1783        String sharedIdStr = null;
1784        String codePathStr = null;
1785        String resourcePathStr = null;
1786        String nativeLibraryPathStr = null;
1787        String systemStr = null;
1788        String installerPackageName = null;
1789        String uidError = null;
1790        int pkgFlags = 0;
1791        long timeStamp = 0;
1792        long firstInstallTime = 0;
1793        long lastUpdateTime = 0;
1794        PackageSettingBase packageSetting = null;
1795        String version = null;
1796        int versionCode = 0;
1797        try {
1798            name = parser.getAttributeValue(null, ATTR_NAME);
1799            realName = parser.getAttributeValue(null, "realName");
1800            idStr = parser.getAttributeValue(null, "userId");
1801            uidError = parser.getAttributeValue(null, "uidError");
1802            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
1803            codePathStr = parser.getAttributeValue(null, "codePath");
1804            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
1805            nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
1806            version = parser.getAttributeValue(null, "version");
1807            if (version != null) {
1808                try {
1809                    versionCode = Integer.parseInt(version);
1810                } catch (NumberFormatException e) {
1811                }
1812            }
1813            installerPackageName = parser.getAttributeValue(null, "installer");
1814
1815            systemStr = parser.getAttributeValue(null, "flags");
1816            if (systemStr != null) {
1817                try {
1818                    pkgFlags = Integer.parseInt(systemStr);
1819                } catch (NumberFormatException e) {
1820                }
1821            } else {
1822                // For backward compatibility
1823                systemStr = parser.getAttributeValue(null, "system");
1824                if (systemStr != null) {
1825                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
1826                            : 0;
1827                } else {
1828                    // Old settings that don't specify system... just treat
1829                    // them as system, good enough.
1830                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1831                }
1832            }
1833            String timeStampStr = parser.getAttributeValue(null, "ft");
1834            if (timeStampStr != null) {
1835                try {
1836                    timeStamp = Long.parseLong(timeStampStr, 16);
1837                } catch (NumberFormatException e) {
1838                }
1839            } else {
1840                timeStampStr = parser.getAttributeValue(null, "ts");
1841                if (timeStampStr != null) {
1842                    try {
1843                        timeStamp = Long.parseLong(timeStampStr);
1844                    } catch (NumberFormatException e) {
1845                    }
1846                }
1847            }
1848            timeStampStr = parser.getAttributeValue(null, "it");
1849            if (timeStampStr != null) {
1850                try {
1851                    firstInstallTime = Long.parseLong(timeStampStr, 16);
1852                } catch (NumberFormatException e) {
1853                }
1854            }
1855            timeStampStr = parser.getAttributeValue(null, "ut");
1856            if (timeStampStr != null) {
1857                try {
1858                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
1859                } catch (NumberFormatException e) {
1860                }
1861            }
1862            if (PackageManagerService.DEBUG_SETTINGS)
1863                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
1864                        + " sharedUserId=" + sharedIdStr);
1865            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
1866            if (resourcePathStr == null) {
1867                resourcePathStr = codePathStr;
1868            }
1869            if (realName != null) {
1870                realName = realName.intern();
1871            }
1872            if (name == null) {
1873                PackageManagerService.reportSettingsProblem(Log.WARN,
1874                        "Error in package manager settings: <package> has no name at "
1875                                + parser.getPositionDescription());
1876            } else if (codePathStr == null) {
1877                PackageManagerService.reportSettingsProblem(Log.WARN,
1878                        "Error in package manager settings: <package> has no codePath at "
1879                                + parser.getPositionDescription());
1880            } else if (userId > 0) {
1881                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
1882                        new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
1883                        pkgFlags);
1884                if (PackageManagerService.DEBUG_SETTINGS)
1885                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
1886                            + userId + " pkg=" + packageSetting);
1887                if (packageSetting == null) {
1888                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
1889                            + userId + " while parsing settings at "
1890                            + parser.getPositionDescription());
1891                } else {
1892                    packageSetting.setTimeStamp(timeStamp);
1893                    packageSetting.firstInstallTime = firstInstallTime;
1894                    packageSetting.lastUpdateTime = lastUpdateTime;
1895                }
1896            } else if (sharedIdStr != null) {
1897                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
1898                if (userId > 0) {
1899                    packageSetting = new PendingPackage(name.intern(), realName, new File(
1900                            codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
1901                            versionCode, pkgFlags);
1902                    packageSetting.setTimeStamp(timeStamp);
1903                    packageSetting.firstInstallTime = firstInstallTime;
1904                    packageSetting.lastUpdateTime = lastUpdateTime;
1905                    mPendingPackages.add((PendingPackage) packageSetting);
1906                    if (PackageManagerService.DEBUG_SETTINGS)
1907                        Log.i(PackageManagerService.TAG, "Reading package " + name
1908                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
1909                } else {
1910                    PackageManagerService.reportSettingsProblem(Log.WARN,
1911                            "Error in package manager settings: package " + name
1912                                    + " has bad sharedId " + sharedIdStr + " at "
1913                                    + parser.getPositionDescription());
1914                }
1915            } else {
1916                PackageManagerService.reportSettingsProblem(Log.WARN,
1917                        "Error in package manager settings: package " + name + " has bad userId "
1918                                + idStr + " at " + parser.getPositionDescription());
1919            }
1920        } catch (NumberFormatException e) {
1921            PackageManagerService.reportSettingsProblem(Log.WARN,
1922                    "Error in package manager settings: package " + name + " has bad userId "
1923                            + idStr + " at " + parser.getPositionDescription());
1924        }
1925        if (packageSetting != null) {
1926            packageSetting.uidError = "true".equals(uidError);
1927            packageSetting.installerPackageName = installerPackageName;
1928            packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
1929            // Handle legacy string here for single-user mode
1930            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
1931            if (enabledStr != null) {
1932                try {
1933                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */);
1934                } catch (NumberFormatException e) {
1935                    if (enabledStr.equalsIgnoreCase("true")) {
1936                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0);
1937                    } else if (enabledStr.equalsIgnoreCase("false")) {
1938                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0);
1939                    } else if (enabledStr.equalsIgnoreCase("default")) {
1940                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0);
1941                    } else {
1942                        PackageManagerService.reportSettingsProblem(Log.WARN,
1943                                "Error in package manager settings: package " + name
1944                                        + " has bad enabled value: " + idStr + " at "
1945                                        + parser.getPositionDescription());
1946                    }
1947                }
1948            } else {
1949                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0);
1950            }
1951
1952            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
1953            if (installStatusStr != null) {
1954                if (installStatusStr.equalsIgnoreCase("false")) {
1955                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
1956                } else {
1957                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
1958                }
1959            }
1960
1961            int outerDepth = parser.getDepth();
1962            int type;
1963            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1964                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1965                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1966                    continue;
1967                }
1968
1969                String tagName = parser.getName();
1970                // Legacy
1971                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
1972                    readDisabledComponentsLPw(packageSetting, parser, 0);
1973                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
1974                    readEnabledComponentsLPw(packageSetting, parser, 0);
1975                } else if (tagName.equals("sigs")) {
1976                    packageSetting.signatures.readXml(parser, mPastSignatures);
1977                } else if (tagName.equals("perms")) {
1978                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
1979                    packageSetting.permissionsFixed = true;
1980                } else {
1981                    PackageManagerService.reportSettingsProblem(Log.WARN,
1982                            "Unknown element under <package>: " + parser.getName());
1983                    XmlUtils.skipCurrentTag(parser);
1984                }
1985            }
1986        } else {
1987            XmlUtils.skipCurrentTag(parser);
1988        }
1989    }
1990
1991    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
1992            int userId) throws IOException, XmlPullParserException {
1993        int outerDepth = parser.getDepth();
1994        int type;
1995        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1996                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1997            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1998                continue;
1999            }
2000
2001            String tagName = parser.getName();
2002            if (tagName.equals(TAG_ITEM)) {
2003                String name = parser.getAttributeValue(null, ATTR_NAME);
2004                if (name != null) {
2005                    packageSetting.addDisabledComponent(name.intern(), userId);
2006                } else {
2007                    PackageManagerService.reportSettingsProblem(Log.WARN,
2008                            "Error in package manager settings: <disabled-components> has"
2009                                    + " no name at " + parser.getPositionDescription());
2010                }
2011            } else {
2012                PackageManagerService.reportSettingsProblem(Log.WARN,
2013                        "Unknown element under <disabled-components>: " + parser.getName());
2014            }
2015            XmlUtils.skipCurrentTag(parser);
2016        }
2017    }
2018
2019    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2020            int userId) throws IOException, XmlPullParserException {
2021        int outerDepth = parser.getDepth();
2022        int type;
2023        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2024                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2025            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2026                continue;
2027            }
2028
2029            String tagName = parser.getName();
2030            if (tagName.equals(TAG_ITEM)) {
2031                String name = parser.getAttributeValue(null, ATTR_NAME);
2032                if (name != null) {
2033                    packageSetting.addEnabledComponent(name.intern(), userId);
2034                } else {
2035                    PackageManagerService.reportSettingsProblem(Log.WARN,
2036                            "Error in package manager settings: <enabled-components> has"
2037                                    + " no name at " + parser.getPositionDescription());
2038                }
2039            } else {
2040                PackageManagerService.reportSettingsProblem(Log.WARN,
2041                        "Unknown element under <enabled-components>: " + parser.getName());
2042            }
2043            XmlUtils.skipCurrentTag(parser);
2044        }
2045    }
2046
2047    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
2048        String name = null;
2049        String idStr = null;
2050        int pkgFlags = 0;
2051        SharedUserSetting su = null;
2052        try {
2053            name = parser.getAttributeValue(null, ATTR_NAME);
2054            idStr = parser.getAttributeValue(null, "userId");
2055            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2056            if ("true".equals(parser.getAttributeValue(null, "system"))) {
2057                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2058            }
2059            if (name == null) {
2060                PackageManagerService.reportSettingsProblem(Log.WARN,
2061                        "Error in package manager settings: <shared-user> has no name at "
2062                                + parser.getPositionDescription());
2063            } else if (userId == 0) {
2064                PackageManagerService.reportSettingsProblem(Log.WARN,
2065                        "Error in package manager settings: shared-user " + name
2066                                + " has bad userId " + idStr + " at "
2067                                + parser.getPositionDescription());
2068            } else {
2069                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
2070                    PackageManagerService
2071                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
2072                                    + parser.getPositionDescription());
2073                }
2074            }
2075        } catch (NumberFormatException e) {
2076            PackageManagerService.reportSettingsProblem(Log.WARN,
2077                    "Error in package manager settings: package " + name + " has bad userId "
2078                            + idStr + " at " + parser.getPositionDescription());
2079        }
2080        ;
2081
2082        if (su != null) {
2083            int outerDepth = parser.getDepth();
2084            int type;
2085            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2086                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2087                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2088                    continue;
2089                }
2090
2091                String tagName = parser.getName();
2092                if (tagName.equals("sigs")) {
2093                    su.signatures.readXml(parser, mPastSignatures);
2094                } else if (tagName.equals("perms")) {
2095                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
2096                } else {
2097                    PackageManagerService.reportSettingsProblem(Log.WARN,
2098                            "Unknown element under <shared-user>: " + parser.getName());
2099                    XmlUtils.skipCurrentTag(parser);
2100                }
2101            }
2102
2103        } else {
2104            XmlUtils.skipCurrentTag(parser);
2105        }
2106    }
2107
2108    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
2109            throws IOException, XmlPullParserException {
2110        int outerDepth = parser.getDepth();
2111        int type;
2112        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2113                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2114            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2115                continue;
2116            }
2117
2118            String tagName = parser.getName();
2119            if (tagName.equals(TAG_ITEM)) {
2120                String name = parser.getAttributeValue(null, ATTR_NAME);
2121                if (name != null) {
2122                    outPerms.add(name.intern());
2123                } else {
2124                    PackageManagerService.reportSettingsProblem(Log.WARN,
2125                            "Error in package manager settings: <perms> has" + " no name at "
2126                                    + parser.getPositionDescription());
2127                }
2128            } else {
2129                PackageManagerService.reportSettingsProblem(Log.WARN,
2130                        "Unknown element under <perms>: " + parser.getName());
2131            }
2132            XmlUtils.skipCurrentTag(parser);
2133        }
2134    }
2135
2136    private void readPreferredActivitiesLPw(XmlPullParser parser) throws XmlPullParserException,
2137            IOException {
2138        int outerDepth = parser.getDepth();
2139        int type;
2140        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2141                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2142            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2143                continue;
2144            }
2145
2146            String tagName = parser.getName();
2147            if (tagName.equals(TAG_ITEM)) {
2148                PreferredActivity pa = new PreferredActivity(parser);
2149                if (pa.mPref.getParseError() == null) {
2150                    mPreferredActivities.addFilter(pa);
2151                } else {
2152                    PackageManagerService.reportSettingsProblem(Log.WARN,
2153                            "Error in package manager settings: <preferred-activity> "
2154                                    + pa.mPref.getParseError() + " at "
2155                                    + parser.getPositionDescription());
2156                }
2157            } else {
2158                PackageManagerService.reportSettingsProblem(Log.WARN,
2159                        "Unknown element under <preferred-activities>: " + parser.getName());
2160                XmlUtils.skipCurrentTag(parser);
2161            }
2162        }
2163    }
2164
2165    void removeUserLPr(int userId) {
2166        File file = getUserPackagesStateFile(userId);
2167        file.delete();
2168        file = getUserPackagesStateBackupFile(userId);
2169        file.delete();
2170    }
2171
2172    // Returns -1 if we could not find an available UserId to assign
2173    private int newUserIdLPw(Object obj) {
2174        // Let's be stupidly inefficient for now...
2175        final int N = mUserIds.size();
2176        for (int i = 0; i < N; i++) {
2177            if (mUserIds.get(i) == null) {
2178                mUserIds.set(i, obj);
2179                return Process.FIRST_APPLICATION_UID + i;
2180            }
2181        }
2182
2183        // None left?
2184        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
2185            return -1;
2186        }
2187
2188        mUserIds.add(obj);
2189        return Process.FIRST_APPLICATION_UID + N;
2190    }
2191
2192    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
2193        if (mVerifierDeviceIdentity == null) {
2194            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
2195
2196            writeLPr();
2197        }
2198
2199        return mVerifierDeviceIdentity;
2200    }
2201
2202    public PackageSetting getDisabledSystemPkgLPr(String name) {
2203        PackageSetting ps = mDisabledSysPackages.get(name);
2204        return ps;
2205    }
2206
2207    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
2208        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
2209            return true;
2210        }
2211        final String pkgName = componentInfo.packageName;
2212        final PackageSetting packageSettings = mPackages.get(pkgName);
2213        if (PackageManagerService.DEBUG_SETTINGS) {
2214            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
2215                    + componentInfo.packageName + " componentName = " + componentInfo.name);
2216            Log.v(PackageManagerService.TAG, "enabledComponents: "
2217                    + Arrays.toString(packageSettings.getEnabledComponents(userId).toArray()));
2218            Log.v(PackageManagerService.TAG, "disabledComponents: "
2219                    + Arrays.toString(packageSettings.getDisabledComponents(userId).toArray()));
2220        }
2221        if (packageSettings == null) {
2222            return false;
2223        }
2224        final int enabled = packageSettings.getEnabled(userId);
2225        if (enabled == COMPONENT_ENABLED_STATE_DISABLED
2226                || enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
2227                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
2228                    && enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
2229            return false;
2230        }
2231        if (packageSettings.getEnabledComponents(userId).contains(componentInfo.name)) {
2232            return true;
2233        }
2234        if (packageSettings.getDisabledComponents(userId).contains(componentInfo.name)) {
2235            return false;
2236        }
2237        return componentInfo.enabled;
2238    }
2239
2240    String getInstallerPackageNameLPr(String packageName) {
2241        final PackageSetting pkg = mPackages.get(packageName);
2242        if (pkg == null) {
2243            throw new IllegalArgumentException("Unknown package: " + packageName);
2244        }
2245        return pkg.installerPackageName;
2246    }
2247
2248    int getApplicationEnabledSettingLPr(String packageName, int userId) {
2249        final PackageSetting pkg = mPackages.get(packageName);
2250        if (pkg == null) {
2251            throw new IllegalArgumentException("Unknown package: " + packageName);
2252        }
2253        return pkg.getEnabled(userId);
2254    }
2255
2256    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
2257        final String packageName = componentName.getPackageName();
2258        final PackageSetting pkg = mPackages.get(packageName);
2259        if (pkg == null) {
2260            throw new IllegalArgumentException("Unknown component: " + componentName);
2261        }
2262        final String classNameStr = componentName.getClassName();
2263        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
2264    }
2265
2266    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
2267            boolean allowedByPermission, int uid, int userId) {
2268        int appId = UserId.getAppId(uid);
2269        final PackageSetting pkgSetting = mPackages.get(packageName);
2270        if (pkgSetting == null) {
2271            throw new IllegalArgumentException("Unknown package: " + packageName);
2272        }
2273        if (!allowedByPermission && (appId != pkgSetting.appId)) {
2274            throw new SecurityException(
2275                    "Permission Denial: attempt to change stopped state from pid="
2276                    + Binder.getCallingPid()
2277                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
2278        }
2279        if (DEBUG_STOPPED) {
2280            if (stopped) {
2281                RuntimeException e = new RuntimeException("here");
2282                e.fillInStackTrace();
2283                Slog.i(TAG, "Stopping package " + packageName, e);
2284            }
2285        }
2286        if (pkgSetting.getStopped(userId) != stopped) {
2287            pkgSetting.setStopped(stopped, userId);
2288            // pkgSetting.pkg.mSetStopped = stopped;
2289            if (pkgSetting.getNotLaunched(userId)) {
2290                if (pkgSetting.installerPackageName != null) {
2291                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
2292                            pkgSetting.name, null,
2293                            pkgSetting.installerPackageName, null, userId);
2294                }
2295                pkgSetting.setNotLaunched(false, userId);
2296            }
2297            return true;
2298        }
2299        return false;
2300    }
2301
2302    private List<UserInfo> getAllUsers() {
2303        long id = Binder.clearCallingIdentity();
2304        try {
2305            return AppGlobals.getPackageManager().getUsers();
2306        } catch (RemoteException re) {
2307            // Local to system process, shouldn't happen
2308        } catch (NullPointerException npe) {
2309            // packagemanager not yet initialized
2310        } finally {
2311            Binder.restoreCallingIdentity(id);
2312        }
2313        return null;
2314    }
2315
2316    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
2317        pw.print("[ ");
2318        for (int i=0; i<spec.length; i+=2) {
2319            int mask = (Integer)spec[i];
2320            if ((val & mask) != 0) {
2321                pw.print(spec[i+1]);
2322                pw.print(" ");
2323            }
2324        }
2325        pw.print("]");
2326    }
2327
2328    static final Object[] FLAG_DUMP_SPEC = new Object[] {
2329        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
2330        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
2331        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
2332        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
2333        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
2334        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
2335        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
2336        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
2337        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
2338        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
2339        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
2340        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
2341        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
2342        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
2343        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
2344        ApplicationInfo.FLAG_STOPPED, "STOPPED",
2345        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
2346        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
2347    };
2348
2349    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2350        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2351        final Date date = new Date();
2352        boolean printedSomething = false;
2353        List<UserInfo> users = getAllUsers();
2354        for (final PackageSetting ps : mPackages.values()) {
2355            if (packageName != null && !packageName.equals(ps.realName)
2356                    && !packageName.equals(ps.name)) {
2357                continue;
2358            }
2359
2360            if (packageName != null) {
2361                dumpState.setSharedUser(ps.sharedUser);
2362            }
2363
2364            if (!printedSomething) {
2365                if (dumpState.onTitlePrinted())
2366                    pw.println(" ");
2367                pw.println("Packages:");
2368                printedSomething = true;
2369            }
2370            pw.print("  Package [");
2371                pw.print(ps.realName != null ? ps.realName : ps.name);
2372                pw.print("] (");
2373                pw.print(Integer.toHexString(System.identityHashCode(ps)));
2374                pw.println("):");
2375
2376            if (ps.realName != null) {
2377                pw.print("    compat name=");
2378                pw.println(ps.name);
2379            }
2380
2381            pw.print("    userId="); pw.print(ps.appId);
2382            pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
2383            pw.print("    sharedUser="); pw.println(ps.sharedUser);
2384            pw.print("    pkg="); pw.println(ps.pkg);
2385            pw.print("    codePath="); pw.println(ps.codePathString);
2386            pw.print("    resourcePath="); pw.println(ps.resourcePathString);
2387            pw.print("    nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
2388            pw.print("    versionCode="); pw.println(ps.versionCode);
2389            if (ps.pkg != null) {
2390                pw.print("    flags="); printFlags(pw, ps.pkg.applicationInfo.flags, FLAG_DUMP_SPEC); pw.println();
2391                pw.print("    versionName="); pw.println(ps.pkg.mVersionName);
2392                pw.print("    dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
2393                pw.print("    targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion);
2394                if (ps.pkg.mOperationPending) {
2395                    pw.println("    mOperationPending=true");
2396                }
2397                pw.print("    supportsScreens=[");
2398                boolean first = true;
2399                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
2400                    if (!first)
2401                        pw.print(", ");
2402                    first = false;
2403                    pw.print("small");
2404                }
2405                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
2406                    if (!first)
2407                        pw.print(", ");
2408                    first = false;
2409                    pw.print("medium");
2410                }
2411                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
2412                    if (!first)
2413                        pw.print(", ");
2414                    first = false;
2415                    pw.print("large");
2416                }
2417                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
2418                    if (!first)
2419                        pw.print(", ");
2420                    first = false;
2421                    pw.print("xlarge");
2422                }
2423                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
2424                    if (!first)
2425                        pw.print(", ");
2426                    first = false;
2427                    pw.print("resizeable");
2428                }
2429                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
2430                    if (!first)
2431                        pw.print(", ");
2432                    first = false;
2433                    pw.print("anyDensity");
2434                }
2435            }
2436            pw.println("]");
2437            pw.print("    timeStamp=");
2438                date.setTime(ps.timeStamp);
2439                pw.println(sdf.format(date));
2440            pw.print("    firstInstallTime=");
2441                date.setTime(ps.firstInstallTime);
2442                pw.println(sdf.format(date));
2443            pw.print("    lastUpdateTime=");
2444                date.setTime(ps.lastUpdateTime);
2445                pw.println(sdf.format(date));
2446            if (ps.installerPackageName != null) {
2447                pw.print("    installerPackageName="); pw.println(ps.installerPackageName);
2448            }
2449            pw.print("    signatures="); pw.println(ps.signatures);
2450            pw.print("    permissionsFixed="); pw.print(ps.permissionsFixed);
2451            pw.print(" haveGids="); pw.println(ps.haveGids);
2452            pw.print("    pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
2453            pw.print(" installStatus="); pw.print(ps.installStatus);
2454            for (UserInfo user : users) {
2455                pw.print(" User "); pw.print(user.id); pw.print(": ");
2456                pw.print(" stopped=");
2457                pw.print(ps.getStopped(user.id));
2458                pw.print(" enabled=");
2459                pw.println(ps.getEnabled(user.id));
2460                if (ps.getDisabledComponents(user.id).size() > 0) {
2461                    pw.println("    disabledComponents:");
2462                    for (String s : ps.getDisabledComponents(user.id)) {
2463                        pw.print("      "); pw.println(s);
2464                    }
2465                }
2466                if (ps.getEnabledComponents(user.id).size() > 0) {
2467                    pw.println("    enabledComponents:");
2468                    for (String s : ps.getEnabledComponents(user.id)) {
2469                        pw.print("      "); pw.println(s);
2470                    }
2471                }
2472            }
2473            if (ps.grantedPermissions.size() > 0) {
2474                pw.println("    grantedPermissions:");
2475                for (String s : ps.grantedPermissions) {
2476                    pw.print("      "); pw.println(s);
2477                }
2478            }
2479        }
2480
2481        printedSomething = false;
2482        if (mRenamedPackages.size() > 0) {
2483            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
2484                if (packageName != null && !packageName.equals(e.getKey())
2485                        && !packageName.equals(e.getValue())) {
2486                    continue;
2487                }
2488                if (!printedSomething) {
2489                    if (dumpState.onTitlePrinted())
2490                        pw.println(" ");
2491                    pw.println("Renamed packages:");
2492                    printedSomething = true;
2493                }
2494                pw.print("  ");
2495                pw.print(e.getKey());
2496                pw.print(" -> ");
2497                pw.println(e.getValue());
2498            }
2499        }
2500
2501        printedSomething = false;
2502        if (mDisabledSysPackages.size() > 0) {
2503            for (final PackageSetting ps : mDisabledSysPackages.values()) {
2504                if (packageName != null && !packageName.equals(ps.realName)
2505                        && !packageName.equals(ps.name)) {
2506                    continue;
2507                }
2508                if (!printedSomething) {
2509                    if (dumpState.onTitlePrinted())
2510                        pw.println(" ");
2511                    pw.println("Hidden system packages:");
2512                    printedSomething = true;
2513                }
2514                pw.print("  Package [");
2515                pw.print(ps.realName != null ? ps.realName : ps.name);
2516                pw.print("] (");
2517                pw.print(Integer.toHexString(System.identityHashCode(ps)));
2518                pw.println("):");
2519                if (ps.realName != null) {
2520                    pw.print("    compat name=");
2521                    pw.println(ps.name);
2522                }
2523                pw.print("    userId=");
2524                pw.println(ps.appId);
2525                pw.print("    sharedUser=");
2526                pw.println(ps.sharedUser);
2527                pw.print("    codePath=");
2528                pw.println(ps.codePathString);
2529                pw.print("    resourcePath=");
2530                pw.println(ps.resourcePathString);
2531            }
2532        }
2533    }
2534
2535    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2536        boolean printedSomething = false;
2537        for (BasePermission p : mPermissions.values()) {
2538            if (packageName != null && !packageName.equals(p.sourcePackage)) {
2539                continue;
2540            }
2541            if (!printedSomething) {
2542                if (dumpState.onTitlePrinted())
2543                    pw.println(" ");
2544                pw.println("Permissions:");
2545                printedSomething = true;
2546            }
2547            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
2548                    pw.print(Integer.toHexString(System.identityHashCode(p)));
2549                    pw.println("):");
2550            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
2551            pw.print("    uid="); pw.print(p.uid);
2552                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
2553                    pw.print(" type="); pw.print(p.type);
2554                    pw.print(" prot=");
2555                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
2556            if (p.packageSetting != null) {
2557                pw.print("    packageSetting="); pw.println(p.packageSetting);
2558            }
2559            if (p.perm != null) {
2560                pw.print("    perm="); pw.println(p.perm);
2561            }
2562            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
2563                pw.print("    enforced=");
2564                pw.println(mReadExternalStorageEnforced);
2565            }
2566        }
2567    }
2568
2569    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2570        boolean printedSomething = false;
2571        for (SharedUserSetting su : mSharedUsers.values()) {
2572            if (packageName != null && su != dumpState.getSharedUser()) {
2573                continue;
2574            }
2575            if (!printedSomething) {
2576                if (dumpState.onTitlePrinted())
2577                    pw.println(" ");
2578                pw.println("Shared users:");
2579                printedSomething = true;
2580            }
2581            pw.print("  SharedUser [");
2582            pw.print(su.name);
2583            pw.print("] (");
2584            pw.print(Integer.toHexString(System.identityHashCode(su)));
2585                    pw.println("):");
2586            pw.print("    userId=");
2587            pw.print(su.userId);
2588            pw.print(" gids=");
2589            pw.println(PackageManagerService.arrayToString(su.gids));
2590            pw.println("    grantedPermissions:");
2591            for (String s : su.grantedPermissions) {
2592                pw.print("      ");
2593                pw.println(s);
2594            }
2595        }
2596    }
2597
2598    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
2599        pw.println("Settings parse messages:");
2600        pw.print(mReadMessages.toString());
2601    }
2602}
2603