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