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