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