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