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