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