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