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