Settings.java revision 8d05172112436a81bed6e4a0810f8914509d8a4d
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            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1182                    e);
1183
1184        } catch (java.io.IOException e) {
1185            mReadMessages.append("Error reading: " + e.toString());
1186            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1187            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1188                    e);
1189        }
1190    }
1191
1192    private HashSet<String> readComponentsLPr(XmlPullParser parser)
1193            throws IOException, XmlPullParserException {
1194        HashSet<String> components = null;
1195        int type;
1196        int outerDepth = parser.getDepth();
1197        String tagName;
1198        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1199                && (type != XmlPullParser.END_TAG
1200                || parser.getDepth() > outerDepth)) {
1201            if (type == XmlPullParser.END_TAG
1202                    || type == XmlPullParser.TEXT) {
1203                continue;
1204            }
1205            tagName = parser.getName();
1206            if (tagName.equals(TAG_ITEM)) {
1207                String componentName = parser.getAttributeValue(null, ATTR_NAME);
1208                if (componentName != null) {
1209                    if (components == null) {
1210                        components = new HashSet<String>();
1211                    }
1212                    components.add(componentName);
1213                }
1214            }
1215        }
1216        return components;
1217    }
1218
1219    void writePreferredActivitiesLPr(XmlSerializer serializer, int userId, boolean full)
1220            throws IllegalArgumentException, IllegalStateException, IOException {
1221        serializer.startTag(null, "preferred-activities");
1222        PreferredIntentResolver pir = mPreferredActivities.get(userId);
1223        if (pir != null) {
1224            for (final PreferredActivity pa : pir.filterSet()) {
1225                serializer.startTag(null, TAG_ITEM);
1226                pa.writeToXml(serializer, full);
1227                serializer.endTag(null, TAG_ITEM);
1228            }
1229        }
1230        serializer.endTag(null, "preferred-activities");
1231    }
1232
1233    void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
1234            throws IllegalArgumentException, IllegalStateException, IOException {
1235        serializer.startTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1236        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
1237        if (ppir != null) {
1238            for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
1239                serializer.startTag(null, TAG_ITEM);
1240                ppa.writeToXml(serializer);
1241                serializer.endTag(null, TAG_ITEM);
1242            }
1243        }
1244        serializer.endTag(null, TAG_PERSISTENT_PREFERRED_ACTIVITIES);
1245    }
1246
1247    void writeCrossProfileIntentFiltersLPr(XmlSerializer serializer, int userId)
1248            throws IllegalArgumentException, IllegalStateException, IOException {
1249        serializer.startTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1250        CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(userId);
1251        if (cpir != null) {
1252            for (final CrossProfileIntentFilter cpif : cpir.filterSet()) {
1253                serializer.startTag(null, TAG_ITEM);
1254                cpif.writeToXml(serializer);
1255                serializer.endTag(null, TAG_ITEM);
1256            }
1257        }
1258        serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
1259    }
1260
1261    void writePackageRestrictionsLPr(int userId) {
1262        if (DEBUG_MU) {
1263            Log.i(TAG, "Writing package restrictions for user=" + userId);
1264        }
1265        // Keep the old stopped packages around until we know the new ones have
1266        // been successfully written.
1267        File userPackagesStateFile = getUserPackagesStateFile(userId);
1268        File backupFile = getUserPackagesStateBackupFile(userId);
1269        new File(userPackagesStateFile.getParent()).mkdirs();
1270        if (userPackagesStateFile.exists()) {
1271            // Presence of backup settings file indicates that we failed
1272            // to persist packages earlier. So preserve the older
1273            // backup for future reference since the current packages
1274            // might have been corrupted.
1275            if (!backupFile.exists()) {
1276                if (!userPackagesStateFile.renameTo(backupFile)) {
1277                    Slog.wtf(PackageManagerService.TAG,
1278                            "Unable to backup user packages state file, "
1279                            + "current changes will be lost at reboot");
1280                    return;
1281                }
1282            } else {
1283                userPackagesStateFile.delete();
1284                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
1285            }
1286        }
1287
1288        try {
1289            final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
1290            final BufferedOutputStream str = new BufferedOutputStream(fstr);
1291
1292            final XmlSerializer serializer = new FastXmlSerializer();
1293            serializer.setOutput(str, "utf-8");
1294            serializer.startDocument(null, true);
1295            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1296
1297            serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
1298
1299            for (final PackageSetting pkg : mPackages.values()) {
1300                PackageUserState ustate = pkg.readUserState(userId);
1301                if (ustate.stopped || ustate.notLaunched || !ustate.installed
1302                        || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT
1303                        || ustate.hidden
1304                        || (ustate.enabledComponents != null
1305                                && ustate.enabledComponents.size() > 0)
1306                        || (ustate.disabledComponents != null
1307                                && ustate.disabledComponents.size() > 0)
1308                        || ustate.blockUninstall) {
1309                    serializer.startTag(null, TAG_PACKAGE);
1310                    serializer.attribute(null, ATTR_NAME, pkg.name);
1311                    if (DEBUG_MU) Log.i(TAG, "  pkg=" + pkg.name + ", state=" + ustate.enabled);
1312
1313                    if (!ustate.installed) {
1314                        serializer.attribute(null, ATTR_INSTALLED, "false");
1315                    }
1316                    if (ustate.stopped) {
1317                        serializer.attribute(null, ATTR_STOPPED, "true");
1318                    }
1319                    if (ustate.notLaunched) {
1320                        serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
1321                    }
1322                    if (ustate.hidden) {
1323                        serializer.attribute(null, ATTR_HIDDEN, "true");
1324                    }
1325                    if (ustate.blockUninstall) {
1326                        serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
1327                    }
1328                    if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
1329                        serializer.attribute(null, ATTR_ENABLED,
1330                                Integer.toString(ustate.enabled));
1331                        if (ustate.lastDisableAppCaller != null) {
1332                            serializer.attribute(null, ATTR_ENABLED_CALLER,
1333                                    ustate.lastDisableAppCaller);
1334                        }
1335                    }
1336                    if (ustate.enabledComponents != null
1337                            && ustate.enabledComponents.size() > 0) {
1338                        serializer.startTag(null, TAG_ENABLED_COMPONENTS);
1339                        for (final String name : ustate.enabledComponents) {
1340                            serializer.startTag(null, TAG_ITEM);
1341                            serializer.attribute(null, ATTR_NAME, name);
1342                            serializer.endTag(null, TAG_ITEM);
1343                        }
1344                        serializer.endTag(null, TAG_ENABLED_COMPONENTS);
1345                    }
1346                    if (ustate.disabledComponents != null
1347                            && ustate.disabledComponents.size() > 0) {
1348                        serializer.startTag(null, TAG_DISABLED_COMPONENTS);
1349                        for (final String name : ustate.disabledComponents) {
1350                            serializer.startTag(null, TAG_ITEM);
1351                            serializer.attribute(null, ATTR_NAME, name);
1352                            serializer.endTag(null, TAG_ITEM);
1353                        }
1354                        serializer.endTag(null, TAG_DISABLED_COMPONENTS);
1355                    }
1356                    serializer.endTag(null, TAG_PACKAGE);
1357                }
1358            }
1359
1360            writePreferredActivitiesLPr(serializer, userId, true);
1361
1362            writePersistentPreferredActivitiesLPr(serializer, userId);
1363
1364            writeCrossProfileIntentFiltersLPr(serializer, userId);
1365
1366            serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
1367
1368            serializer.endDocument();
1369
1370            str.flush();
1371            FileUtils.sync(fstr);
1372            str.close();
1373
1374            // New settings successfully written, old ones are no longer
1375            // needed.
1376            backupFile.delete();
1377            FileUtils.setPermissions(userPackagesStateFile.toString(),
1378                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1379                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1380                    -1, -1);
1381
1382            // Done, all is good!
1383            return;
1384        } catch(java.io.IOException e) {
1385            Slog.wtf(PackageManagerService.TAG,
1386                    "Unable to write package manager user packages state, "
1387                    + " current changes will be lost at reboot", e);
1388        }
1389
1390        // Clean up partially written files
1391        if (userPackagesStateFile.exists()) {
1392            if (!userPackagesStateFile.delete()) {
1393                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
1394                        + mStoppedPackagesFilename);
1395            }
1396        }
1397    }
1398
1399    // Note: assumed "stopped" field is already cleared in all packages.
1400    // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
1401    void readStoppedLPw() {
1402        FileInputStream str = null;
1403        if (mBackupStoppedPackagesFilename.exists()) {
1404            try {
1405                str = new FileInputStream(mBackupStoppedPackagesFilename);
1406                mReadMessages.append("Reading from backup stopped packages file\n");
1407                PackageManagerService.reportSettingsProblem(Log.INFO,
1408                        "Need to read from backup stopped packages file");
1409                if (mSettingsFilename.exists()) {
1410                    // If both the backup and normal file exist, we
1411                    // ignore the normal one since it might have been
1412                    // corrupted.
1413                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
1414                            + mStoppedPackagesFilename);
1415                    mStoppedPackagesFilename.delete();
1416                }
1417            } catch (java.io.IOException e) {
1418                // We'll try for the normal settings file.
1419            }
1420        }
1421
1422        try {
1423            if (str == null) {
1424                if (!mStoppedPackagesFilename.exists()) {
1425                    mReadMessages.append("No stopped packages file found\n");
1426                    PackageManagerService.reportSettingsProblem(Log.INFO,
1427                            "No stopped packages file file; assuming all started");
1428                    // At first boot, make sure no packages are stopped.
1429                    // We usually want to have third party apps initialize
1430                    // in the stopped state, but not at first boot.
1431                    for (PackageSetting pkg : mPackages.values()) {
1432                        pkg.setStopped(false, 0);
1433                        pkg.setNotLaunched(false, 0);
1434                    }
1435                    return;
1436                }
1437                str = new FileInputStream(mStoppedPackagesFilename);
1438            }
1439            final XmlPullParser parser = Xml.newPullParser();
1440            parser.setInput(str, null);
1441
1442            int type;
1443            while ((type=parser.next()) != XmlPullParser.START_TAG
1444                       && type != XmlPullParser.END_DOCUMENT) {
1445                ;
1446            }
1447
1448            if (type != XmlPullParser.START_TAG) {
1449                mReadMessages.append("No start tag found in stopped packages file\n");
1450                PackageManagerService.reportSettingsProblem(Log.WARN,
1451                        "No start tag found in package manager stopped packages");
1452                return;
1453            }
1454
1455            int outerDepth = parser.getDepth();
1456            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1457                   && (type != XmlPullParser.END_TAG
1458                           || parser.getDepth() > outerDepth)) {
1459                if (type == XmlPullParser.END_TAG
1460                        || type == XmlPullParser.TEXT) {
1461                    continue;
1462                }
1463
1464                String tagName = parser.getName();
1465                if (tagName.equals(TAG_PACKAGE)) {
1466                    String name = parser.getAttributeValue(null, ATTR_NAME);
1467                    PackageSetting ps = mPackages.get(name);
1468                    if (ps != null) {
1469                        ps.setStopped(true, 0);
1470                        if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
1471                            ps.setNotLaunched(true, 0);
1472                        }
1473                    } else {
1474                        Slog.w(PackageManagerService.TAG,
1475                                "No package known for stopped package: " + name);
1476                    }
1477                    XmlUtils.skipCurrentTag(parser);
1478                } else {
1479                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
1480                          + parser.getName());
1481                    XmlUtils.skipCurrentTag(parser);
1482                }
1483            }
1484
1485            str.close();
1486
1487        } catch (XmlPullParserException e) {
1488            mReadMessages.append("Error reading: " + e.toString());
1489            PackageManagerService.reportSettingsProblem(Log.ERROR,
1490                    "Error reading stopped packages: " + e);
1491            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1492                    e);
1493
1494        } catch (java.io.IOException e) {
1495            mReadMessages.append("Error reading: " + e.toString());
1496            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1497            Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
1498                    e);
1499
1500        }
1501    }
1502
1503    void writeLPr() {
1504        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
1505
1506        // Keep the old settings around until we know the new ones have
1507        // been successfully written.
1508        if (mSettingsFilename.exists()) {
1509            // Presence of backup settings file indicates that we failed
1510            // to persist settings earlier. So preserve the older
1511            // backup for future reference since the current settings
1512            // might have been corrupted.
1513            if (!mBackupSettingsFilename.exists()) {
1514                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
1515                    Slog.wtf(PackageManagerService.TAG,
1516                            "Unable to backup package manager settings, "
1517                            + " current changes will be lost at reboot");
1518                    return;
1519                }
1520            } else {
1521                mSettingsFilename.delete();
1522                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
1523            }
1524        }
1525
1526        mPastSignatures.clear();
1527
1528        try {
1529            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
1530            BufferedOutputStream str = new BufferedOutputStream(fstr);
1531
1532            //XmlSerializer serializer = XmlUtils.serializerInstance();
1533            XmlSerializer serializer = new FastXmlSerializer();
1534            serializer.setOutput(str, "utf-8");
1535            serializer.startDocument(null, true);
1536            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1537
1538            serializer.startTag(null, "packages");
1539
1540            serializer.startTag(null, "last-platform-version");
1541            serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
1542            serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
1543            serializer.attribute(null, "fingerprint", mFingerprint);
1544            serializer.endTag(null, "last-platform-version");
1545
1546            serializer.startTag(null, "database-version");
1547            serializer.attribute(null, "internal", Integer.toString(mInternalDatabaseVersion));
1548            serializer.attribute(null, "external", Integer.toString(mExternalDatabaseVersion));
1549            serializer.endTag(null, "database-version");
1550
1551            if (mVerifierDeviceIdentity != null) {
1552                serializer.startTag(null, "verifier");
1553                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
1554                serializer.endTag(null, "verifier");
1555            }
1556
1557            if (mReadExternalStorageEnforced != null) {
1558                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
1559                serializer.attribute(
1560                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
1561                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
1562            }
1563
1564            serializer.startTag(null, "permission-trees");
1565            for (BasePermission bp : mPermissionTrees.values()) {
1566                writePermissionLPr(serializer, bp);
1567            }
1568            serializer.endTag(null, "permission-trees");
1569
1570            serializer.startTag(null, "permissions");
1571            for (BasePermission bp : mPermissions.values()) {
1572                writePermissionLPr(serializer, bp);
1573            }
1574            serializer.endTag(null, "permissions");
1575
1576            for (final PackageSetting pkg : mPackages.values()) {
1577                writePackageLPr(serializer, pkg);
1578            }
1579
1580            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
1581                writeDisabledSysPackageLPr(serializer, pkg);
1582            }
1583
1584            for (final SharedUserSetting usr : mSharedUsers.values()) {
1585                serializer.startTag(null, "shared-user");
1586                serializer.attribute(null, ATTR_NAME, usr.name);
1587                serializer.attribute(null, "userId",
1588                        Integer.toString(usr.userId));
1589                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
1590                serializer.startTag(null, "perms");
1591                for (String name : usr.grantedPermissions) {
1592                    serializer.startTag(null, TAG_ITEM);
1593                    serializer.attribute(null, ATTR_NAME, name);
1594                    serializer.endTag(null, TAG_ITEM);
1595                }
1596                serializer.endTag(null, "perms");
1597                serializer.endTag(null, "shared-user");
1598            }
1599
1600            if (mPackagesToBeCleaned.size() > 0) {
1601                for (PackageCleanItem item : mPackagesToBeCleaned) {
1602                    final String userStr = Integer.toString(item.userId);
1603                    serializer.startTag(null, "cleaning-package");
1604                    serializer.attribute(null, ATTR_NAME, item.packageName);
1605                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
1606                    serializer.attribute(null, ATTR_USER, userStr);
1607                    serializer.endTag(null, "cleaning-package");
1608                }
1609            }
1610
1611            if (mRenamedPackages.size() > 0) {
1612                for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
1613                    serializer.startTag(null, "renamed-package");
1614                    serializer.attribute(null, "new", e.getKey());
1615                    serializer.attribute(null, "old", e.getValue());
1616                    serializer.endTag(null, "renamed-package");
1617                }
1618            }
1619
1620            mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
1621
1622            serializer.endTag(null, "packages");
1623
1624            serializer.endDocument();
1625
1626            str.flush();
1627            FileUtils.sync(fstr);
1628            str.close();
1629
1630            // New settings successfully written, old ones are no longer
1631            // needed.
1632            mBackupSettingsFilename.delete();
1633            FileUtils.setPermissions(mSettingsFilename.toString(),
1634                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
1635                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
1636                    -1, -1);
1637
1638            // Write package list file now, use a JournaledFile.
1639            File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
1640            JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
1641
1642            final File writeTarget = journal.chooseForWrite();
1643            fstr = new FileOutputStream(writeTarget);
1644            str = new BufferedOutputStream(fstr);
1645            try {
1646                FileUtils.setPermissions(fstr.getFD(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
1647
1648                StringBuilder sb = new StringBuilder();
1649                for (final PackageSetting pkg : mPackages.values()) {
1650                    if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
1651                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
1652                        continue;
1653                    }
1654
1655                    final ApplicationInfo ai = pkg.pkg.applicationInfo;
1656                    final String dataPath = ai.dataDir;
1657                    final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
1658                    final int[] gids = pkg.getGids();
1659
1660                    // Avoid any application that has a space in its path.
1661                    if (dataPath.indexOf(" ") >= 0)
1662                        continue;
1663
1664                    // we store on each line the following information for now:
1665                    //
1666                    // pkgName    - package name
1667                    // userId     - application-specific user id
1668                    // debugFlag  - 0 or 1 if the package is debuggable.
1669                    // dataPath   - path to package's data path
1670                    // seinfo     - seinfo label for the app (assigned at install time)
1671                    // gids       - supplementary gids this app launches with
1672                    //
1673                    // NOTE: We prefer not to expose all ApplicationInfo flags for now.
1674                    //
1675                    // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
1676                    // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
1677                    //   system/core/run-as/run-as.c
1678                    //   system/core/sdcard/sdcard.c
1679                    //   external/libselinux/src/android.c:package_info_init()
1680                    //
1681                    sb.setLength(0);
1682                    sb.append(ai.packageName);
1683                    sb.append(" ");
1684                    sb.append((int)ai.uid);
1685                    sb.append(isDebug ? " 1 " : " 0 ");
1686                    sb.append(dataPath);
1687                    sb.append(" ");
1688                    sb.append(ai.seinfo);
1689                    sb.append(" ");
1690                    if (gids != null && gids.length > 0) {
1691                        sb.append(gids[0]);
1692                        for (int i = 1; i < gids.length; i++) {
1693                            sb.append(",");
1694                            sb.append(gids[i]);
1695                        }
1696                    } else {
1697                        sb.append("none");
1698                    }
1699                    sb.append("\n");
1700                    str.write(sb.toString().getBytes());
1701                }
1702                str.flush();
1703                FileUtils.sync(fstr);
1704                str.close();
1705                journal.commit();
1706            } catch (Exception e) {
1707                Slog.wtf(TAG, "Failed to write packages.list", e);
1708                IoUtils.closeQuietly(str);
1709                journal.rollback();
1710            }
1711
1712            writeAllUsersPackageRestrictionsLPr();
1713            return;
1714
1715        } catch(XmlPullParserException e) {
1716            Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1717                    + "current changes will be lost at reboot", e);
1718        } catch(java.io.IOException e) {
1719            Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1720                    + "current changes will be lost at reboot", e);
1721        }
1722        // Clean up partially written files
1723        if (mSettingsFilename.exists()) {
1724            if (!mSettingsFilename.delete()) {
1725                Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
1726                        + mSettingsFilename);
1727            }
1728        }
1729        //Debug.stopMethodTracing();
1730    }
1731
1732    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1733            throws java.io.IOException {
1734        serializer.startTag(null, "updated-package");
1735        serializer.attribute(null, ATTR_NAME, pkg.name);
1736        if (pkg.realName != null) {
1737            serializer.attribute(null, "realName", pkg.realName);
1738        }
1739        serializer.attribute(null, "codePath", pkg.codePathString);
1740        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1741        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1742        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1743        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1744        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1745            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1746        }
1747        if (pkg.legacyNativeLibraryPathString != null) {
1748            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
1749        }
1750        if (pkg.primaryCpuAbiString != null) {
1751           serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
1752        }
1753        if (pkg.secondaryCpuAbiString != null) {
1754            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
1755        }
1756        if (pkg.cpuAbiOverrideString != null) {
1757            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
1758        }
1759
1760        if (pkg.sharedUser == null) {
1761            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1762        } else {
1763            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1764        }
1765        serializer.startTag(null, "perms");
1766        if (pkg.sharedUser == null) {
1767            // If this is a shared user, the permissions will
1768            // be written there. We still need to write an
1769            // empty permissions list so permissionsFixed will
1770            // be set.
1771            for (final String name : pkg.grantedPermissions) {
1772                BasePermission bp = mPermissions.get(name);
1773                if (bp != null) {
1774                    // We only need to write signature or system permissions but
1775                    // this wont
1776                    // match the semantics of grantedPermissions. So write all
1777                    // permissions.
1778                    serializer.startTag(null, TAG_ITEM);
1779                    serializer.attribute(null, ATTR_NAME, name);
1780                    serializer.endTag(null, TAG_ITEM);
1781                }
1782            }
1783        }
1784        serializer.endTag(null, "perms");
1785        serializer.endTag(null, "updated-package");
1786    }
1787
1788    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1789            throws java.io.IOException {
1790        serializer.startTag(null, "package");
1791        serializer.attribute(null, ATTR_NAME, pkg.name);
1792        if (pkg.realName != null) {
1793            serializer.attribute(null, "realName", pkg.realName);
1794        }
1795        serializer.attribute(null, "codePath", pkg.codePathString);
1796        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1797            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1798        }
1799
1800        if (pkg.legacyNativeLibraryPathString != null) {
1801            serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString);
1802        }
1803        if (pkg.primaryCpuAbiString != null) {
1804            serializer.attribute(null, "primaryCpuAbi", pkg.primaryCpuAbiString);
1805        }
1806        if (pkg.secondaryCpuAbiString != null) {
1807            serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString);
1808        }
1809        if (pkg.cpuAbiOverrideString != null) {
1810            serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString);
1811        }
1812
1813        serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1814        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1815        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1816        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1817        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1818        if (pkg.sharedUser == null) {
1819            serializer.attribute(null, "userId", Integer.toString(pkg.appId));
1820        } else {
1821            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
1822        }
1823        if (pkg.uidError) {
1824            serializer.attribute(null, "uidError", "true");
1825        }
1826        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1827            serializer.attribute(null, "installStatus", "false");
1828        }
1829        if (pkg.installerPackageName != null) {
1830            serializer.attribute(null, "installer", pkg.installerPackageName);
1831        }
1832        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1833        if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1834            serializer.startTag(null, "perms");
1835            if (pkg.sharedUser == null) {
1836                // If this is a shared user, the permissions will
1837                // be written there. We still need to write an
1838                // empty permissions list so permissionsFixed will
1839                // be set.
1840                for (final String name : pkg.grantedPermissions) {
1841                    serializer.startTag(null, TAG_ITEM);
1842                    serializer.attribute(null, ATTR_NAME, name);
1843                    serializer.endTag(null, TAG_ITEM);
1844                }
1845            }
1846            serializer.endTag(null, "perms");
1847        }
1848
1849        writeSigningKeySetsLPr(serializer, pkg.keySetData);
1850        writeUpgradeKeySetsLPr(serializer, pkg.keySetData);
1851        writeKeySetAliasesLPr(serializer, pkg.keySetData);
1852
1853        serializer.endTag(null, "package");
1854    }
1855
1856    void writeSigningKeySetsLPr(XmlSerializer serializer,
1857            PackageKeySetData data) throws IOException {
1858        if (data.getSigningKeySets() != null) {
1859            // Keep track of the original signing-keyset.
1860            // Must be recorded first, since it will be read first and wipe the
1861            // current signing-keysets for the package when set.
1862            long properSigningKeySet = data.getProperSigningKeySet();
1863            serializer.startTag(null, "proper-signing-keyset");
1864            serializer.attribute(null, "identifier", Long.toString(properSigningKeySet));
1865            serializer.endTag(null, "proper-signing-keyset");
1866            for (long id : data.getSigningKeySets()) {
1867                serializer.startTag(null, "signing-keyset");
1868                serializer.attribute(null, "identifier", Long.toString(id));
1869                serializer.endTag(null, "signing-keyset");
1870            }
1871        }
1872    }
1873
1874    void writeUpgradeKeySetsLPr(XmlSerializer serializer,
1875            PackageKeySetData data) throws IOException {
1876        if (data.isUsingUpgradeKeySets()) {
1877            for (long id : data.getUpgradeKeySets()) {
1878                serializer.startTag(null, "upgrade-keyset");
1879                serializer.attribute(null, "identifier", Long.toString(id));
1880                serializer.endTag(null, "upgrade-keyset");
1881            }
1882        }
1883    }
1884
1885    void writeKeySetAliasesLPr(XmlSerializer serializer,
1886            PackageKeySetData data) throws IOException {
1887        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
1888            serializer.startTag(null, "defined-keyset");
1889            serializer.attribute(null, "alias", e.getKey());
1890            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
1891            serializer.endTag(null, "defined-keyset");
1892        }
1893    }
1894
1895    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1896            throws XmlPullParserException, java.io.IOException {
1897        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1898            serializer.startTag(null, TAG_ITEM);
1899            serializer.attribute(null, ATTR_NAME, bp.name);
1900            serializer.attribute(null, "package", bp.sourcePackage);
1901            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1902                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1903            }
1904            if (PackageManagerService.DEBUG_SETTINGS)
1905                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1906                        + bp.type);
1907            if (bp.type == BasePermission.TYPE_DYNAMIC) {
1908                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1909                if (pi != null) {
1910                    serializer.attribute(null, "type", "dynamic");
1911                    if (pi.icon != 0) {
1912                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
1913                    }
1914                    if (pi.nonLocalizedLabel != null) {
1915                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1916                    }
1917                }
1918            }
1919            serializer.endTag(null, TAG_ITEM);
1920        }
1921    }
1922
1923    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
1924        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
1925        final Iterator<String> its = kList.iterator();
1926        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
1927        while (its.hasNext()) {
1928            final String key = its.next();
1929            final PackageSetting ps = mPackages.get(key);
1930            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1931                ret.add(ps);
1932            }
1933        }
1934        return ret;
1935    }
1936
1937    void addPackageToCleanLPw(PackageCleanItem pkg) {
1938        if (!mPackagesToBeCleaned.contains(pkg)) {
1939            mPackagesToBeCleaned.add(pkg);
1940        }
1941    }
1942
1943    boolean readLPw(PackageManagerService service, List<UserInfo> users, int sdkVersion,
1944            boolean onlyCore) {
1945        FileInputStream str = null;
1946        if (mBackupSettingsFilename.exists()) {
1947            try {
1948                str = new FileInputStream(mBackupSettingsFilename);
1949                mReadMessages.append("Reading from backup settings file\n");
1950                PackageManagerService.reportSettingsProblem(Log.INFO,
1951                        "Need to read from backup settings file");
1952                if (mSettingsFilename.exists()) {
1953                    // If both the backup and settings file exist, we
1954                    // ignore the settings since it might have been
1955                    // corrupted.
1956                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
1957                            + mSettingsFilename);
1958                    mSettingsFilename.delete();
1959                }
1960            } catch (java.io.IOException e) {
1961                // We'll try for the normal settings file.
1962            }
1963        }
1964
1965        mPendingPackages.clear();
1966        mPastSignatures.clear();
1967
1968        try {
1969            if (str == null) {
1970                if (!mSettingsFilename.exists()) {
1971                    mReadMessages.append("No settings file found\n");
1972                    PackageManagerService.reportSettingsProblem(Log.INFO,
1973                            "No settings file; creating initial state");
1974                    mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion;
1975                    mFingerprint = Build.FINGERPRINT;
1976                    return false;
1977                }
1978                str = new FileInputStream(mSettingsFilename);
1979            }
1980            XmlPullParser parser = Xml.newPullParser();
1981            parser.setInput(str, null);
1982
1983            int type;
1984            while ((type = parser.next()) != XmlPullParser.START_TAG
1985                    && type != XmlPullParser.END_DOCUMENT) {
1986                ;
1987            }
1988
1989            if (type != XmlPullParser.START_TAG) {
1990                mReadMessages.append("No start tag found in settings file\n");
1991                PackageManagerService.reportSettingsProblem(Log.WARN,
1992                        "No start tag found in package manager settings");
1993                Slog.wtf(PackageManagerService.TAG,
1994                        "No start tag found in package manager settings");
1995                return false;
1996            }
1997
1998            int outerDepth = parser.getDepth();
1999            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2000                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2001                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2002                    continue;
2003                }
2004
2005                String tagName = parser.getName();
2006                if (tagName.equals("package")) {
2007                    readPackageLPw(parser);
2008                } else if (tagName.equals("permissions")) {
2009                    readPermissionsLPw(mPermissions, parser);
2010                } else if (tagName.equals("permission-trees")) {
2011                    readPermissionsLPw(mPermissionTrees, parser);
2012                } else if (tagName.equals("shared-user")) {
2013                    readSharedUserLPw(parser);
2014                } else if (tagName.equals("preferred-packages")) {
2015                    // no longer used.
2016                } else if (tagName.equals("preferred-activities")) {
2017                    // Upgrading from old single-user implementation;
2018                    // these are the preferred activities for user 0.
2019                    readPreferredActivitiesLPw(parser, 0);
2020                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
2021                    // TODO: check whether this is okay! as it is very
2022                    // similar to how preferred-activities are treated
2023                    readPersistentPreferredActivitiesLPw(parser, 0);
2024                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
2025                    // TODO: check whether this is okay! as it is very
2026                    // similar to how preferred-activities are treated
2027                    readCrossProfileIntentFiltersLPw(parser, 0);
2028                } else if (tagName.equals("updated-package")) {
2029                    readDisabledSysPackageLPw(parser);
2030                } else if (tagName.equals("cleaning-package")) {
2031                    String name = parser.getAttributeValue(null, ATTR_NAME);
2032                    String userStr = parser.getAttributeValue(null, ATTR_USER);
2033                    String codeStr = parser.getAttributeValue(null, ATTR_CODE);
2034                    if (name != null) {
2035                        int userId = 0;
2036                        boolean andCode = true;
2037                        try {
2038                            if (userStr != null) {
2039                                userId = Integer.parseInt(userStr);
2040                            }
2041                        } catch (NumberFormatException e) {
2042                        }
2043                        if (codeStr != null) {
2044                            andCode = Boolean.parseBoolean(codeStr);
2045                        }
2046                        addPackageToCleanLPw(new PackageCleanItem(userId, name, andCode));
2047                    }
2048                } else if (tagName.equals("renamed-package")) {
2049                    String nname = parser.getAttributeValue(null, "new");
2050                    String oname = parser.getAttributeValue(null, "old");
2051                    if (nname != null && oname != null) {
2052                        mRenamedPackages.put(nname, oname);
2053                    }
2054                } else if (tagName.equals("last-platform-version")) {
2055                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
2056                    try {
2057                        String internal = parser.getAttributeValue(null, "internal");
2058                        if (internal != null) {
2059                            mInternalSdkPlatform = Integer.parseInt(internal);
2060                        }
2061                        String external = parser.getAttributeValue(null, "external");
2062                        if (external != null) {
2063                            mExternalSdkPlatform = Integer.parseInt(external);
2064                        }
2065                    } catch (NumberFormatException e) {
2066                    }
2067                    mFingerprint = parser.getAttributeValue(null, "fingerprint");
2068                } else if (tagName.equals("database-version")) {
2069                    mInternalDatabaseVersion = mExternalDatabaseVersion = 0;
2070                    try {
2071                        String internalDbVersionString = parser.getAttributeValue(null, "internal");
2072                        if (internalDbVersionString != null) {
2073                            mInternalDatabaseVersion = Integer.parseInt(internalDbVersionString);
2074                        }
2075                        String externalDbVersionString = parser.getAttributeValue(null, "external");
2076                        if (externalDbVersionString != null) {
2077                            mExternalDatabaseVersion = Integer.parseInt(externalDbVersionString);
2078                        }
2079                    } catch (NumberFormatException ignored) {
2080                    }
2081                } else if (tagName.equals("verifier")) {
2082                    final String deviceIdentity = parser.getAttributeValue(null, "device");
2083                    try {
2084                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
2085                    } catch (IllegalArgumentException e) {
2086                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
2087                                + e.getMessage());
2088                    }
2089                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
2090                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
2091                    mReadExternalStorageEnforced = "1".equals(enforcement);
2092                } else if (tagName.equals("keyset-settings")) {
2093                    mKeySetManagerService.readKeySetsLPw(parser);
2094                } else {
2095                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
2096                            + parser.getName());
2097                    XmlUtils.skipCurrentTag(parser);
2098                }
2099            }
2100
2101            str.close();
2102
2103        } catch (XmlPullParserException e) {
2104            mReadMessages.append("Error reading: " + e.toString());
2105            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2106            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2107
2108        } catch (java.io.IOException e) {
2109            mReadMessages.append("Error reading: " + e.toString());
2110            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
2111            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
2112        }
2113
2114        final int N = mPendingPackages.size();
2115        for (int i = 0; i < N; i++) {
2116            final PendingPackage pp = mPendingPackages.get(i);
2117            Object idObj = getUserIdLPr(pp.sharedId);
2118            if (idObj != null && idObj instanceof SharedUserSetting) {
2119                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
2120                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
2121                        pp.legacyNativeLibraryPathString, pp.primaryCpuAbiString,
2122                        pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags, null,
2123                        true /* add */, false /* allowInstall */);
2124                if (p == null) {
2125                    PackageManagerService.reportSettingsProblem(Log.WARN,
2126                            "Unable to create application package for " + pp.name);
2127                    continue;
2128                }
2129                p.copyFrom(pp);
2130            } else if (idObj != null) {
2131                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2132                        + pp.sharedId + " that is not a shared uid\n";
2133                mReadMessages.append(msg);
2134                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2135            } else {
2136                String msg = "Bad package setting: package " + pp.name + " has shared uid "
2137                        + pp.sharedId + " that is not defined\n";
2138                mReadMessages.append(msg);
2139                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
2140            }
2141        }
2142        mPendingPackages.clear();
2143
2144        if (mBackupStoppedPackagesFilename.exists()
2145                || mStoppedPackagesFilename.exists()) {
2146            // Read old file
2147            readStoppedLPw();
2148            mBackupStoppedPackagesFilename.delete();
2149            mStoppedPackagesFilename.delete();
2150            // Migrate to new file format
2151            writePackageRestrictionsLPr(0);
2152        } else {
2153            if (users == null) {
2154                readPackageRestrictionsLPr(0);
2155            } else {
2156                for (UserInfo user : users) {
2157                    readPackageRestrictionsLPr(user.id);
2158                }
2159            }
2160        }
2161
2162        /*
2163         * Make sure all the updated system packages have their shared users
2164         * associated with them.
2165         */
2166        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
2167        while (disabledIt.hasNext()) {
2168            final PackageSetting disabledPs = disabledIt.next();
2169            final Object id = getUserIdLPr(disabledPs.appId);
2170            if (id != null && id instanceof SharedUserSetting) {
2171                disabledPs.sharedUser = (SharedUserSetting) id;
2172            }
2173        }
2174
2175        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
2176                + mSharedUsers.size() + " shared uids\n");
2177
2178        return true;
2179    }
2180
2181    void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
2182        // First pull data from any pre-installed apps.
2183        for (PackageSetting ps : mPackages.values()) {
2184            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
2185                    && ps.pkg.preferredActivityFilters != null) {
2186                ArrayList<PackageParser.ActivityIntentInfo> intents
2187                        = ps.pkg.preferredActivityFilters;
2188                for (int i=0; i<intents.size(); i++) {
2189                    PackageParser.ActivityIntentInfo aii = intents.get(i);
2190                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
2191                            ps.name, aii.activity.className), userId);
2192                }
2193            }
2194        }
2195
2196        // Read preferred apps from .../etc/preferred-apps directory.
2197        File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
2198        if (!preferredDir.exists() || !preferredDir.isDirectory()) {
2199            return;
2200        }
2201        if (!preferredDir.canRead()) {
2202            Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
2203            return;
2204        }
2205
2206        // Iterate over the files in the directory and scan .xml files
2207        for (File f : preferredDir.listFiles()) {
2208            if (!f.getPath().endsWith(".xml")) {
2209                Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
2210                continue;
2211            }
2212            if (!f.canRead()) {
2213                Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
2214                continue;
2215            }
2216
2217            if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Reading default preferred " + f);
2218            FileInputStream str = null;
2219            try {
2220                str = new FileInputStream(f);
2221                XmlPullParser parser = Xml.newPullParser();
2222                parser.setInput(str, null);
2223
2224                int type;
2225                while ((type = parser.next()) != XmlPullParser.START_TAG
2226                        && type != XmlPullParser.END_DOCUMENT) {
2227                    ;
2228                }
2229
2230                if (type != XmlPullParser.START_TAG) {
2231                    Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
2232                    continue;
2233                }
2234                if (!"preferred-activities".equals(parser.getName())) {
2235                    Slog.w(TAG, "Preferred apps file " + f
2236                            + " does not start with 'preferred-activities'");
2237                    continue;
2238                }
2239                readDefaultPreferredActivitiesLPw(service, parser, userId);
2240            } catch (XmlPullParserException e) {
2241                Slog.w(TAG, "Error reading apps file " + f, e);
2242            } catch (IOException e) {
2243                Slog.w(TAG, "Error reading apps file " + f, e);
2244            } finally {
2245                if (str != null) {
2246                    try {
2247                        str.close();
2248                    } catch (IOException e) {
2249                    }
2250                }
2251            }
2252        }
2253    }
2254
2255    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2256            IntentFilter tmpPa, ComponentName cn, int userId) {
2257        // The initial preferences only specify the target activity
2258        // component and intent-filter, not the set of matches.  So we
2259        // now need to query for the matches to build the correct
2260        // preferred activity entry.
2261        if (PackageManagerService.DEBUG_PREFERRED) {
2262            Log.d(TAG, "Processing preferred:");
2263            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
2264        }
2265        Intent intent = new Intent();
2266        int flags = 0;
2267        intent.setAction(tmpPa.getAction(0));
2268        for (int i=0; i<tmpPa.countCategories(); i++) {
2269            String cat = tmpPa.getCategory(i);
2270            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
2271                flags |= PackageManager.MATCH_DEFAULT_ONLY;
2272            } else {
2273                intent.addCategory(cat);
2274            }
2275        }
2276
2277        boolean doNonData = true;
2278        boolean hasSchemes = false;
2279
2280        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2281            boolean doScheme = true;
2282            String scheme = tmpPa.getDataScheme(ischeme);
2283            if (scheme != null && !scheme.isEmpty()) {
2284                hasSchemes = true;
2285            }
2286            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
2287                Uri.Builder builder = new Uri.Builder();
2288                builder.scheme(scheme);
2289                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
2290                builder.opaquePart(ssp.getPath());
2291                Intent finalIntent = new Intent(intent);
2292                finalIntent.setData(builder.build());
2293                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2294                        scheme, ssp, null, null, userId);
2295                doScheme = false;
2296            }
2297            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
2298                boolean doAuth = true;
2299                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
2300                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
2301                    Uri.Builder builder = new Uri.Builder();
2302                    builder.scheme(scheme);
2303                    if (auth.getHost() != null) {
2304                        builder.authority(auth.getHost());
2305                    }
2306                    PatternMatcher path = tmpPa.getDataPath(ipath);
2307                    builder.path(path.getPath());
2308                    Intent finalIntent = new Intent(intent);
2309                    finalIntent.setData(builder.build());
2310                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2311                            scheme, null, auth, path, userId);
2312                    doAuth = doScheme = false;
2313                }
2314                if (doAuth) {
2315                    Uri.Builder builder = new Uri.Builder();
2316                    builder.scheme(scheme);
2317                    if (auth.getHost() != null) {
2318                        builder.authority(auth.getHost());
2319                    }
2320                    Intent finalIntent = new Intent(intent);
2321                    finalIntent.setData(builder.build());
2322                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2323                            scheme, null, auth, null, userId);
2324                    doScheme = false;
2325                }
2326            }
2327            if (doScheme) {
2328                Uri.Builder builder = new Uri.Builder();
2329                builder.scheme(scheme);
2330                Intent finalIntent = new Intent(intent);
2331                finalIntent.setData(builder.build());
2332                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2333                        scheme, null, null, null, userId);
2334            }
2335            doNonData = false;
2336        }
2337
2338        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
2339            String mimeType = tmpPa.getDataType(idata);
2340            if (hasSchemes) {
2341                Uri.Builder builder = new Uri.Builder();
2342                for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
2343                    String scheme = tmpPa.getDataScheme(ischeme);
2344                    if (scheme != null && !scheme.isEmpty()) {
2345                        Intent finalIntent = new Intent(intent);
2346                        builder.scheme(scheme);
2347                        finalIntent.setDataAndType(builder.build(), mimeType);
2348                        applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2349                                scheme, null, null, null, userId);
2350                    }
2351                }
2352            } else {
2353                Intent finalIntent = new Intent(intent);
2354                finalIntent.setType(mimeType);
2355                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
2356                        null, null, null, null, userId);
2357            }
2358            doNonData = false;
2359        }
2360
2361        if (doNonData) {
2362            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
2363                    null, null, null, null, userId);
2364        }
2365    }
2366
2367    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
2368            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
2369            IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
2370        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
2371                intent.getType(), flags, 0);
2372        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
2373                + " results: " + ri);
2374        int match = 0;
2375        if (ri != null && ri.size() > 1) {
2376            boolean haveAct = false;
2377            ComponentName haveNonSys = null;
2378            ComponentName[] set = new ComponentName[ri.size()];
2379            for (int i=0; i<ri.size(); i++) {
2380                ActivityInfo ai = ri.get(i).activityInfo;
2381                set[i] = new ComponentName(ai.packageName, ai.name);
2382                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
2383                    if (ri.get(i).match >= match) {
2384                        // If any of the matches are not system apps, then
2385                        // there is a third party app that is now an option...
2386                        // so don't set a default since we don't want to hide it.
2387                        // Only do this if the match of this one is at least as good
2388                        // as what we have found as the built-in app; if it isn't
2389                        // as good, the user won't want it anyway, right?
2390                        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2391                                + ai.packageName + "/" + ai.name + ": non-system!");
2392                        haveNonSys = set[i];
2393                        break;
2394                    }
2395                } else if (cn.getPackageName().equals(ai.packageName)
2396                        && cn.getClassName().equals(ai.name)) {
2397                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2398                            + ai.packageName + "/" + ai.name + ": default!");
2399                    haveAct = true;
2400                    match = ri.get(i).match;
2401                } else {
2402                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2403                            + ai.packageName + "/" + ai.name + ": skipped");
2404                }
2405            }
2406            if (haveAct && haveNonSys == null) {
2407                IntentFilter filter = new IntentFilter();
2408                if (intent.getAction() != null) {
2409                    filter.addAction(intent.getAction());
2410                }
2411                if (intent.getCategories() != null) {
2412                    for (String cat : intent.getCategories()) {
2413                        filter.addCategory(cat);
2414                    }
2415                }
2416                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
2417                    filter.addCategory(Intent.CATEGORY_DEFAULT);
2418                }
2419                if (scheme != null) {
2420                    filter.addDataScheme(scheme);
2421                }
2422                if (ssp != null) {
2423                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
2424                }
2425                if (auth != null) {
2426                    filter.addDataAuthority(auth);
2427                }
2428                if (path != null) {
2429                    filter.addDataPath(path);
2430                }
2431                if (intent.getType() != null) {
2432                    try {
2433                        filter.addDataType(intent.getType());
2434                    } catch (IntentFilter.MalformedMimeTypeException ex) {
2435                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
2436                    }
2437                }
2438                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
2439                editPreferredActivitiesLPw(userId).addFilter(pa);
2440            } else if (haveNonSys == null) {
2441                StringBuilder sb = new StringBuilder();
2442                sb.append("No component ");
2443                sb.append(cn.flattenToShortString());
2444                sb.append(" found setting preferred ");
2445                sb.append(intent);
2446                sb.append("; possible matches are ");
2447                for (int i=0; i<set.length; i++) {
2448                    if (i > 0) sb.append(", ");
2449                    sb.append(set[i].flattenToShortString());
2450                }
2451                Slog.w(TAG, sb.toString());
2452            } else {
2453                Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
2454                        + haveNonSys.flattenToShortString());
2455            }
2456        } else {
2457            Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
2458                    + cn.flattenToShortString());
2459        }
2460    }
2461
2462    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
2463            XmlPullParser parser, int userId)
2464            throws XmlPullParserException, IOException {
2465        int outerDepth = parser.getDepth();
2466        int type;
2467        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2468                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2469            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2470                continue;
2471            }
2472
2473            String tagName = parser.getName();
2474            if (tagName.equals(TAG_ITEM)) {
2475                PreferredActivity tmpPa = new PreferredActivity(parser);
2476                if (tmpPa.mPref.getParseError() == null) {
2477                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
2478                            userId);
2479                } else {
2480                    PackageManagerService.reportSettingsProblem(Log.WARN,
2481                            "Error in package manager settings: <preferred-activity> "
2482                                    + tmpPa.mPref.getParseError() + " at "
2483                                    + parser.getPositionDescription());
2484                }
2485            } else {
2486                PackageManagerService.reportSettingsProblem(Log.WARN,
2487                        "Unknown element under <preferred-activities>: " + parser.getName());
2488                XmlUtils.skipCurrentTag(parser);
2489            }
2490        }
2491    }
2492
2493    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
2494        String v = parser.getAttributeValue(ns, name);
2495        try {
2496            if (v == null) {
2497                return defValue;
2498            }
2499            return Integer.parseInt(v);
2500        } catch (NumberFormatException e) {
2501            PackageManagerService.reportSettingsProblem(Log.WARN,
2502                    "Error in package manager settings: attribute " + name
2503                            + " has bad integer value " + v + " at "
2504                            + parser.getPositionDescription());
2505        }
2506        return defValue;
2507    }
2508
2509    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
2510            throws IOException, XmlPullParserException {
2511        int outerDepth = parser.getDepth();
2512        int type;
2513        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2514                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2515            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2516                continue;
2517            }
2518
2519            final String tagName = parser.getName();
2520            if (tagName.equals(TAG_ITEM)) {
2521                final String name = parser.getAttributeValue(null, ATTR_NAME);
2522                final String sourcePackage = parser.getAttributeValue(null, "package");
2523                final String ptype = parser.getAttributeValue(null, "type");
2524                if (name != null && sourcePackage != null) {
2525                    final boolean dynamic = "dynamic".equals(ptype);
2526                    final BasePermission bp = new BasePermission(name, sourcePackage,
2527                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
2528                    bp.protectionLevel = readInt(parser, null, "protection",
2529                            PermissionInfo.PROTECTION_NORMAL);
2530                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
2531                    if (dynamic) {
2532                        PermissionInfo pi = new PermissionInfo();
2533                        pi.packageName = sourcePackage.intern();
2534                        pi.name = name.intern();
2535                        pi.icon = readInt(parser, null, "icon", 0);
2536                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
2537                        pi.protectionLevel = bp.protectionLevel;
2538                        bp.pendingInfo = pi;
2539                    }
2540                    out.put(bp.name, bp);
2541                } else {
2542                    PackageManagerService.reportSettingsProblem(Log.WARN,
2543                            "Error in package manager settings: permissions has" + " no name at "
2544                                    + parser.getPositionDescription());
2545                }
2546            } else {
2547                PackageManagerService.reportSettingsProblem(Log.WARN,
2548                        "Unknown element reading permissions: " + parser.getName() + " at "
2549                                + parser.getPositionDescription());
2550            }
2551            XmlUtils.skipCurrentTag(parser);
2552        }
2553    }
2554
2555    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
2556            IOException {
2557        String name = parser.getAttributeValue(null, ATTR_NAME);
2558        String realName = parser.getAttributeValue(null, "realName");
2559        String codePathStr = parser.getAttributeValue(null, "codePath");
2560        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2561
2562        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
2563        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2564
2565        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
2566        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
2567        String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
2568
2569        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
2570            primaryCpuAbiStr = legacyCpuAbiStr;
2571        }
2572
2573        if (resourcePathStr == null) {
2574            resourcePathStr = codePathStr;
2575        }
2576        String version = parser.getAttributeValue(null, "version");
2577        int versionCode = 0;
2578        if (version != null) {
2579            try {
2580                versionCode = Integer.parseInt(version);
2581            } catch (NumberFormatException e) {
2582            }
2583        }
2584
2585        int pkgFlags = 0;
2586        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2587        final File codePathFile = new File(codePathStr);
2588        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
2589            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
2590        }
2591        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
2592                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
2593                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags);
2594        String timeStampStr = parser.getAttributeValue(null, "ft");
2595        if (timeStampStr != null) {
2596            try {
2597                long timeStamp = Long.parseLong(timeStampStr, 16);
2598                ps.setTimeStamp(timeStamp);
2599            } catch (NumberFormatException e) {
2600            }
2601        } else {
2602            timeStampStr = parser.getAttributeValue(null, "ts");
2603            if (timeStampStr != null) {
2604                try {
2605                    long timeStamp = Long.parseLong(timeStampStr);
2606                    ps.setTimeStamp(timeStamp);
2607                } catch (NumberFormatException e) {
2608                }
2609            }
2610        }
2611        timeStampStr = parser.getAttributeValue(null, "it");
2612        if (timeStampStr != null) {
2613            try {
2614                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
2615            } catch (NumberFormatException e) {
2616            }
2617        }
2618        timeStampStr = parser.getAttributeValue(null, "ut");
2619        if (timeStampStr != null) {
2620            try {
2621                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
2622            } catch (NumberFormatException e) {
2623            }
2624        }
2625        String idStr = parser.getAttributeValue(null, "userId");
2626        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
2627        if (ps.appId <= 0) {
2628            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2629            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2630        }
2631        int outerDepth = parser.getDepth();
2632        int type;
2633        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2634                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2635            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2636                continue;
2637            }
2638
2639            String tagName = parser.getName();
2640            if (tagName.equals("perms")) {
2641                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
2642            } else {
2643                PackageManagerService.reportSettingsProblem(Log.WARN,
2644                        "Unknown element under <updated-package>: " + parser.getName());
2645                XmlUtils.skipCurrentTag(parser);
2646            }
2647        }
2648
2649        mDisabledSysPackages.put(name, ps);
2650    }
2651
2652    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
2653        String name = null;
2654        String realName = null;
2655        String idStr = null;
2656        String sharedIdStr = null;
2657        String codePathStr = null;
2658        String resourcePathStr = null;
2659        String legacyCpuAbiString = null;
2660        String legacyNativeLibraryPathStr = null;
2661        String primaryCpuAbiString = null;
2662        String secondaryCpuAbiString = null;
2663        String cpuAbiOverrideString = null;
2664        String systemStr = null;
2665        String installerPackageName = null;
2666        String uidError = null;
2667        int pkgFlags = 0;
2668        long timeStamp = 0;
2669        long firstInstallTime = 0;
2670        long lastUpdateTime = 0;
2671        PackageSettingBase packageSetting = null;
2672        String version = null;
2673        int versionCode = 0;
2674        try {
2675            name = parser.getAttributeValue(null, ATTR_NAME);
2676            realName = parser.getAttributeValue(null, "realName");
2677            idStr = parser.getAttributeValue(null, "userId");
2678            uidError = parser.getAttributeValue(null, "uidError");
2679            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2680            codePathStr = parser.getAttributeValue(null, "codePath");
2681            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2682
2683            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2684
2685            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2686            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
2687            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
2688            cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
2689
2690            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
2691                primaryCpuAbiString = legacyCpuAbiString;
2692            }
2693;
2694            version = parser.getAttributeValue(null, "version");
2695            if (version != null) {
2696                try {
2697                    versionCode = Integer.parseInt(version);
2698                } catch (NumberFormatException e) {
2699                }
2700            }
2701            installerPackageName = parser.getAttributeValue(null, "installer");
2702
2703            systemStr = parser.getAttributeValue(null, "flags");
2704            if (systemStr != null) {
2705                try {
2706                    pkgFlags = Integer.parseInt(systemStr);
2707                } catch (NumberFormatException e) {
2708                }
2709            } else {
2710                // For backward compatibility
2711                systemStr = parser.getAttributeValue(null, "system");
2712                if (systemStr != null) {
2713                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
2714                            : 0;
2715                } else {
2716                    // Old settings that don't specify system... just treat
2717                    // them as system, good enough.
2718                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2719                }
2720            }
2721            String timeStampStr = parser.getAttributeValue(null, "ft");
2722            if (timeStampStr != null) {
2723                try {
2724                    timeStamp = Long.parseLong(timeStampStr, 16);
2725                } catch (NumberFormatException e) {
2726                }
2727            } else {
2728                timeStampStr = parser.getAttributeValue(null, "ts");
2729                if (timeStampStr != null) {
2730                    try {
2731                        timeStamp = Long.parseLong(timeStampStr);
2732                    } catch (NumberFormatException e) {
2733                    }
2734                }
2735            }
2736            timeStampStr = parser.getAttributeValue(null, "it");
2737            if (timeStampStr != null) {
2738                try {
2739                    firstInstallTime = Long.parseLong(timeStampStr, 16);
2740                } catch (NumberFormatException e) {
2741                }
2742            }
2743            timeStampStr = parser.getAttributeValue(null, "ut");
2744            if (timeStampStr != null) {
2745                try {
2746                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
2747                } catch (NumberFormatException e) {
2748                }
2749            }
2750            if (PackageManagerService.DEBUG_SETTINGS)
2751                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
2752                        + " sharedUserId=" + sharedIdStr);
2753            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2754            if (resourcePathStr == null) {
2755                resourcePathStr = codePathStr;
2756            }
2757            if (realName != null) {
2758                realName = realName.intern();
2759            }
2760            if (name == null) {
2761                PackageManagerService.reportSettingsProblem(Log.WARN,
2762                        "Error in package manager settings: <package> has no name at "
2763                                + parser.getPositionDescription());
2764            } else if (codePathStr == null) {
2765                PackageManagerService.reportSettingsProblem(Log.WARN,
2766                        "Error in package manager settings: <package> has no codePath at "
2767                                + parser.getPositionDescription());
2768            } else if (userId > 0) {
2769                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
2770                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
2771                        secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags);
2772                if (PackageManagerService.DEBUG_SETTINGS)
2773                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
2774                            + userId + " pkg=" + packageSetting);
2775                if (packageSetting == null) {
2776                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
2777                            + userId + " while parsing settings at "
2778                            + parser.getPositionDescription());
2779                } else {
2780                    packageSetting.setTimeStamp(timeStamp);
2781                    packageSetting.firstInstallTime = firstInstallTime;
2782                    packageSetting.lastUpdateTime = lastUpdateTime;
2783                }
2784            } else if (sharedIdStr != null) {
2785                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2786                if (userId > 0) {
2787                    packageSetting = new PendingPackage(name.intern(), realName, new File(
2788                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
2789                            primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
2790                            userId, versionCode, pkgFlags);
2791                    packageSetting.setTimeStamp(timeStamp);
2792                    packageSetting.firstInstallTime = firstInstallTime;
2793                    packageSetting.lastUpdateTime = lastUpdateTime;
2794                    mPendingPackages.add((PendingPackage) packageSetting);
2795                    if (PackageManagerService.DEBUG_SETTINGS)
2796                        Log.i(PackageManagerService.TAG, "Reading package " + name
2797                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
2798                } else {
2799                    PackageManagerService.reportSettingsProblem(Log.WARN,
2800                            "Error in package manager settings: package " + name
2801                                    + " has bad sharedId " + sharedIdStr + " at "
2802                                    + parser.getPositionDescription());
2803                }
2804            } else {
2805                PackageManagerService.reportSettingsProblem(Log.WARN,
2806                        "Error in package manager settings: package " + name + " has bad userId "
2807                                + idStr + " at " + parser.getPositionDescription());
2808            }
2809        } catch (NumberFormatException e) {
2810            PackageManagerService.reportSettingsProblem(Log.WARN,
2811                    "Error in package manager settings: package " + name + " has bad userId "
2812                            + idStr + " at " + parser.getPositionDescription());
2813        }
2814        if (packageSetting != null) {
2815            packageSetting.uidError = "true".equals(uidError);
2816            packageSetting.installerPackageName = installerPackageName;
2817            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
2818            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
2819            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
2820            // Handle legacy string here for single-user mode
2821            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
2822            if (enabledStr != null) {
2823                try {
2824                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
2825                } catch (NumberFormatException e) {
2826                    if (enabledStr.equalsIgnoreCase("true")) {
2827                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
2828                    } else if (enabledStr.equalsIgnoreCase("false")) {
2829                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
2830                    } else if (enabledStr.equalsIgnoreCase("default")) {
2831                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2832                    } else {
2833                        PackageManagerService.reportSettingsProblem(Log.WARN,
2834                                "Error in package manager settings: package " + name
2835                                        + " has bad enabled value: " + idStr + " at "
2836                                        + parser.getPositionDescription());
2837                    }
2838                }
2839            } else {
2840                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2841            }
2842
2843            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
2844            if (installStatusStr != null) {
2845                if (installStatusStr.equalsIgnoreCase("false")) {
2846                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
2847                } else {
2848                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
2849                }
2850            }
2851
2852            int outerDepth = parser.getDepth();
2853            int type;
2854            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2855                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2856                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2857                    continue;
2858                }
2859
2860                String tagName = parser.getName();
2861                // Legacy
2862                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
2863                    readDisabledComponentsLPw(packageSetting, parser, 0);
2864                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
2865                    readEnabledComponentsLPw(packageSetting, parser, 0);
2866                } else if (tagName.equals("sigs")) {
2867                    packageSetting.signatures.readXml(parser, mPastSignatures);
2868                } else if (tagName.equals("perms")) {
2869                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
2870                    packageSetting.permissionsFixed = true;
2871                } else if (tagName.equals("proper-signing-keyset")) {
2872                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2873                    packageSetting.keySetData.setProperSigningKeySet(id);
2874                } else if (tagName.equals("signing-keyset")) {
2875                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2876                    packageSetting.keySetData.addSigningKeySet(id);
2877                } else if (tagName.equals("upgrade-keyset")) {
2878                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2879                    packageSetting.keySetData.addUpgradeKeySetById(id);
2880                } else if (tagName.equals("defined-keyset")) {
2881                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2882                    String alias = parser.getAttributeValue(null, "alias");
2883                    packageSetting.keySetData.addDefinedKeySet(id, alias);
2884                } else {
2885                    PackageManagerService.reportSettingsProblem(Log.WARN,
2886                            "Unknown element under <package>: " + parser.getName());
2887                    XmlUtils.skipCurrentTag(parser);
2888                }
2889            }
2890
2891
2892        } else {
2893            XmlUtils.skipCurrentTag(parser);
2894        }
2895    }
2896
2897    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2898            int userId) throws IOException, XmlPullParserException {
2899        int outerDepth = parser.getDepth();
2900        int type;
2901        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2902                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2903            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2904                continue;
2905            }
2906
2907            String tagName = parser.getName();
2908            if (tagName.equals(TAG_ITEM)) {
2909                String name = parser.getAttributeValue(null, ATTR_NAME);
2910                if (name != null) {
2911                    packageSetting.addDisabledComponent(name.intern(), userId);
2912                } else {
2913                    PackageManagerService.reportSettingsProblem(Log.WARN,
2914                            "Error in package manager settings: <disabled-components> has"
2915                                    + " no name at " + parser.getPositionDescription());
2916                }
2917            } else {
2918                PackageManagerService.reportSettingsProblem(Log.WARN,
2919                        "Unknown element under <disabled-components>: " + parser.getName());
2920            }
2921            XmlUtils.skipCurrentTag(parser);
2922        }
2923    }
2924
2925    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2926            int userId) throws IOException, XmlPullParserException {
2927        int outerDepth = parser.getDepth();
2928        int type;
2929        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2930                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2931            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2932                continue;
2933            }
2934
2935            String tagName = parser.getName();
2936            if (tagName.equals(TAG_ITEM)) {
2937                String name = parser.getAttributeValue(null, ATTR_NAME);
2938                if (name != null) {
2939                    packageSetting.addEnabledComponent(name.intern(), userId);
2940                } else {
2941                    PackageManagerService.reportSettingsProblem(Log.WARN,
2942                            "Error in package manager settings: <enabled-components> has"
2943                                    + " no name at " + parser.getPositionDescription());
2944                }
2945            } else {
2946                PackageManagerService.reportSettingsProblem(Log.WARN,
2947                        "Unknown element under <enabled-components>: " + parser.getName());
2948            }
2949            XmlUtils.skipCurrentTag(parser);
2950        }
2951    }
2952
2953    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
2954        String name = null;
2955        String idStr = null;
2956        int pkgFlags = 0;
2957        SharedUserSetting su = null;
2958        try {
2959            name = parser.getAttributeValue(null, ATTR_NAME);
2960            idStr = parser.getAttributeValue(null, "userId");
2961            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2962            if ("true".equals(parser.getAttributeValue(null, "system"))) {
2963                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2964            }
2965            if (name == null) {
2966                PackageManagerService.reportSettingsProblem(Log.WARN,
2967                        "Error in package manager settings: <shared-user> has no name at "
2968                                + parser.getPositionDescription());
2969            } else if (userId == 0) {
2970                PackageManagerService.reportSettingsProblem(Log.WARN,
2971                        "Error in package manager settings: shared-user " + name
2972                                + " has bad userId " + idStr + " at "
2973                                + parser.getPositionDescription());
2974            } else {
2975                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
2976                    PackageManagerService
2977                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
2978                                    + parser.getPositionDescription());
2979                }
2980            }
2981        } catch (NumberFormatException e) {
2982            PackageManagerService.reportSettingsProblem(Log.WARN,
2983                    "Error in package manager settings: package " + name + " has bad userId "
2984                            + idStr + " at " + parser.getPositionDescription());
2985        }
2986        ;
2987
2988        if (su != null) {
2989            int outerDepth = parser.getDepth();
2990            int type;
2991            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2992                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2993                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2994                    continue;
2995                }
2996
2997                String tagName = parser.getName();
2998                if (tagName.equals("sigs")) {
2999                    su.signatures.readXml(parser, mPastSignatures);
3000                } else if (tagName.equals("perms")) {
3001                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
3002                } else {
3003                    PackageManagerService.reportSettingsProblem(Log.WARN,
3004                            "Unknown element under <shared-user>: " + parser.getName());
3005                    XmlUtils.skipCurrentTag(parser);
3006                }
3007            }
3008
3009        } else {
3010            XmlUtils.skipCurrentTag(parser);
3011        }
3012    }
3013
3014    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
3015            throws IOException, XmlPullParserException {
3016        int outerDepth = parser.getDepth();
3017        int type;
3018        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3019                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3020            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3021                continue;
3022            }
3023
3024            String tagName = parser.getName();
3025            if (tagName.equals(TAG_ITEM)) {
3026                String name = parser.getAttributeValue(null, ATTR_NAME);
3027                if (name != null) {
3028                    outPerms.add(name.intern());
3029                } else {
3030                    PackageManagerService.reportSettingsProblem(Log.WARN,
3031                            "Error in package manager settings: <perms> has" + " no name at "
3032                                    + parser.getPositionDescription());
3033                }
3034            } else {
3035                PackageManagerService.reportSettingsProblem(Log.WARN,
3036                        "Unknown element under <perms>: " + parser.getName());
3037            }
3038            XmlUtils.skipCurrentTag(parser);
3039        }
3040    }
3041
3042    void createNewUserLILPw(PackageManagerService service, Installer installer,
3043            int userHandle, File path) {
3044        path.mkdir();
3045        FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
3046                | FileUtils.S_IXOTH, -1, -1);
3047        for (PackageSetting ps : mPackages.values()) {
3048            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
3049                continue;
3050            }
3051            // Only system apps are initially installed.
3052            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
3053            // Need to create a data directory for all apps under this user.
3054            installer.createUserData(ps.name,
3055                    UserHandle.getUid(userHandle, ps.appId), userHandle,
3056                    ps.pkg.applicationInfo.seinfo);
3057        }
3058        readDefaultPreferredAppsLPw(service, userHandle);
3059        writePackageRestrictionsLPr(userHandle);
3060    }
3061
3062    void removeUserLPw(int userId) {
3063        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
3064        for (Entry<String, PackageSetting> entry : entries) {
3065            entry.getValue().removeUser(userId);
3066        }
3067        mPreferredActivities.remove(userId);
3068        File file = getUserPackagesStateFile(userId);
3069        file.delete();
3070        file = getUserPackagesStateBackupFile(userId);
3071        file.delete();
3072        removeCrossProfileIntentFiltersLPw(userId);
3073    }
3074
3075    void removeCrossProfileIntentFiltersLPw(int userId) {
3076        synchronized (mCrossProfileIntentResolvers) {
3077            // userId is the source user
3078            if (mCrossProfileIntentResolvers.get(userId) != null) {
3079                mCrossProfileIntentResolvers.remove(userId);
3080                writePackageRestrictionsLPr(userId);
3081            }
3082            // userId is the target user
3083            int count = mCrossProfileIntentResolvers.size();
3084            for (int i = 0; i < count; i++) {
3085                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
3086                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
3087                boolean needsWriting = false;
3088                HashSet<CrossProfileIntentFilter> cpifs =
3089                        new HashSet<CrossProfileIntentFilter>(cpir.filterSet());
3090                for (CrossProfileIntentFilter cpif : cpifs) {
3091                    if (cpif.getTargetUserId() == userId) {
3092                        needsWriting = true;
3093                        cpir.removeFilter(cpif);
3094                    }
3095                }
3096                if (needsWriting) {
3097                    writePackageRestrictionsLPr(sourceUserId);
3098                }
3099            }
3100        }
3101    }
3102
3103    // This should be called (at least) whenever an application is removed
3104    private void setFirstAvailableUid(int uid) {
3105        if (uid > mFirstAvailableUid) {
3106            mFirstAvailableUid = uid;
3107        }
3108    }
3109
3110    // Returns -1 if we could not find an available UserId to assign
3111    private int newUserIdLPw(Object obj) {
3112        // Let's be stupidly inefficient for now...
3113        final int N = mUserIds.size();
3114        for (int i = mFirstAvailableUid; i < N; i++) {
3115            if (mUserIds.get(i) == null) {
3116                mUserIds.set(i, obj);
3117                return Process.FIRST_APPLICATION_UID + i;
3118            }
3119        }
3120
3121        // None left?
3122        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
3123            return -1;
3124        }
3125
3126        mUserIds.add(obj);
3127        return Process.FIRST_APPLICATION_UID + N;
3128    }
3129
3130    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
3131        if (mVerifierDeviceIdentity == null) {
3132            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
3133
3134            writeLPr();
3135        }
3136
3137        return mVerifierDeviceIdentity;
3138    }
3139
3140    public PackageSetting getDisabledSystemPkgLPr(String name) {
3141        PackageSetting ps = mDisabledSysPackages.get(name);
3142        return ps;
3143    }
3144
3145    private String compToString(HashSet<String> cmp) {
3146        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
3147    }
3148
3149    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
3150        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
3151            return true;
3152        }
3153        final String pkgName = componentInfo.packageName;
3154        final PackageSetting packageSettings = mPackages.get(pkgName);
3155        if (PackageManagerService.DEBUG_SETTINGS) {
3156            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
3157                    + componentInfo.packageName + " componentName = " + componentInfo.name);
3158            Log.v(PackageManagerService.TAG, "enabledComponents: "
3159                    + compToString(packageSettings.getEnabledComponents(userId)));
3160            Log.v(PackageManagerService.TAG, "disabledComponents: "
3161                    + compToString(packageSettings.getDisabledComponents(userId)));
3162        }
3163        if (packageSettings == null) {
3164            return false;
3165        }
3166        PackageUserState ustate = packageSettings.readUserState(userId);
3167        if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
3168            if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
3169                return true;
3170            }
3171        }
3172        if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
3173                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
3174                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
3175                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
3176                    && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
3177            return false;
3178        }
3179        if (ustate.enabledComponents != null
3180                && ustate.enabledComponents.contains(componentInfo.name)) {
3181            return true;
3182        }
3183        if (ustate.disabledComponents != null
3184                && ustate.disabledComponents.contains(componentInfo.name)) {
3185            return false;
3186        }
3187        return componentInfo.enabled;
3188    }
3189
3190    String getInstallerPackageNameLPr(String packageName) {
3191        final PackageSetting pkg = mPackages.get(packageName);
3192        if (pkg == null) {
3193            throw new IllegalArgumentException("Unknown package: " + packageName);
3194        }
3195        return pkg.installerPackageName;
3196    }
3197
3198    int getApplicationEnabledSettingLPr(String packageName, int userId) {
3199        final PackageSetting pkg = mPackages.get(packageName);
3200        if (pkg == null) {
3201            throw new IllegalArgumentException("Unknown package: " + packageName);
3202        }
3203        return pkg.getEnabled(userId);
3204    }
3205
3206    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
3207        final String packageName = componentName.getPackageName();
3208        final PackageSetting pkg = mPackages.get(packageName);
3209        if (pkg == null) {
3210            throw new IllegalArgumentException("Unknown component: " + componentName);
3211        }
3212        final String classNameStr = componentName.getClassName();
3213        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
3214    }
3215
3216    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
3217            boolean allowedByPermission, int uid, int userId) {
3218        int appId = UserHandle.getAppId(uid);
3219        final PackageSetting pkgSetting = mPackages.get(packageName);
3220        if (pkgSetting == null) {
3221            throw new IllegalArgumentException("Unknown package: " + packageName);
3222        }
3223        if (!allowedByPermission && (appId != pkgSetting.appId)) {
3224            throw new SecurityException(
3225                    "Permission Denial: attempt to change stopped state from pid="
3226                    + Binder.getCallingPid()
3227                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
3228        }
3229        if (DEBUG_STOPPED) {
3230            if (stopped) {
3231                RuntimeException e = new RuntimeException("here");
3232                e.fillInStackTrace();
3233                Slog.i(TAG, "Stopping package " + packageName, e);
3234            }
3235        }
3236        if (pkgSetting.getStopped(userId) != stopped) {
3237            pkgSetting.setStopped(stopped, userId);
3238            // pkgSetting.pkg.mSetStopped = stopped;
3239            if (pkgSetting.getNotLaunched(userId)) {
3240                if (pkgSetting.installerPackageName != null) {
3241                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
3242                            pkgSetting.name, null,
3243                            pkgSetting.installerPackageName, null, new int[] {userId});
3244                }
3245                pkgSetting.setNotLaunched(false, userId);
3246            }
3247            return true;
3248        }
3249        return false;
3250    }
3251
3252    private List<UserInfo> getAllUsers() {
3253        long id = Binder.clearCallingIdentity();
3254        try {
3255            return UserManagerService.getInstance().getUsers(false);
3256        } catch (NullPointerException npe) {
3257            // packagemanager not yet initialized
3258        } finally {
3259            Binder.restoreCallingIdentity(id);
3260        }
3261        return null;
3262    }
3263
3264    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
3265        pw.print("[ ");
3266        for (int i=0; i<spec.length; i+=2) {
3267            int mask = (Integer)spec[i];
3268            if ((val & mask) != 0) {
3269                pw.print(spec[i+1]);
3270                pw.print(" ");
3271            }
3272        }
3273        pw.print("]");
3274    }
3275
3276    static final Object[] FLAG_DUMP_SPEC = new Object[] {
3277        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
3278        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
3279        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
3280        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
3281        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
3282        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
3283        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
3284        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
3285        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
3286        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
3287        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
3288        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
3289        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
3290        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
3291        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
3292        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
3293        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
3294        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
3295    };
3296
3297    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
3298            SimpleDateFormat sdf, Date date, List<UserInfo> users) {
3299        if (checkinTag != null) {
3300            pw.print(checkinTag);
3301            pw.print(",");
3302            pw.print(ps.realName != null ? ps.realName : ps.name);
3303            pw.print(",");
3304            pw.print(ps.appId);
3305            pw.print(",");
3306            pw.print(ps.versionCode);
3307            pw.print(",");
3308            pw.print(ps.firstInstallTime);
3309            pw.print(",");
3310            pw.print(ps.lastUpdateTime);
3311            pw.print(",");
3312            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
3313            pw.println();
3314            for (UserInfo user : users) {
3315                pw.print(checkinTag);
3316                pw.print("-");
3317                pw.print("usr");
3318                pw.print(",");
3319                pw.print(user.id);
3320                pw.print(",");
3321                pw.print(ps.getInstalled(user.id) ? "I" : "i");
3322                pw.print(ps.getHidden(user.id) ? "B" : "b");
3323                pw.print(ps.getStopped(user.id) ? "S" : "s");
3324                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
3325                pw.print(",");
3326                pw.print(ps.getEnabled(user.id));
3327                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3328                pw.print(",");
3329                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
3330                pw.println();
3331            }
3332            return;
3333        }
3334
3335        pw.print(prefix); pw.print("Package [");
3336            pw.print(ps.realName != null ? ps.realName : ps.name);
3337            pw.print("] (");
3338            pw.print(Integer.toHexString(System.identityHashCode(ps)));
3339            pw.println("):");
3340
3341        if (ps.realName != null) {
3342            pw.print(prefix); pw.print("  compat name=");
3343            pw.println(ps.name);
3344        }
3345
3346        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
3347                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
3348        if (ps.sharedUser != null) {
3349            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
3350        }
3351        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
3352        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
3353        pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
3354        pw.print(prefix); pw.print("  legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString);
3355        pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
3356        pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
3357        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
3358        if (ps.pkg != null) {
3359            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
3360        }
3361        pw.println();
3362        if (ps.pkg != null) {
3363            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
3364            pw.print(prefix); pw.print("  applicationInfo=");
3365                pw.println(ps.pkg.applicationInfo.toString());
3366            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
3367                    FLAG_DUMP_SPEC); pw.println();
3368            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
3369            if (ps.pkg.mOperationPending) {
3370                pw.print(prefix); pw.println("  mOperationPending=true");
3371            }
3372            pw.print(prefix); pw.print("  supportsScreens=[");
3373            boolean first = true;
3374            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
3375                if (!first)
3376                    pw.print(", ");
3377                first = false;
3378                pw.print("small");
3379            }
3380            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
3381                if (!first)
3382                    pw.print(", ");
3383                first = false;
3384                pw.print("medium");
3385            }
3386            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
3387                if (!first)
3388                    pw.print(", ");
3389                first = false;
3390                pw.print("large");
3391            }
3392            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
3393                if (!first)
3394                    pw.print(", ");
3395                first = false;
3396                pw.print("xlarge");
3397            }
3398            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
3399                if (!first)
3400                    pw.print(", ");
3401                first = false;
3402                pw.print("resizeable");
3403            }
3404            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
3405                if (!first)
3406                    pw.print(", ");
3407                first = false;
3408                pw.print("anyDensity");
3409            }
3410            pw.println("]");
3411            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
3412                pw.print(prefix); pw.println("  libraries:");
3413                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
3414                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
3415                }
3416            }
3417            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
3418                pw.print(prefix); pw.println("  usesLibraries:");
3419                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
3420                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
3421                }
3422            }
3423            if (ps.pkg.usesOptionalLibraries != null
3424                    && ps.pkg.usesOptionalLibraries.size() > 0) {
3425                pw.print(prefix); pw.println("  usesOptionalLibraries:");
3426                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
3427                    pw.print(prefix); pw.print("    ");
3428                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
3429                }
3430            }
3431            if (ps.pkg.usesLibraryFiles != null
3432                    && ps.pkg.usesLibraryFiles.length > 0) {
3433                pw.print(prefix); pw.println("  usesLibraryFiles:");
3434                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
3435                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
3436                }
3437            }
3438        }
3439        pw.print(prefix); pw.print("  timeStamp=");
3440            date.setTime(ps.timeStamp);
3441            pw.println(sdf.format(date));
3442        pw.print(prefix); pw.print("  firstInstallTime=");
3443            date.setTime(ps.firstInstallTime);
3444            pw.println(sdf.format(date));
3445        pw.print(prefix); pw.print("  lastUpdateTime=");
3446            date.setTime(ps.lastUpdateTime);
3447            pw.println(sdf.format(date));
3448        if (ps.installerPackageName != null) {
3449            pw.print(prefix); pw.print("  installerPackageName=");
3450                    pw.println(ps.installerPackageName);
3451        }
3452        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
3453        pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
3454                pw.print(" haveGids="); pw.print(ps.haveGids);
3455                pw.print(" installStatus="); pw.println(ps.installStatus);
3456        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
3457                pw.println();
3458        for (UserInfo user : users) {
3459            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
3460            pw.print(" installed=");
3461            pw.print(ps.getInstalled(user.id));
3462            pw.print(" hidden=");
3463            pw.print(ps.getHidden(user.id));
3464            pw.print(" stopped=");
3465            pw.print(ps.getStopped(user.id));
3466            pw.print(" notLaunched=");
3467            pw.print(ps.getNotLaunched(user.id));
3468            pw.print(" enabled=");
3469            pw.println(ps.getEnabled(user.id));
3470            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3471            if (lastDisabledAppCaller != null) {
3472                pw.print(prefix); pw.print("    lastDisabledCaller: ");
3473                        pw.println(lastDisabledAppCaller);
3474            }
3475            HashSet<String> cmp = ps.getDisabledComponents(user.id);
3476            if (cmp != null && cmp.size() > 0) {
3477                pw.print(prefix); pw.println("    disabledComponents:");
3478                for (String s : cmp) {
3479                    pw.print(prefix); pw.print("    "); pw.println(s);
3480                }
3481            }
3482            cmp = ps.getEnabledComponents(user.id);
3483            if (cmp != null && cmp.size() > 0) {
3484                pw.print(prefix); pw.println("    enabledComponents:");
3485                for (String s : cmp) {
3486                    pw.print(prefix); pw.print("    "); pw.println(s);
3487                }
3488            }
3489        }
3490        if (ps.grantedPermissions.size() > 0) {
3491            pw.print(prefix); pw.println("  grantedPermissions:");
3492            for (String s : ps.grantedPermissions) {
3493                pw.print(prefix); pw.print("    "); pw.println(s);
3494            }
3495        }
3496    }
3497
3498    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
3499        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3500        final Date date = new Date();
3501        boolean printedSomething = false;
3502        List<UserInfo> users = getAllUsers();
3503        for (final PackageSetting ps : mPackages.values()) {
3504            if (packageName != null && !packageName.equals(ps.realName)
3505                    && !packageName.equals(ps.name)) {
3506                continue;
3507            }
3508
3509            if (!checkin && packageName != null) {
3510                dumpState.setSharedUser(ps.sharedUser);
3511            }
3512
3513            if (!checkin && !printedSomething) {
3514                if (dumpState.onTitlePrinted())
3515                    pw.println();
3516                pw.println("Packages:");
3517                printedSomething = true;
3518            }
3519            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, ps, sdf, date, users);
3520        }
3521
3522        printedSomething = false;
3523        if (!checkin && mRenamedPackages.size() > 0) {
3524            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
3525                if (packageName != null && !packageName.equals(e.getKey())
3526                        && !packageName.equals(e.getValue())) {
3527                    continue;
3528                }
3529                if (!checkin) {
3530                    if (!printedSomething) {
3531                        if (dumpState.onTitlePrinted())
3532                            pw.println();
3533                        pw.println("Renamed packages:");
3534                        printedSomething = true;
3535                    }
3536                    pw.print("  ");
3537                } else {
3538                    pw.print("ren,");
3539                }
3540                pw.print(e.getKey());
3541                pw.print(checkin ? " -> " : ",");
3542                pw.println(e.getValue());
3543            }
3544        }
3545
3546        printedSomething = false;
3547        if (mDisabledSysPackages.size() > 0) {
3548            for (final PackageSetting ps : mDisabledSysPackages.values()) {
3549                if (packageName != null && !packageName.equals(ps.realName)
3550                        && !packageName.equals(ps.name)) {
3551                    continue;
3552                }
3553                if (!checkin && !printedSomething) {
3554                    if (dumpState.onTitlePrinted())
3555                        pw.println();
3556                    pw.println("Hidden system packages:");
3557                    printedSomething = true;
3558                }
3559                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, ps, sdf, date, users);
3560            }
3561        }
3562    }
3563
3564    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3565        boolean printedSomething = false;
3566        for (BasePermission p : mPermissions.values()) {
3567            if (packageName != null && !packageName.equals(p.sourcePackage)) {
3568                continue;
3569            }
3570            if (!printedSomething) {
3571                if (dumpState.onTitlePrinted())
3572                    pw.println();
3573                pw.println("Permissions:");
3574                printedSomething = true;
3575            }
3576            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
3577                    pw.print(Integer.toHexString(System.identityHashCode(p)));
3578                    pw.println("):");
3579            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
3580            pw.print("    uid="); pw.print(p.uid);
3581                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
3582                    pw.print(" type="); pw.print(p.type);
3583                    pw.print(" prot=");
3584                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
3585            if (p.packageSetting != null) {
3586                pw.print("    packageSetting="); pw.println(p.packageSetting);
3587            }
3588            if (p.perm != null) {
3589                pw.print("    perm="); pw.println(p.perm);
3590            }
3591            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
3592                pw.print("    enforced=");
3593                pw.println(mReadExternalStorageEnforced);
3594            }
3595        }
3596    }
3597
3598    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3599        boolean printedSomething = false;
3600        for (SharedUserSetting su : mSharedUsers.values()) {
3601            if (packageName != null && su != dumpState.getSharedUser()) {
3602                continue;
3603            }
3604            if (!printedSomething) {
3605                if (dumpState.onTitlePrinted())
3606                    pw.println();
3607                pw.println("Shared users:");
3608                printedSomething = true;
3609            }
3610            pw.print("  SharedUser [");
3611            pw.print(su.name);
3612            pw.print("] (");
3613            pw.print(Integer.toHexString(System.identityHashCode(su)));
3614                    pw.println("):");
3615            pw.print("    userId=");
3616            pw.print(su.userId);
3617            pw.print(" gids=");
3618            pw.println(PackageManagerService.arrayToString(su.gids));
3619            pw.println("    grantedPermissions:");
3620            for (String s : su.grantedPermissions) {
3621                pw.print("      ");
3622                pw.println(s);
3623            }
3624        }
3625    }
3626
3627    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
3628        pw.println("Settings parse messages:");
3629        pw.print(mReadMessages.toString());
3630    }
3631}
3632