Settings.java revision af597627cb344a144cbeb0a982e97e282cfd8f82
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                    //
1484                    sb.setLength(0);
1485                    sb.append(ai.packageName);
1486                    sb.append(" ");
1487                    sb.append((int)ai.uid);
1488                    sb.append(isDebug ? " 1 " : " 0 ");
1489                    sb.append(dataPath);
1490                    sb.append(" ");
1491                    sb.append(ai.seinfo);
1492                    sb.append(" ");
1493                    if (gids != null && gids.length > 0) {
1494                        sb.append(gids[0]);
1495                        for (int i = 1; i < gids.length; i++) {
1496                            sb.append(",");
1497                            sb.append(gids[i]);
1498                        }
1499                    } else {
1500                        sb.append("none");
1501                    }
1502                    sb.append("\n");
1503                    str.write(sb.toString().getBytes());
1504                }
1505                str.flush();
1506                FileUtils.sync(fstr);
1507                str.close();
1508                journal.commit();
1509            } catch (Exception e) {
1510                Log.wtf(TAG, "Failed to write packages.list", e);
1511                IoUtils.closeQuietly(str);
1512                journal.rollback();
1513            }
1514
1515            writeAllUsersPackageRestrictionsLPr();
1516            return;
1517
1518        } catch(XmlPullParserException e) {
1519            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1520                    + "current changes will be lost at reboot", e);
1521        } catch(java.io.IOException e) {
1522            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1523                    + "current changes will be lost at reboot", e);
1524        }
1525        // Clean up partially written files
1526        if (mSettingsFilename.exists()) {
1527            if (!mSettingsFilename.delete()) {
1528                Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
1529                        + mSettingsFilename);
1530            }
1531        }
1532        //Debug.stopMethodTracing();
1533    }
1534
1535    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1536            throws java.io.IOException {
1537        serializer.startTag(null, "updated-package");
1538        serializer.attribute(null, ATTR_NAME, pkg.name);
1539        if (pkg.realName != null) {
1540            serializer.attribute(null, "realName", pkg.realName);
1541        }
1542        serializer.attribute(null, "codePath", pkg.codePathString);
1543        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1544        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1545        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1546        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1547        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1548            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1549        }
1550        if (pkg.nativeLibraryPathString != null) {
1551            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1552        }
1553        if (pkg.sharedUser == null) {
1554            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1555        } else {
1556            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1557        }
1558        serializer.startTag(null, "perms");
1559        if (pkg.sharedUser == null) {
1560            // If this is a shared user, the permissions will
1561            // be written there. We still need to write an
1562            // empty permissions list so permissionsFixed will
1563            // be set.
1564            for (final String name : pkg.grantedPermissions) {
1565                BasePermission bp = mPermissions.get(name);
1566                if (bp != null) {
1567                    // We only need to write signature or system permissions but
1568                    // this wont
1569                    // match the semantics of grantedPermissions. So write all
1570                    // permissions.
1571                    serializer.startTag(null, TAG_ITEM);
1572                    serializer.attribute(null, ATTR_NAME, name);
1573                    serializer.endTag(null, TAG_ITEM);
1574                }
1575            }
1576        }
1577        serializer.endTag(null, "perms");
1578        serializer.endTag(null, "updated-package");
1579    }
1580
1581    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1582            throws java.io.IOException {
1583        serializer.startTag(null, "package");
1584        serializer.attribute(null, ATTR_NAME, pkg.name);
1585        if (pkg.realName != null) {
1586            serializer.attribute(null, "realName", pkg.realName);
1587        }
1588        serializer.attribute(null, "codePath", pkg.codePathString);
1589        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1590            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1591        }
1592        if (pkg.nativeLibraryPathString != null) {
1593            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1594        }
1595        serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1596        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1597        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1598        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1599        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1600        if (pkg.sharedUser == null) {
1601            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1602        } else {
1603            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1604        }
1605        if (pkg.uidError) {
1606            serializer.attribute(null, "uidError", "true");
1607        }
1608        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1609            serializer.attribute(null, "installStatus", "false");
1610        }
1611        if (pkg.installerPackageName != null) {
1612            serializer.attribute(null, "installer", pkg.installerPackageName);
1613        }
1614        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1615        if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1616            serializer.startTag(null, "perms");
1617            if (pkg.sharedUser == null) {
1618                // If this is a shared user, the permissions will
1619                // be written there. We still need to write an
1620                // empty permissions list so permissionsFixed will
1621                // be set.
1622                for (final String name : pkg.grantedPermissions) {
1623                    serializer.startTag(null, TAG_ITEM);
1624                    serializer.attribute(null, ATTR_NAME, name);
1625                    serializer.endTag(null, TAG_ITEM);
1626                }
1627            }
1628            serializer.endTag(null, "perms");
1629        }
1630
1631        writeSigningKeySetsLPr(serializer, pkg.keySetData);
1632        writeKeySetAliasesLPr(serializer, pkg.keySetData);
1633
1634        serializer.endTag(null, "package");
1635    }
1636
1637    void writeSigningKeySetsLPr(XmlSerializer serializer,
1638            PackageKeySetData data) throws IOException {
1639        for (long id : data.getSigningKeySets()) {
1640            serializer.startTag(null, "signing-keyset");
1641            serializer.attribute(null, "identifier", Long.toString(id));
1642            serializer.endTag(null, "signing-keyset");
1643        }
1644    }
1645
1646    void writeKeySetAliasesLPr(XmlSerializer serializer,
1647            PackageKeySetData data) throws IOException {
1648        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
1649            serializer.startTag(null, "defined-keyset");
1650            serializer.attribute(null, "alias", e.getKey());
1651            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
1652            serializer.endTag(null, "defined-keyset");
1653        }
1654    }
1655
1656    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1657            throws XmlPullParserException, java.io.IOException {
1658        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1659            serializer.startTag(null, TAG_ITEM);
1660            serializer.attribute(null, ATTR_NAME, bp.name);
1661            serializer.attribute(null, "package", bp.sourcePackage);
1662            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1663                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1664            }
1665            if (PackageManagerService.DEBUG_SETTINGS)
1666                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1667                        + bp.type);
1668            if (bp.type == BasePermission.TYPE_DYNAMIC) {
1669                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1670                if (pi != null) {
1671                    serializer.attribute(null, "type", "dynamic");
1672                    if (pi.icon != 0) {
1673                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
1674                    }
1675                    if (pi.nonLocalizedLabel != null) {
1676                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1677                    }
1678                }
1679            }
1680            serializer.endTag(null, TAG_ITEM);
1681        }
1682    }
1683
1684    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
1685        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
1686        final Iterator<String> its = kList.iterator();
1687        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
1688        while (its.hasNext()) {
1689            final String key = its.next();
1690            final PackageSetting ps = mPackages.get(key);
1691            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1692                ret.add(ps);
1693            }
1694        }
1695        return ret;
1696    }
1697
1698    void addPackageToCleanLPw(PackageCleanItem pkg) {
1699        if (!mPackagesToBeCleaned.contains(pkg)) {
1700            mPackagesToBeCleaned.add(pkg);
1701        }
1702    }
1703
1704    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
1705            boolean onlyCore) {
1706        FileInputStream str = null;
1707        if (mBackupSettingsFilename.exists()) {
1708            try {
1709                str = new FileInputStream(mBackupSettingsFilename);
1710                mReadMessages.append("Reading from backup settings file\n");
1711                PackageManagerService.reportSettingsProblem(Log.INFO,
1712                        "Need to read from backup settings file");
1713                if (mSettingsFilename.exists()) {
1714                    // If both the backup and settings file exist, we
1715                    // ignore the settings since it might have been
1716                    // corrupted.
1717                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
1718                            + mSettingsFilename);
1719                    mSettingsFilename.delete();
1720                }
1721            } catch (java.io.IOException e) {
1722                // We'll try for the normal settings file.
1723            }
1724        }
1725
1726        mPendingPackages.clear();
1727        mPastSignatures.clear();
1728
1729        try {
1730            if (str == null) {
1731                if (!mSettingsFilename.exists()) {
1732                    mReadMessages.append("No settings file found\n");
1733                    PackageManagerService.reportSettingsProblem(Log.INFO,
1734                            "No settings file; creating initial state");
1735                    mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion;
1736                    return false;
1737                }
1738                str = new FileInputStream(mSettingsFilename);
1739            }
1740            XmlPullParser parser = Xml.newPullParser();
1741            parser.setInput(str, null);
1742
1743            int type;
1744            while ((type = parser.next()) != XmlPullParser.START_TAG
1745                    && type != XmlPullParser.END_DOCUMENT) {
1746                ;
1747            }
1748
1749            if (type != XmlPullParser.START_TAG) {
1750                mReadMessages.append("No start tag found in settings file\n");
1751                PackageManagerService.reportSettingsProblem(Log.WARN,
1752                        "No start tag found in package manager settings");
1753                Log.wtf(PackageManagerService.TAG,
1754                        "No start tag found in package manager settings");
1755                return false;
1756            }
1757
1758            int outerDepth = parser.getDepth();
1759            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1760                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1761                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1762                    continue;
1763                }
1764
1765                String tagName = parser.getName();
1766                if (tagName.equals("package")) {
1767                    readPackageLPw(parser);
1768                } else if (tagName.equals("permissions")) {
1769                    readPermissionsLPw(mPermissions, parser);
1770                } else if (tagName.equals("permission-trees")) {
1771                    readPermissionsLPw(mPermissionTrees, parser);
1772                } else if (tagName.equals("shared-user")) {
1773                    readSharedUserLPw(parser);
1774                } else if (tagName.equals("preferred-packages")) {
1775                    // no longer used.
1776                } else if (tagName.equals("preferred-activities")) {
1777                    // Upgrading from old single-user implementation;
1778                    // these are the preferred activities for user 0.
1779                    readPreferredActivitiesLPw(parser, 0);
1780                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
1781                    // TODO: check whether this is okay! as it is very
1782                    // similar to how preferred-activities are treated
1783                    readPersistentPreferredActivitiesLPw(parser, 0);
1784                } else if (tagName.equals("updated-package")) {
1785                    readDisabledSysPackageLPw(parser);
1786                } else if (tagName.equals("cleaning-package")) {
1787                    String name = parser.getAttributeValue(null, ATTR_NAME);
1788                    String userStr = parser.getAttributeValue(null, ATTR_USER);
1789                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
1790                    if (name != null) {
1791                        int userId = 0;
1792                        boolean andCode = true;
1793                        try {
1794                            if (userStr != null) {
1795                                userId = Integer.parseInt(userStr);
1796                            }
1797                        } catch (NumberFormatException e) {
1798                        }
1799                        if (codeStr != null) {
1800                            andCode = Boolean.parseBoolean(codeStr);
1801                        }
1802                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
1803                    }
1804                } else if (tagName.equals("renamed-package")) {
1805                    String nname = parser.getAttributeValue(null, "new");
1806                    String oname = parser.getAttributeValue(null, "old");
1807                    if (nname != null && oname != null) {
1808                        mRenamedPackages.put(nname, oname);
1809                    }
1810                } else if (tagName.equals("last-platform-version")) {
1811                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
1812                    try {
1813                        String internal = parser.getAttributeValue(null, "internal");
1814                        if (internal != null) {
1815                            mInternalSdkPlatform = Integer.parseInt(internal);
1816                        }
1817                        String external = parser.getAttributeValue(null, "external");
1818                        if (external != null) {
1819                            mExternalSdkPlatform = Integer.parseInt(external);
1820                        }
1821                    } catch (NumberFormatException e) {
1822                    }
1823                } else if (tagName.equals("verifier")) {
1824                    final String deviceIdentity = parser.getAttributeValue(null, "device");
1825                    try {
1826                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
1827                    } catch (IllegalArgumentException e) {
1828                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
1829                                + e.getMessage());
1830                    }
1831                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
1832                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
1833                    mReadExternalStorageEnforced = "1".equals(enforcement);
1834                } else if (tagName.equals("keyset-settings")) {
1835                    mKeySetManager.readKeySetsLPw(parser);
1836                } else {
1837                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
1838                            + parser.getName());
1839                    XmlUtils.skipCurrentTag(parser);
1840                }
1841            }
1842
1843            str.close();
1844
1845        } catch (XmlPullParserException e) {
1846            mReadMessages.append("Error reading: " + e.toString());
1847            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1848            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1849
1850        } catch (java.io.IOException e) {
1851            mReadMessages.append("Error reading: " + e.toString());
1852            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1853            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1854        }
1855
1856        final int N = mPendingPackages.size();
1857        for (int i = 0; i < N; i++) {
1858            final PendingPackage pp = mPendingPackages.get(i);
1859            Object idObj = getUserIdLPr(pp.sharedId);
1860            if (idObj != null && idObj instanceof SharedUserSetting) {
1861                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
1862                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
1863                        pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags,
1864                        null, true /* add */, false /* allowInstall */);
1865                if (p == null) {
1866                    PackageManagerService.reportSettingsProblem(Log.WARN,
1867                            "Unable to create application package for " + pp.name);
1868                    continue;
1869                }
1870                p.copyFrom(pp);
1871            } else if (idObj != null) {
1872                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1873                        + pp.sharedId + " that is not a shared uid\n";
1874                mReadMessages.append(msg);
1875                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1876            } else {
1877                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1878                        + pp.sharedId + " that is not defined\n";
1879                mReadMessages.append(msg);
1880                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1881            }
1882        }
1883        mPendingPackages.clear();
1884
1885        if (mBackupStoppedPackagesFilename.exists()
1886                || mStoppedPackagesFilename.exists()) {
1887            // Read old file
1888            readStoppedLPw();
1889            mBackupStoppedPackagesFilename.delete();
1890            mStoppedPackagesFilename.delete();
1891            // Migrate to new file format
1892            writePackageRestrictionsLPr(0);
1893        } else {
1894            if (users == null) {
1895                readPackageRestrictionsLPr(0);
1896            } else {
1897                for (UserInfo user : users) {
1898                    readPackageRestrictionsLPr(user.id);
1899                }
1900            }
1901        }
1902
1903        /*
1904         * Make sure all the updated system packages have their shared users
1905         * associated with them.
1906         */
1907        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
1908        while (disabledIt.hasNext()) {
1909            final PackageSetting disabledPs = disabledIt.next();
1910            final Object id = getUserIdLPr(disabledPs.appId);
1911            if (id != null && id instanceof SharedUserSetting) {
1912                disabledPs.sharedUser = (SharedUserSetting) id;
1913            }
1914        }
1915
1916        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
1917                + mSharedUsers.size() + " shared uids\n");
1918
1919        return true;
1920    }
1921
1922    void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
1923        // First pull data from any pre-installed apps.
1924        for (PackageSetting ps : mPackages.values()) {
1925            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
1926                    && ps.pkg.preferredActivityFilters != null) {
1927                ArrayList<PackageParser.ActivityIntentInfo> intents
1928                        = ps.pkg.preferredActivityFilters;
1929                for (int i=0; i<intents.size(); i++) {
1930                    PackageParser.ActivityIntentInfo aii = intents.get(i);
1931                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
1932                            ps.name, aii.activity.className), userId);
1933                }
1934            }
1935        }
1936
1937        // Read preferred apps from .../etc/preferred-apps directory.
1938        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
1939        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
1940            return;
1941        }
1942        if (!preferredDir.canRead()) {
1943            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
1944            return;
1945        }
1946
1947        // Iterate over the files in the directory and scan .xml files
1948        for (File f : preferredDir.listFiles()) {
1949            if (!f.getPath().endsWith(".xml")) {
1950                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
1951                continue;
1952            }
1953            if (!f.canRead()) {
1954                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
1955                continue;
1956            }
1957
1958            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
1959            FileInputStream str = null;
1960            try {
1961                str = new FileInputStream(f);
1962                XmlPullParser parser = Xml.newPullParser();
1963                parser.setInput(str, null);
1964
1965                int type;
1966                while ((type = parser.next()) != XmlPullParser.START_TAG
1967                        && type != XmlPullParser.END_DOCUMENT) {
1968                    ;
1969                }
1970
1971                if (type != XmlPullParser.START_TAG) {
1972                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
1973                    continue;
1974                }
1975                if (!"preferred-activities".equals(parser.getName())) {
1976                    Slog.w(TAG, "Preferred apps file " + f
1977                            + " does not start with 'preferred-activities'");
1978                    continue;
1979                }
1980                readDefaultPreferredActivitiesLPw(service, parser, userId);
1981            } catch (XmlPullParserException e) {
1982                Slog.w(TAG, "Error reading apps file " + f, e);
1983            } catch (IOException e) {
1984                Slog.w(TAG, "Error reading apps file " + f, e);
1985            } finally {
1986                if (str != null) {
1987                    try {
1988                        str.close();
1989                    } catch (IOException e) {
1990                    }
1991                }
1992            }
1993        }
1994    }
1995
1996    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
1997            IntentFilter tmpPa, ComponentName cn, int userId) {
1998        // The initial preferences only specify the target activity
1999        // component and intent-filter, not the set of matches.  So we
2000        // now need to query for the matches to build the correct
2001        // preferred activity entry.
2002        if (PackageManagerService.DEBUG_PREFERRED) {
2003            Log.d(TAG, "Processing preferred:");
2004            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
2005        }
2006        Intent intent = new Intent();
2007        int flags = 0;
2008        intent.setAction(tmpPa.getAction(0));
2009        for (int i=0; i<tmpPa.countCategories(); i++) {
2010            String cat = tmpPa.getCategory(i);
2011            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
2012                flags |= PackageManager.MATCH_DEFAULT_ONLY;
2013            } else {
2014                intent.addCategory(cat);
2015            }
2016        }
2017
2018        boolean doNonData = true;
2019        boolean hasSchemes = false;
2020
2021        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2022            boolean doScheme = true;
2023            String scheme = tmpPa.getDataScheme(ischeme);
2024            if (scheme != null && !scheme.isEmpty()) {
2025                hasSchemes = true;
2026            }
2027            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
2028                Uri.Builder builder = new Uri.Builder();
2029                builder.scheme(scheme);
2030                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
2031                builder.opaquePart(ssp.getPath());
2032                Intent finalIntent = new Intent(intent);
2033                finalIntent.setData(builder.build());
2034                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2035                        scheme, ssp, null, null, null, userId);
2036                doScheme = false;
2037            }
2038            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
2039                boolean doAuth = true;
2040                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
2041                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
2042                    Uri.Builder builder = new Uri.Builder();
2043                    builder.scheme(scheme);
2044                    if (auth.getHost() != null) {
2045                        builder.authority(auth.getHost());
2046                    }
2047                    PatternMatcher path = tmpPa.getDataPath(ipath);
2048                    builder.path(path.getPath());
2049                    Intent finalIntent = new Intent(intent);
2050                    finalIntent.setData(builder.build());
2051                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2052                            scheme, null, auth, path, null, userId);
2053                    doAuth = doScheme = false;
2054                }
2055                if (doAuth) {
2056                    Uri.Builder builder = new Uri.Builder();
2057                    builder.scheme(scheme);
2058                    if (auth.getHost() != null) {
2059                        builder.authority(auth.getHost());
2060                    }
2061                    Intent finalIntent = new Intent(intent);
2062                    finalIntent.setData(builder.build());
2063                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2064                            scheme, null, auth, null, null, userId);
2065                    doScheme = false;
2066                }
2067            }
2068            if (doScheme) {
2069                Uri.Builder builder = new Uri.Builder();
2070                builder.scheme(scheme);
2071                Intent finalIntent = new Intent(intent);
2072                finalIntent.setData(builder.build());
2073                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2074                        scheme, null, null, null, null, userId);
2075            }
2076            doNonData = false;
2077        }
2078
2079        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
2080            String mimeType = tmpPa.getDataType(idata);
2081            if (hasSchemes) {
2082                Uri.Builder builder = new Uri.Builder();
2083                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2084                    String scheme = tmpPa.getDataScheme(ischeme);
2085                    if (scheme != null && !scheme.isEmpty()) {
2086                        Intent finalIntent = new Intent(intent);
2087                        builder.scheme(scheme);
2088                        finalIntent.setDataAndType(builder.build(), mimeType);
2089                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2090                                scheme, null, null, null, mimeType, userId);
2091                    }
2092                }
2093            } else {
2094                Intent finalIntent = new Intent(intent);
2095                finalIntent.setType(mimeType);
2096                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2097                        null, null, null, null, mimeType, userId);
2098            }
2099            doNonData = false;
2100        }
2101
2102        if (doNonData) {
2103            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
2104                    null, null, null, null, null, userId);
2105        }
2106    }
2107
2108    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2109            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
2110            IntentFilter.AuthorityEntry auth, PatternMatcher path, String mimeType,
2111            int userId) {
2112        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
2113                intent.getType(), flags, 0);
2114        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
2115                + " results: " + ri);
2116        int match = 0;
2117        if (ri != null && ri.size() > 1) {
2118            boolean haveAct = false;
2119            boolean haveNonSys = false;
2120            ComponentName[] set = new ComponentName[ri.size()];
2121            for (int i=0; i<ri.size(); i++) {
2122                ActivityInfo ai = ri.get(i).activityInfo;
2123                set[i] = new ComponentName(ai.packageName, ai.name);
2124                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
2125                    // If any of the matches are not system apps, then
2126                    // there is a third party app that is now an option...
2127                    // so don't set a default since we don't want to hide it.
2128                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2129                            + ai.packageName + "/" + ai.name + ": non-system!");
2130                    haveNonSys = true;
2131                    break;
2132                } else if (cn.getPackageName().equals(ai.packageName)
2133                        && cn.getClassName().equals(ai.name)) {
2134                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2135                            + ai.packageName + "/" + ai.name + ": default!");
2136                    haveAct = true;
2137                    match = ri.get(i).match;
2138                } else {
2139                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2140                            + ai.packageName + "/" + ai.name + ": skipped");
2141                }
2142            }
2143            if (haveAct && !haveNonSys) {
2144                IntentFilter filter = new IntentFilter();
2145                if (intent.getAction() != null) {
2146                    filter.addAction(intent.getAction());
2147                }
2148                if (intent.getCategories() != null) {
2149                    for (String cat : intent.getCategories()) {
2150                        filter.addCategory(cat);
2151                    }
2152                }
2153                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
2154                    filter.addCategory(Intent.CATEGORY_DEFAULT);
2155                }
2156                if (scheme != null) {
2157                    filter.addDataScheme(scheme);
2158                }
2159                if (ssp != null) {
2160                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
2161                }
2162                if (auth != null) {
2163                    filter.addDataAuthority(auth);
2164                }
2165                if (path != null) {
2166                    filter.addDataPath(path);
2167                }
2168                if (intent.getType() != null) {
2169                    try {
2170                        filter.addDataType(intent.getType());
2171                    } catch (IntentFilter.MalformedMimeTypeException ex) {
2172                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
2173                    }
2174                }
2175                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
2176                editPreferredActivitiesLPw(userId).addFilter(pa);
2177            } else if (!haveNonSys) {
2178                Slog.w(TAG, "No component found for default preferred activity " + cn);
2179            }
2180        }
2181    }
2182
2183    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
2184            XmlPullParser parser, int userId)
2185            throws XmlPullParserException, IOException {
2186        int outerDepth = parser.getDepth();
2187        int type;
2188        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2189                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2190            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2191                continue;
2192            }
2193
2194            String tagName = parser.getName();
2195            if (tagName.equals(TAG_ITEM)) {
2196                PreferredActivity tmpPa = new PreferredActivity(parser);
2197                if (tmpPa.mPref.getParseError() == null) {
2198                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
2199                            userId);
2200                } else {
2201                    PackageManagerService.reportSettingsProblem(Log.WARN,
2202                            "Error in package manager settings: <preferred-activity> "
2203                                    + tmpPa.mPref.getParseError() + " at "
2204                                    + parser.getPositionDescription());
2205                }
2206            } else {
2207                PackageManagerService.reportSettingsProblem(Log.WARN,
2208                        "Unknown element under <preferred-activities>: " + parser.getName());
2209                XmlUtils.skipCurrentTag(parser);
2210            }
2211        }
2212    }
2213
2214    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
2215        String v = parser.getAttributeValue(ns, name);
2216        try {
2217            if (v == null) {
2218                return defValue;
2219            }
2220            return Integer.parseInt(v);
2221        } catch (NumberFormatException e) {
2222            PackageManagerService.reportSettingsProblem(Log.WARN,
2223                    "Error in package manager settings: attribute " + name
2224                            + " has bad integer value " + v + " at "
2225                            + parser.getPositionDescription());
2226        }
2227        return defValue;
2228    }
2229
2230    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
2231            throws IOException, XmlPullParserException {
2232        int outerDepth = parser.getDepth();
2233        int type;
2234        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2235                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2236            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2237                continue;
2238            }
2239
2240            final String tagName = parser.getName();
2241            if (tagName.equals(TAG_ITEM)) {
2242                final String name = parser.getAttributeValue(null, ATTR_NAME);
2243                final String sourcePackage = parser.getAttributeValue(null, "package");
2244                final String ptype = parser.getAttributeValue(null, "type");
2245                if (name != null && sourcePackage != null) {
2246                    final boolean dynamic = "dynamic".equals(ptype);
2247                    final BasePermission bp = new BasePermission(name, sourcePackage,
2248                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
2249                    bp.protectionLevel = readInt(parser, null, "protection",
2250                            PermissionInfo.PROTECTION_NORMAL);
2251                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
2252                    if (dynamic) {
2253                        PermissionInfo pi = new PermissionInfo();
2254                        pi.packageName = sourcePackage.intern();
2255                        pi.name = name.intern();
2256                        pi.icon = readInt(parser, null, "icon", 0);
2257                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
2258                        pi.protectionLevel = bp.protectionLevel;
2259                        bp.pendingInfo = pi;
2260                    }
2261                    out.put(bp.name, bp);
2262                } else {
2263                    PackageManagerService.reportSettingsProblem(Log.WARN,
2264                            "Error in package manager settings: permissions has" + " no name at "
2265                                    + parser.getPositionDescription());
2266                }
2267            } else {
2268                PackageManagerService.reportSettingsProblem(Log.WARN,
2269                        "Unknown element reading permissions: " + parser.getName() + " at "
2270                                + parser.getPositionDescription());
2271            }
2272            XmlUtils.skipCurrentTag(parser);
2273        }
2274    }
2275
2276    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
2277            IOException {
2278        String name = parser.getAttributeValue(null, ATTR_NAME);
2279        String realName = parser.getAttributeValue(null, "realName");
2280        String codePathStr = parser.getAttributeValue(null, "codePath");
2281        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2282        String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2283        if (resourcePathStr == null) {
2284            resourcePathStr = codePathStr;
2285        }
2286        String version = parser.getAttributeValue(null, "version");
2287        int versionCode = 0;
2288        if (version != null) {
2289            try {
2290                versionCode = Integer.parseInt(version);
2291            } catch (NumberFormatException e) {
2292            }
2293        }
2294
2295        int pkgFlags = 0;
2296        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2297        final File codePathFile = new File(codePathStr);
2298        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
2299            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
2300        }
2301        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
2302                new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
2303        String timeStampStr = parser.getAttributeValue(null, "ft");
2304        if (timeStampStr != null) {
2305            try {
2306                long timeStamp = Long.parseLong(timeStampStr, 16);
2307                ps.setTimeStamp(timeStamp);
2308            } catch (NumberFormatException e) {
2309            }
2310        } else {
2311            timeStampStr = parser.getAttributeValue(null, "ts");
2312            if (timeStampStr != null) {
2313                try {
2314                    long timeStamp = Long.parseLong(timeStampStr);
2315                    ps.setTimeStamp(timeStamp);
2316                } catch (NumberFormatException e) {
2317                }
2318            }
2319        }
2320        timeStampStr = parser.getAttributeValue(null, "it");
2321        if (timeStampStr != null) {
2322            try {
2323                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
2324            } catch (NumberFormatException e) {
2325            }
2326        }
2327        timeStampStr = parser.getAttributeValue(null, "ut");
2328        if (timeStampStr != null) {
2329            try {
2330                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
2331            } catch (NumberFormatException e) {
2332            }
2333        }
2334        String idStr = parser.getAttributeValue(null, "userId");
2335        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
2336        if (ps.appId <= 0) {
2337            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2338            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2339        }
2340        int outerDepth = parser.getDepth();
2341        int type;
2342        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2343                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2344            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2345                continue;
2346            }
2347
2348            String tagName = parser.getName();
2349            if (tagName.equals("perms")) {
2350                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
2351            } else {
2352                PackageManagerService.reportSettingsProblem(Log.WARN,
2353                        "Unknown element under <updated-package>: " + parser.getName());
2354                XmlUtils.skipCurrentTag(parser);
2355            }
2356        }
2357
2358        mDisabledSysPackages.put(name, ps);
2359    }
2360
2361    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
2362        String name = null;
2363        String realName = null;
2364        String idStr = null;
2365        String sharedIdStr = null;
2366        String codePathStr = null;
2367        String resourcePathStr = null;
2368        String nativeLibraryPathStr = null;
2369        String systemStr = null;
2370        String installerPackageName = null;
2371        String uidError = null;
2372        int pkgFlags = 0;
2373        long timeStamp = 0;
2374        long firstInstallTime = 0;
2375        long lastUpdateTime = 0;
2376        PackageSettingBase packageSetting = null;
2377        String version = null;
2378        int versionCode = 0;
2379        try {
2380            name = parser.getAttributeValue(null, ATTR_NAME);
2381            realName = parser.getAttributeValue(null, "realName");
2382            idStr = parser.getAttributeValue(null, "userId");
2383            uidError = parser.getAttributeValue(null, "uidError");
2384            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2385            codePathStr = parser.getAttributeValue(null, "codePath");
2386            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2387            nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2388            version = parser.getAttributeValue(null, "version");
2389            if (version != null) {
2390                try {
2391                    versionCode = Integer.parseInt(version);
2392                } catch (NumberFormatException e) {
2393                }
2394            }
2395            installerPackageName = parser.getAttributeValue(null, "installer");
2396
2397            systemStr = parser.getAttributeValue(null, "flags");
2398            if (systemStr != null) {
2399                try {
2400                    pkgFlags = Integer.parseInt(systemStr);
2401                } catch (NumberFormatException e) {
2402                }
2403            } else {
2404                // For backward compatibility
2405                systemStr = parser.getAttributeValue(null, "system");
2406                if (systemStr != null) {
2407                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
2408                            : 0;
2409                } else {
2410                    // Old settings that don't specify system... just treat
2411                    // them as system, good enough.
2412                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2413                }
2414            }
2415            String timeStampStr = parser.getAttributeValue(null, "ft");
2416            if (timeStampStr != null) {
2417                try {
2418                    timeStamp = Long.parseLong(timeStampStr, 16);
2419                } catch (NumberFormatException e) {
2420                }
2421            } else {
2422                timeStampStr = parser.getAttributeValue(null, "ts");
2423                if (timeStampStr != null) {
2424                    try {
2425                        timeStamp = Long.parseLong(timeStampStr);
2426                    } catch (NumberFormatException e) {
2427                    }
2428                }
2429            }
2430            timeStampStr = parser.getAttributeValue(null, "it");
2431            if (timeStampStr != null) {
2432                try {
2433                    firstInstallTime = Long.parseLong(timeStampStr, 16);
2434                } catch (NumberFormatException e) {
2435                }
2436            }
2437            timeStampStr = parser.getAttributeValue(null, "ut");
2438            if (timeStampStr != null) {
2439                try {
2440                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
2441                } catch (NumberFormatException e) {
2442                }
2443            }
2444            if (PackageManagerService.DEBUG_SETTINGS)
2445                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
2446                        + " sharedUserId=" + sharedIdStr);
2447            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2448            if (resourcePathStr == null) {
2449                resourcePathStr = codePathStr;
2450            }
2451            if (realName != null) {
2452                realName = realName.intern();
2453            }
2454            if (name == null) {
2455                PackageManagerService.reportSettingsProblem(Log.WARN,
2456                        "Error in package manager settings: <package> has no name at "
2457                                + parser.getPositionDescription());
2458            } else if (codePathStr == null) {
2459                PackageManagerService.reportSettingsProblem(Log.WARN,
2460                        "Error in package manager settings: <package> has no codePath at "
2461                                + parser.getPositionDescription());
2462            } else if (userId > 0) {
2463                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
2464                        new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
2465                        pkgFlags);
2466                if (PackageManagerService.DEBUG_SETTINGS)
2467                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
2468                            + userId + " pkg=" + packageSetting);
2469                if (packageSetting == null) {
2470                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
2471                            + userId + " while parsing settings at "
2472                            + parser.getPositionDescription());
2473                } else {
2474                    packageSetting.setTimeStamp(timeStamp);
2475                    packageSetting.firstInstallTime = firstInstallTime;
2476                    packageSetting.lastUpdateTime = lastUpdateTime;
2477                }
2478            } else if (sharedIdStr != null) {
2479                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2480                if (userId > 0) {
2481                    packageSetting = new PendingPackage(name.intern(), realName, new File(
2482                            codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
2483                            versionCode, pkgFlags);
2484                    packageSetting.setTimeStamp(timeStamp);
2485                    packageSetting.firstInstallTime = firstInstallTime;
2486                    packageSetting.lastUpdateTime = lastUpdateTime;
2487                    mPendingPackages.add((PendingPackage) packageSetting);
2488                    if (PackageManagerService.DEBUG_SETTINGS)
2489                        Log.i(PackageManagerService.TAG, "Reading package " + name
2490                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
2491                } else {
2492                    PackageManagerService.reportSettingsProblem(Log.WARN,
2493                            "Error in package manager settings: package " + name
2494                                    + " has bad sharedId " + sharedIdStr + " at "
2495                                    + parser.getPositionDescription());
2496                }
2497            } else {
2498                PackageManagerService.reportSettingsProblem(Log.WARN,
2499                        "Error in package manager settings: package " + name + " has bad userId "
2500                                + idStr + " at " + parser.getPositionDescription());
2501            }
2502        } catch (NumberFormatException e) {
2503            PackageManagerService.reportSettingsProblem(Log.WARN,
2504                    "Error in package manager settings: package " + name + " has bad userId "
2505                            + idStr + " at " + parser.getPositionDescription());
2506        }
2507        if (packageSetting != null) {
2508            packageSetting.uidError = "true".equals(uidError);
2509            packageSetting.installerPackageName = installerPackageName;
2510            packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
2511            // Handle legacy string here for single-user mode
2512            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
2513            if (enabledStr != null) {
2514                try {
2515                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
2516                } catch (NumberFormatException e) {
2517                    if (enabledStr.equalsIgnoreCase("true")) {
2518                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
2519                    } else if (enabledStr.equalsIgnoreCase("false")) {
2520                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
2521                    } else if (enabledStr.equalsIgnoreCase("default")) {
2522                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2523                    } else {
2524                        PackageManagerService.reportSettingsProblem(Log.WARN,
2525                                "Error in package manager settings: package " + name
2526                                        + " has bad enabled value: " + idStr + " at "
2527                                        + parser.getPositionDescription());
2528                    }
2529                }
2530            } else {
2531                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2532            }
2533
2534            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
2535            if (installStatusStr != null) {
2536                if (installStatusStr.equalsIgnoreCase("false")) {
2537                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
2538                } else {
2539                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
2540                }
2541            }
2542
2543            int outerDepth = parser.getDepth();
2544            int type;
2545            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2546                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2547                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2548                    continue;
2549                }
2550
2551                String tagName = parser.getName();
2552                // Legacy
2553                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
2554                    readDisabledComponentsLPw(packageSetting, parser, 0);
2555                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
2556                    readEnabledComponentsLPw(packageSetting, parser, 0);
2557                } else if (tagName.equals("sigs")) {
2558                    packageSetting.signatures.readXml(parser, mPastSignatures);
2559                } else if (tagName.equals("perms")) {
2560                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
2561                    packageSetting.permissionsFixed = true;
2562                } else if (tagName.equals("signing-keyset")) {
2563                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2564                    packageSetting.keySetData.addSigningKeySet(id);
2565                    if (false) Slog.d(TAG, "Adding signing keyset " + Long.toString(id)
2566                            + " to " + name);
2567                } else if (tagName.equals("defined-keyset")) {
2568                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2569                    String alias = parser.getAttributeValue(null, "alias");
2570                    packageSetting.keySetData.addDefinedKeySet(id, alias);
2571                } else {
2572                    PackageManagerService.reportSettingsProblem(Log.WARN,
2573                            "Unknown element under <package>: " + parser.getName());
2574                    XmlUtils.skipCurrentTag(parser);
2575                }
2576            }
2577
2578
2579        } else {
2580            XmlUtils.skipCurrentTag(parser);
2581        }
2582    }
2583
2584    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2585            int userId) throws IOException, XmlPullParserException {
2586        int outerDepth = parser.getDepth();
2587        int type;
2588        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2589                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2590            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2591                continue;
2592            }
2593
2594            String tagName = parser.getName();
2595            if (tagName.equals(TAG_ITEM)) {
2596                String name = parser.getAttributeValue(null, ATTR_NAME);
2597                if (name != null) {
2598                    packageSetting.addDisabledComponent(name.intern(), userId);
2599                } else {
2600                    PackageManagerService.reportSettingsProblem(Log.WARN,
2601                            "Error in package manager settings: <disabled-components> has"
2602                                    + " no name at " + parser.getPositionDescription());
2603                }
2604            } else {
2605                PackageManagerService.reportSettingsProblem(Log.WARN,
2606                        "Unknown element under <disabled-components>: " + parser.getName());
2607            }
2608            XmlUtils.skipCurrentTag(parser);
2609        }
2610    }
2611
2612    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2613            int userId) throws IOException, XmlPullParserException {
2614        int outerDepth = parser.getDepth();
2615        int type;
2616        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2617                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2618            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2619                continue;
2620            }
2621
2622            String tagName = parser.getName();
2623            if (tagName.equals(TAG_ITEM)) {
2624                String name = parser.getAttributeValue(null, ATTR_NAME);
2625                if (name != null) {
2626                    packageSetting.addEnabledComponent(name.intern(), userId);
2627                } else {
2628                    PackageManagerService.reportSettingsProblem(Log.WARN,
2629                            "Error in package manager settings: <enabled-components> has"
2630                                    + " no name at " + parser.getPositionDescription());
2631                }
2632            } else {
2633                PackageManagerService.reportSettingsProblem(Log.WARN,
2634                        "Unknown element under <enabled-components>: " + parser.getName());
2635            }
2636            XmlUtils.skipCurrentTag(parser);
2637        }
2638    }
2639
2640    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
2641        String name = null;
2642        String idStr = null;
2643        int pkgFlags = 0;
2644        SharedUserSetting su = null;
2645        try {
2646            name = parser.getAttributeValue(null, ATTR_NAME);
2647            idStr = parser.getAttributeValue(null, "userId");
2648            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2649            if ("true".equals(parser.getAttributeValue(null, "system"))) {
2650                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2651            }
2652            if (name == null) {
2653                PackageManagerService.reportSettingsProblem(Log.WARN,
2654                        "Error in package manager settings: <shared-user> has no name at "
2655                                + parser.getPositionDescription());
2656            } else if (userId == 0) {
2657                PackageManagerService.reportSettingsProblem(Log.WARN,
2658                        "Error in package manager settings: shared-user " + name
2659                                + " has bad userId " + idStr + " at "
2660                                + parser.getPositionDescription());
2661            } else {
2662                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
2663                    PackageManagerService
2664                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
2665                                    + parser.getPositionDescription());
2666                }
2667            }
2668        } catch (NumberFormatException e) {
2669            PackageManagerService.reportSettingsProblem(Log.WARN,
2670                    "Error in package manager settings: package " + name + " has bad userId "
2671                            + idStr + " at " + parser.getPositionDescription());
2672        }
2673        ;
2674
2675        if (su != null) {
2676            int outerDepth = parser.getDepth();
2677            int type;
2678            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2679                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2680                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2681                    continue;
2682                }
2683
2684                String tagName = parser.getName();
2685                if (tagName.equals("sigs")) {
2686                    su.signatures.readXml(parser, mPastSignatures);
2687                } else if (tagName.equals("perms")) {
2688                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
2689                } else {
2690                    PackageManagerService.reportSettingsProblem(Log.WARN,
2691                            "Unknown element under <shared-user>: " + parser.getName());
2692                    XmlUtils.skipCurrentTag(parser);
2693                }
2694            }
2695
2696        } else {
2697            XmlUtils.skipCurrentTag(parser);
2698        }
2699    }
2700
2701    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
2702            throws IOException, XmlPullParserException {
2703        int outerDepth = parser.getDepth();
2704        int type;
2705        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2706                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2707            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2708                continue;
2709            }
2710
2711            String tagName = parser.getName();
2712            if (tagName.equals(TAG_ITEM)) {
2713                String name = parser.getAttributeValue(null, ATTR_NAME);
2714                if (name != null) {
2715                    outPerms.add(name.intern());
2716                } else {
2717                    PackageManagerService.reportSettingsProblem(Log.WARN,
2718                            "Error in package manager settings: <perms> has" + " no name at "
2719                                    + parser.getPositionDescription());
2720                }
2721            } else {
2722                PackageManagerService.reportSettingsProblem(Log.WARN,
2723                        "Unknown element under <perms>: " + parser.getName());
2724            }
2725            XmlUtils.skipCurrentTag(parser);
2726        }
2727    }
2728
2729    void createNewUserLILPw(PackageManagerService service, Installer installer,
2730            int userHandle, File path) {
2731        path.mkdir();
2732        FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
2733                | FileUtils.S_IXOTH, -1, -1);
2734        for (PackageSetting ps : mPackages.values()) {
2735            // Only system apps are initially installed.
2736            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
2737            // Need to create a data directory for all apps under this user.
2738            installer.createUserData(ps.name,
2739                    UserHandle.getUid(userHandle, ps.appId), userHandle,
2740                    ps.pkg.applicationInfo.seinfo);
2741        }
2742        readDefaultPreferredAppsLPw(service, userHandle);
2743        writePackageRestrictionsLPr(userHandle);
2744    }
2745
2746    void removeUserLPr(int userId) {
2747        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
2748        for (Entry<String, PackageSetting> entry : entries) {
2749            entry.getValue().removeUser(userId);
2750        }
2751        mPreferredActivities.remove(userId);
2752        File file = getUserPackagesStateFile(userId);
2753        file.delete();
2754        file = getUserPackagesStateBackupFile(userId);
2755        file.delete();
2756    }
2757
2758    // This should be called (at least) whenever an application is removed
2759    private void setFirstAvailableUid(int uid) {
2760        if (uid > mFirstAvailableUid) {
2761            mFirstAvailableUid = uid;
2762        }
2763    }
2764
2765    // Returns -1 if we could not find an available UserId to assign
2766    private int newUserIdLPw(Object obj) {
2767        // Let's be stupidly inefficient for now...
2768        final int N = mUserIds.size();
2769        for (int i = mFirstAvailableUid; i < N; i++) {
2770            if (mUserIds.get(i) == null) {
2771                mUserIds.set(i, obj);
2772                return Process.FIRST_APPLICATION_UID + i;
2773            }
2774        }
2775
2776        // None left?
2777        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
2778            return -1;
2779        }
2780
2781        mUserIds.add(obj);
2782        return Process.FIRST_APPLICATION_UID + N;
2783    }
2784
2785    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
2786        if (mVerifierDeviceIdentity == null) {
2787            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
2788
2789            writeLPr();
2790        }
2791
2792        return mVerifierDeviceIdentity;
2793    }
2794
2795    public PackageSetting getDisabledSystemPkgLPr(String name) {
2796        PackageSetting ps = mDisabledSysPackages.get(name);
2797        return ps;
2798    }
2799
2800    private String compToString(HashSet<String> cmp) {
2801        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
2802    }
2803
2804    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
2805        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
2806            return true;
2807        }
2808        final String pkgName = componentInfo.packageName;
2809        final PackageSetting packageSettings = mPackages.get(pkgName);
2810        if (PackageManagerService.DEBUG_SETTINGS) {
2811            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
2812                    + componentInfo.packageName + " componentName = " + componentInfo.name);
2813            Log.v(PackageManagerService.TAG, "enabledComponents: "
2814                    + compToString(packageSettings.getEnabledComponents(userId)));
2815            Log.v(PackageManagerService.TAG, "disabledComponents: "
2816                    + compToString(packageSettings.getDisabledComponents(userId)));
2817        }
2818        if (packageSettings == null) {
2819            return false;
2820        }
2821        PackageUserState ustate = packageSettings.readUserState(userId);
2822        if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
2823            if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
2824                return true;
2825            }
2826        }
2827        if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
2828                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
2829                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
2830                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
2831                    && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
2832            return false;
2833        }
2834        if (ustate.enabledComponents != null
2835                && ustate.enabledComponents.contains(componentInfo.name)) {
2836            return true;
2837        }
2838        if (ustate.disabledComponents != null
2839                && ustate.disabledComponents.contains(componentInfo.name)) {
2840            return false;
2841        }
2842        return componentInfo.enabled;
2843    }
2844
2845    String getInstallerPackageNameLPr(String packageName) {
2846        final PackageSetting pkg = mPackages.get(packageName);
2847        if (pkg == null) {
2848            throw new IllegalArgumentException("Unknown package: " + packageName);
2849        }
2850        return pkg.installerPackageName;
2851    }
2852
2853    int getApplicationEnabledSettingLPr(String packageName, int userId) {
2854        final PackageSetting pkg = mPackages.get(packageName);
2855        if (pkg == null) {
2856            throw new IllegalArgumentException("Unknown package: " + packageName);
2857        }
2858        return pkg.getEnabled(userId);
2859    }
2860
2861    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
2862        final String packageName = componentName.getPackageName();
2863        final PackageSetting pkg = mPackages.get(packageName);
2864        if (pkg == null) {
2865            throw new IllegalArgumentException("Unknown component: " + componentName);
2866        }
2867        final String classNameStr = componentName.getClassName();
2868        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
2869    }
2870
2871    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
2872            boolean allowedByPermission, int uid, int userId) {
2873        int appId = UserHandle.getAppId(uid);
2874        final PackageSetting pkgSetting = mPackages.get(packageName);
2875        if (pkgSetting == null) {
2876            throw new IllegalArgumentException("Unknown package: " + packageName);
2877        }
2878        if (!allowedByPermission && (appId != pkgSetting.appId)) {
2879            throw new SecurityException(
2880                    "Permission Denial: attempt to change stopped state from pid="
2881                    + Binder.getCallingPid()
2882                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
2883        }
2884        if (DEBUG_STOPPED) {
2885            if (stopped) {
2886                RuntimeException e = new RuntimeException("here");
2887                e.fillInStackTrace();
2888                Slog.i(TAG, "Stopping package " + packageName, e);
2889            }
2890        }
2891        if (pkgSetting.getStopped(userId) != stopped) {
2892            pkgSetting.setStopped(stopped, userId);
2893            // pkgSetting.pkg.mSetStopped = stopped;
2894            if (pkgSetting.getNotLaunched(userId)) {
2895                if (pkgSetting.installerPackageName != null) {
2896                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
2897                            pkgSetting.name, null,
2898                            pkgSetting.installerPackageName, null, new int[] {userId});
2899                }
2900                pkgSetting.setNotLaunched(false, userId);
2901            }
2902            return true;
2903        }
2904        return false;
2905    }
2906
2907    private List<UserInfo> getAllUsers() {
2908        long id = Binder.clearCallingIdentity();
2909        try {
2910            return UserManagerService.getInstance().getUsers(false);
2911        } catch (NullPointerException npe) {
2912            // packagemanager not yet initialized
2913        } finally {
2914            Binder.restoreCallingIdentity(id);
2915        }
2916        return null;
2917    }
2918
2919    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
2920        pw.print("[ ");
2921        for (int i=0; i<spec.length; i+=2) {
2922            int mask = (Integer)spec[i];
2923            if ((val & mask) != 0) {
2924                pw.print(spec[i+1]);
2925                pw.print(" ");
2926            }
2927        }
2928        pw.print("]");
2929    }
2930
2931    static final Object[] FLAG_DUMP_SPEC = new Object[] {
2932        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
2933        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
2934        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
2935        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
2936        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
2937        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
2938        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
2939        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
2940        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
2941        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
2942        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
2943        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
2944        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
2945        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
2946        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
2947        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
2948        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
2949        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
2950    };
2951
2952    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
2953            SimpleDateFormat sdf, Date date, List<UserInfo> users) {
2954        if (checkinTag != null) {
2955            pw.print(checkinTag);
2956            pw.print(",");
2957            pw.print(ps.realName != null ? ps.realName : ps.name);
2958            pw.print(",");
2959            pw.print(ps.appId);
2960            pw.print(",");
2961            pw.print(ps.versionCode);
2962            pw.print(",");
2963            pw.print(ps.firstInstallTime);
2964            pw.print(",");
2965            pw.print(ps.lastUpdateTime);
2966            pw.print(",");
2967            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
2968            pw.println();
2969            for (UserInfo user : users) {
2970                pw.print(checkinTag);
2971                pw.print("-");
2972                pw.print("usr");
2973                pw.print(",");
2974                pw.print(user.id);
2975                pw.print(",");
2976                pw.print(ps.getInstalled(user.id) ? "I" : "i");
2977                pw.print(ps.getBlocked(user.id) ? "B" : "b");
2978                pw.print(ps.getStopped(user.id) ? "S" : "s");
2979                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
2980                pw.print(",");
2981                pw.print(ps.getEnabled(user.id));
2982                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
2983                pw.print(",");
2984                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
2985                pw.println();
2986            }
2987            return;
2988        }
2989
2990        pw.print(prefix); pw.print("Package [");
2991            pw.print(ps.realName != null ? ps.realName : ps.name);
2992            pw.print("] (");
2993            pw.print(Integer.toHexString(System.identityHashCode(ps)));
2994            pw.println("):");
2995
2996        if (ps.realName != null) {
2997            pw.print(prefix); pw.print("  compat name=");
2998            pw.println(ps.name);
2999        }
3000
3001        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
3002                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
3003        if (ps.sharedUser != null) {
3004            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
3005        }
3006        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
3007        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
3008        pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
3009        pw.print(prefix); pw.print("  nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
3010        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
3011        if (ps.pkg != null) {
3012            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
3013        }
3014        pw.println();
3015        if (ps.pkg != null) {
3016            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
3017            pw.print(prefix); pw.print("  applicationInfo=");
3018                pw.println(ps.pkg.applicationInfo.toString());
3019            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
3020                    FLAG_DUMP_SPEC); pw.println();
3021            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
3022            if (ps.pkg.mOperationPending) {
3023                pw.print(prefix); pw.println("  mOperationPending=true");
3024            }
3025            pw.print(prefix); pw.print("  supportsScreens=[");
3026            boolean first = true;
3027            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
3028                if (!first)
3029                    pw.print(", ");
3030                first = false;
3031                pw.print("small");
3032            }
3033            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
3034                if (!first)
3035                    pw.print(", ");
3036                first = false;
3037                pw.print("medium");
3038            }
3039            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
3040                if (!first)
3041                    pw.print(", ");
3042                first = false;
3043                pw.print("large");
3044            }
3045            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
3046                if (!first)
3047                    pw.print(", ");
3048                first = false;
3049                pw.print("xlarge");
3050            }
3051            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
3052                if (!first)
3053                    pw.print(", ");
3054                first = false;
3055                pw.print("resizeable");
3056            }
3057            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
3058                if (!first)
3059                    pw.print(", ");
3060                first = false;
3061                pw.print("anyDensity");
3062            }
3063            pw.println("]");
3064            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
3065                pw.print(prefix); pw.println("  libraries:");
3066                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
3067                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
3068                }
3069            }
3070            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
3071                pw.print(prefix); pw.println("  usesLibraries:");
3072                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
3073                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
3074                }
3075            }
3076            if (ps.pkg.usesOptionalLibraries != null
3077                    && ps.pkg.usesOptionalLibraries.size() > 0) {
3078                pw.print(prefix); pw.println("  usesOptionalLibraries:");
3079                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
3080                    pw.print(prefix); pw.print("    ");
3081                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
3082                }
3083            }
3084            if (ps.pkg.usesLibraryFiles != null
3085                    && ps.pkg.usesLibraryFiles.length > 0) {
3086                pw.print(prefix); pw.println("  usesLibraryFiles:");
3087                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
3088                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
3089                }
3090            }
3091        }
3092        pw.print(prefix); pw.print("  timeStamp=");
3093            date.setTime(ps.timeStamp);
3094            pw.println(sdf.format(date));
3095        pw.print(prefix); pw.print("  firstInstallTime=");
3096            date.setTime(ps.firstInstallTime);
3097            pw.println(sdf.format(date));
3098        pw.print(prefix); pw.print("  lastUpdateTime=");
3099            date.setTime(ps.lastUpdateTime);
3100            pw.println(sdf.format(date));
3101        if (ps.installerPackageName != null) {
3102            pw.print(prefix); pw.print("  installerPackageName=");
3103                    pw.println(ps.installerPackageName);
3104        }
3105        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
3106        pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
3107                pw.print(" haveGids="); pw.print(ps.haveGids);
3108                pw.print(" installStatus="); pw.println(ps.installStatus);
3109        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
3110                pw.println();
3111        for (UserInfo user : users) {
3112            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
3113            pw.print(" installed=");
3114            pw.print(ps.getInstalled(user.id));
3115            pw.print(" blocked=");
3116            pw.print(ps.getBlocked(user.id));
3117            pw.print(" stopped=");
3118            pw.print(ps.getStopped(user.id));
3119            pw.print(" notLaunched=");
3120            pw.print(ps.getNotLaunched(user.id));
3121            pw.print(" enabled=");
3122            pw.println(ps.getEnabled(user.id));
3123            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3124            if (lastDisabledAppCaller != null) {
3125                pw.print(prefix); pw.print("    lastDisabledCaller: ");
3126                        pw.println(lastDisabledAppCaller);
3127            }
3128            HashSet<String> cmp = ps.getDisabledComponents(user.id);
3129            if (cmp != null && cmp.size() > 0) {
3130                pw.print(prefix); pw.println("    disabledComponents:");
3131                for (String s : cmp) {
3132                    pw.print(prefix); pw.print("    "); pw.println(s);
3133                }
3134            }
3135            cmp = ps.getEnabledComponents(user.id);
3136            if (cmp != null && cmp.size() > 0) {
3137                pw.print(prefix); pw.println("    enabledComponents:");
3138                for (String s : cmp) {
3139                    pw.print(prefix); pw.print("    "); pw.println(s);
3140                }
3141            }
3142        }
3143        if (ps.grantedPermissions.size() > 0) {
3144            pw.print(prefix); pw.println("  grantedPermissions:");
3145            for (String s : ps.grantedPermissions) {
3146                pw.print(prefix); pw.print("    "); pw.println(s);
3147            }
3148        }
3149    }
3150
3151    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
3152        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3153        final Date date = new Date();
3154        boolean printedSomething = false;
3155        List<UserInfo> users = getAllUsers();
3156        for (final PackageSetting ps : mPackages.values()) {
3157            if (packageName != null && !packageName.equals(ps.realName)
3158                    && !packageName.equals(ps.name)) {
3159                continue;
3160            }
3161
3162            if (!checkin && packageName != null) {
3163                dumpState.setSharedUser(ps.sharedUser);
3164            }
3165
3166            if (!checkin && !printedSomething) {
3167                if (dumpState.onTitlePrinted())
3168                    pw.println();
3169                pw.println("Packages:");
3170                printedSomething = true;
3171            }
3172            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, ps, sdf, date, users);
3173        }
3174
3175        printedSomething = false;
3176        if (!checkin && mRenamedPackages.size() > 0) {
3177            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
3178                if (packageName != null && !packageName.equals(e.getKey())
3179                        && !packageName.equals(e.getValue())) {
3180                    continue;
3181                }
3182                if (!checkin) {
3183                    if (!printedSomething) {
3184                        if (dumpState.onTitlePrinted())
3185                            pw.println();
3186                        pw.println("Renamed packages:");
3187                        printedSomething = true;
3188                    }
3189                    pw.print("  ");
3190                } else {
3191                    pw.print("ren,");
3192                }
3193                pw.print(e.getKey());
3194                pw.print(checkin ? " -> " : ",");
3195                pw.println(e.getValue());
3196            }
3197        }
3198
3199        printedSomething = false;
3200        if (mDisabledSysPackages.size() > 0) {
3201            for (final PackageSetting ps : mDisabledSysPackages.values()) {
3202                if (packageName != null && !packageName.equals(ps.realName)
3203                        && !packageName.equals(ps.name)) {
3204                    continue;
3205                }
3206                if (!checkin && !printedSomething) {
3207                    if (dumpState.onTitlePrinted())
3208                        pw.println();
3209                    pw.println("Hidden system packages:");
3210                    printedSomething = true;
3211                }
3212                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, ps, sdf, date, users);
3213            }
3214        }
3215    }
3216
3217    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3218        boolean printedSomething = false;
3219        for (BasePermission p : mPermissions.values()) {
3220            if (packageName != null && !packageName.equals(p.sourcePackage)) {
3221                continue;
3222            }
3223            if (!printedSomething) {
3224                if (dumpState.onTitlePrinted())
3225                    pw.println();
3226                pw.println("Permissions:");
3227                printedSomething = true;
3228            }
3229            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
3230                    pw.print(Integer.toHexString(System.identityHashCode(p)));
3231                    pw.println("):");
3232            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
3233            pw.print("    uid="); pw.print(p.uid);
3234                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
3235                    pw.print(" type="); pw.print(p.type);
3236                    pw.print(" prot=");
3237                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
3238            if (p.packageSetting != null) {
3239                pw.print("    packageSetting="); pw.println(p.packageSetting);
3240            }
3241            if (p.perm != null) {
3242                pw.print("    perm="); pw.println(p.perm);
3243            }
3244            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
3245                pw.print("    enforced=");
3246                pw.println(mReadExternalStorageEnforced);
3247            }
3248        }
3249    }
3250
3251    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3252        boolean printedSomething = false;
3253        for (SharedUserSetting su : mSharedUsers.values()) {
3254            if (packageName != null && su != dumpState.getSharedUser()) {
3255                continue;
3256            }
3257            if (!printedSomething) {
3258                if (dumpState.onTitlePrinted())
3259                    pw.println();
3260                pw.println("Shared users:");
3261                printedSomething = true;
3262            }
3263            pw.print("  SharedUser [");
3264            pw.print(su.name);
3265            pw.print("] (");
3266            pw.print(Integer.toHexString(System.identityHashCode(su)));
3267                    pw.println("):");
3268            pw.print("    userId=");
3269            pw.print(su.userId);
3270            pw.print(" gids=");
3271            pw.println(PackageManagerService.arrayToString(su.gids));
3272            pw.println("    grantedPermissions:");
3273            for (String s : su.grantedPermissions) {
3274                pw.print("      ");
3275                pw.println(s);
3276            }
3277        }
3278    }
3279
3280    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
3281        pw.println("Settings parse messages:");
3282        pw.print(mReadMessages.toString());
3283    }
3284}
3285