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