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