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