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 systemMatch = 0;
2375        int thirdPartyMatch = 0;
2376        if (ri != null && ri.size() > 1) {
2377            boolean haveAct = false;
2378            ComponentName haveNonSys = null;
2379            ComponentName[] set = new ComponentName[ri.size()];
2380            for (int i=0; i<ri.size(); i++) {
2381                ActivityInfo ai = ri.get(i).activityInfo;
2382                set[i] = new ComponentName(ai.packageName, ai.name);
2383                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
2384                    if (ri.get(i).match >= thirdPartyMatch) {
2385                        // Keep track of the best match we find of all third
2386                        // party apps, for use later to determine if we actually
2387                        // want to set a preferred app for this intent.
2388                        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2389                                + ai.packageName + "/" + ai.name + ": non-system!");
2390                        haveNonSys = set[i];
2391                        break;
2392                    }
2393                } else if (cn.getPackageName().equals(ai.packageName)
2394                        && cn.getClassName().equals(ai.name)) {
2395                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2396                            + ai.packageName + "/" + ai.name + ": default!");
2397                    haveAct = true;
2398                    systemMatch = ri.get(i).match;
2399                } else {
2400                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
2401                            + ai.packageName + "/" + ai.name + ": skipped");
2402                }
2403            }
2404            if (haveNonSys != null && thirdPartyMatch < systemMatch) {
2405                // If we have a matching third party app, but its match is not as
2406                // good as the built-in system app, then we don't want to actually
2407                // consider it a match because presumably the built-in app is still
2408                // the thing we want users to see by default.
2409                haveNonSys = null;
2410            }
2411            if (haveAct && haveNonSys == null) {
2412                IntentFilter filter = new IntentFilter();
2413                if (intent.getAction() != null) {
2414                    filter.addAction(intent.getAction());
2415                }
2416                if (intent.getCategories() != null) {
2417                    for (String cat : intent.getCategories()) {
2418                        filter.addCategory(cat);
2419                    }
2420                }
2421                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
2422                    filter.addCategory(Intent.CATEGORY_DEFAULT);
2423                }
2424                if (scheme != null) {
2425                    filter.addDataScheme(scheme);
2426                }
2427                if (ssp != null) {
2428                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
2429                }
2430                if (auth != null) {
2431                    filter.addDataAuthority(auth);
2432                }
2433                if (path != null) {
2434                    filter.addDataPath(path);
2435                }
2436                if (intent.getType() != null) {
2437                    try {
2438                        filter.addDataType(intent.getType());
2439                    } catch (IntentFilter.MalformedMimeTypeException ex) {
2440                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
2441                    }
2442                }
2443                PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
2444                editPreferredActivitiesLPw(userId).addFilter(pa);
2445            } else if (haveNonSys == null) {
2446                StringBuilder sb = new StringBuilder();
2447                sb.append("No component ");
2448                sb.append(cn.flattenToShortString());
2449                sb.append(" found setting preferred ");
2450                sb.append(intent);
2451                sb.append("; possible matches are ");
2452                for (int i=0; i<set.length; i++) {
2453                    if (i > 0) sb.append(", ");
2454                    sb.append(set[i].flattenToShortString());
2455                }
2456                Slog.w(TAG, sb.toString());
2457            } else {
2458                Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
2459                        + haveNonSys.flattenToShortString());
2460            }
2461        } else {
2462            Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
2463                    + cn.flattenToShortString());
2464        }
2465    }
2466
2467    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
2468            XmlPullParser parser, int userId)
2469            throws XmlPullParserException, IOException {
2470        int outerDepth = parser.getDepth();
2471        int type;
2472        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2473                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2474            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2475                continue;
2476            }
2477
2478            String tagName = parser.getName();
2479            if (tagName.equals(TAG_ITEM)) {
2480                PreferredActivity tmpPa = new PreferredActivity(parser);
2481                if (tmpPa.mPref.getParseError() == null) {
2482                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
2483                            userId);
2484                } else {
2485                    PackageManagerService.reportSettingsProblem(Log.WARN,
2486                            "Error in package manager settings: <preferred-activity> "
2487                                    + tmpPa.mPref.getParseError() + " at "
2488                                    + parser.getPositionDescription());
2489                }
2490            } else {
2491                PackageManagerService.reportSettingsProblem(Log.WARN,
2492                        "Unknown element under <preferred-activities>: " + parser.getName());
2493                XmlUtils.skipCurrentTag(parser);
2494            }
2495        }
2496    }
2497
2498    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
2499        String v = parser.getAttributeValue(ns, name);
2500        try {
2501            if (v == null) {
2502                return defValue;
2503            }
2504            return Integer.parseInt(v);
2505        } catch (NumberFormatException e) {
2506            PackageManagerService.reportSettingsProblem(Log.WARN,
2507                    "Error in package manager settings: attribute " + name
2508                            + " has bad integer value " + v + " at "
2509                            + parser.getPositionDescription());
2510        }
2511        return defValue;
2512    }
2513
2514    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
2515            throws IOException, XmlPullParserException {
2516        int outerDepth = parser.getDepth();
2517        int type;
2518        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2519                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2520            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2521                continue;
2522            }
2523
2524            final String tagName = parser.getName();
2525            if (tagName.equals(TAG_ITEM)) {
2526                final String name = parser.getAttributeValue(null, ATTR_NAME);
2527                final String sourcePackage = parser.getAttributeValue(null, "package");
2528                final String ptype = parser.getAttributeValue(null, "type");
2529                if (name != null && sourcePackage != null) {
2530                    final boolean dynamic = "dynamic".equals(ptype);
2531                    final BasePermission bp = new BasePermission(name, sourcePackage,
2532                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
2533                    bp.protectionLevel = readInt(parser, null, "protection",
2534                            PermissionInfo.PROTECTION_NORMAL);
2535                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
2536                    if (dynamic) {
2537                        PermissionInfo pi = new PermissionInfo();
2538                        pi.packageName = sourcePackage.intern();
2539                        pi.name = name.intern();
2540                        pi.icon = readInt(parser, null, "icon", 0);
2541                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
2542                        pi.protectionLevel = bp.protectionLevel;
2543                        bp.pendingInfo = pi;
2544                    }
2545                    out.put(bp.name, bp);
2546                } else {
2547                    PackageManagerService.reportSettingsProblem(Log.WARN,
2548                            "Error in package manager settings: permissions has" + " no name at "
2549                                    + parser.getPositionDescription());
2550                }
2551            } else {
2552                PackageManagerService.reportSettingsProblem(Log.WARN,
2553                        "Unknown element reading permissions: " + parser.getName() + " at "
2554                                + parser.getPositionDescription());
2555            }
2556            XmlUtils.skipCurrentTag(parser);
2557        }
2558    }
2559
2560    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
2561            IOException {
2562        String name = parser.getAttributeValue(null, ATTR_NAME);
2563        String realName = parser.getAttributeValue(null, "realName");
2564        String codePathStr = parser.getAttributeValue(null, "codePath");
2565        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2566
2567        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
2568        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2569
2570        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
2571        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
2572        String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
2573
2574        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
2575            primaryCpuAbiStr = legacyCpuAbiStr;
2576        }
2577
2578        if (resourcePathStr == null) {
2579            resourcePathStr = codePathStr;
2580        }
2581        String version = parser.getAttributeValue(null, "version");
2582        int versionCode = 0;
2583        if (version != null) {
2584            try {
2585                versionCode = Integer.parseInt(version);
2586            } catch (NumberFormatException e) {
2587            }
2588        }
2589
2590        int pkgFlags = 0;
2591        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2592        final File codePathFile = new File(codePathStr);
2593        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
2594            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
2595        }
2596        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
2597                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
2598                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags);
2599        String timeStampStr = parser.getAttributeValue(null, "ft");
2600        if (timeStampStr != null) {
2601            try {
2602                long timeStamp = Long.parseLong(timeStampStr, 16);
2603                ps.setTimeStamp(timeStamp);
2604            } catch (NumberFormatException e) {
2605            }
2606        } else {
2607            timeStampStr = parser.getAttributeValue(null, "ts");
2608            if (timeStampStr != null) {
2609                try {
2610                    long timeStamp = Long.parseLong(timeStampStr);
2611                    ps.setTimeStamp(timeStamp);
2612                } catch (NumberFormatException e) {
2613                }
2614            }
2615        }
2616        timeStampStr = parser.getAttributeValue(null, "it");
2617        if (timeStampStr != null) {
2618            try {
2619                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
2620            } catch (NumberFormatException e) {
2621            }
2622        }
2623        timeStampStr = parser.getAttributeValue(null, "ut");
2624        if (timeStampStr != null) {
2625            try {
2626                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
2627            } catch (NumberFormatException e) {
2628            }
2629        }
2630        String idStr = parser.getAttributeValue(null, "userId");
2631        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
2632        if (ps.appId <= 0) {
2633            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2634            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2635        }
2636        int outerDepth = parser.getDepth();
2637        int type;
2638        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2639                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2640            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2641                continue;
2642            }
2643
2644            String tagName = parser.getName();
2645            if (tagName.equals("perms")) {
2646                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
2647            } else {
2648                PackageManagerService.reportSettingsProblem(Log.WARN,
2649                        "Unknown element under <updated-package>: " + parser.getName());
2650                XmlUtils.skipCurrentTag(parser);
2651            }
2652        }
2653
2654        mDisabledSysPackages.put(name, ps);
2655    }
2656
2657    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
2658        String name = null;
2659        String realName = null;
2660        String idStr = null;
2661        String sharedIdStr = null;
2662        String codePathStr = null;
2663        String resourcePathStr = null;
2664        String legacyCpuAbiString = null;
2665        String legacyNativeLibraryPathStr = null;
2666        String primaryCpuAbiString = null;
2667        String secondaryCpuAbiString = null;
2668        String cpuAbiOverrideString = null;
2669        String systemStr = null;
2670        String installerPackageName = null;
2671        String uidError = null;
2672        int pkgFlags = 0;
2673        long timeStamp = 0;
2674        long firstInstallTime = 0;
2675        long lastUpdateTime = 0;
2676        PackageSettingBase packageSetting = null;
2677        String version = null;
2678        int versionCode = 0;
2679        try {
2680            name = parser.getAttributeValue(null, ATTR_NAME);
2681            realName = parser.getAttributeValue(null, "realName");
2682            idStr = parser.getAttributeValue(null, "userId");
2683            uidError = parser.getAttributeValue(null, "uidError");
2684            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
2685            codePathStr = parser.getAttributeValue(null, "codePath");
2686            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
2687
2688            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
2689
2690            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
2691            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
2692            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
2693            cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
2694
2695            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
2696                primaryCpuAbiString = legacyCpuAbiString;
2697            }
2698;
2699            version = parser.getAttributeValue(null, "version");
2700            if (version != null) {
2701                try {
2702                    versionCode = Integer.parseInt(version);
2703                } catch (NumberFormatException e) {
2704                }
2705            }
2706            installerPackageName = parser.getAttributeValue(null, "installer");
2707
2708            systemStr = parser.getAttributeValue(null, "flags");
2709            if (systemStr != null) {
2710                try {
2711                    pkgFlags = Integer.parseInt(systemStr);
2712                } catch (NumberFormatException e) {
2713                }
2714            } else {
2715                // For backward compatibility
2716                systemStr = parser.getAttributeValue(null, "system");
2717                if (systemStr != null) {
2718                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
2719                            : 0;
2720                } else {
2721                    // Old settings that don't specify system... just treat
2722                    // them as system, good enough.
2723                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2724                }
2725            }
2726            String timeStampStr = parser.getAttributeValue(null, "ft");
2727            if (timeStampStr != null) {
2728                try {
2729                    timeStamp = Long.parseLong(timeStampStr, 16);
2730                } catch (NumberFormatException e) {
2731                }
2732            } else {
2733                timeStampStr = parser.getAttributeValue(null, "ts");
2734                if (timeStampStr != null) {
2735                    try {
2736                        timeStamp = Long.parseLong(timeStampStr);
2737                    } catch (NumberFormatException e) {
2738                    }
2739                }
2740            }
2741            timeStampStr = parser.getAttributeValue(null, "it");
2742            if (timeStampStr != null) {
2743                try {
2744                    firstInstallTime = Long.parseLong(timeStampStr, 16);
2745                } catch (NumberFormatException e) {
2746                }
2747            }
2748            timeStampStr = parser.getAttributeValue(null, "ut");
2749            if (timeStampStr != null) {
2750                try {
2751                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
2752                } catch (NumberFormatException e) {
2753                }
2754            }
2755            if (PackageManagerService.DEBUG_SETTINGS)
2756                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
2757                        + " sharedUserId=" + sharedIdStr);
2758            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2759            if (resourcePathStr == null) {
2760                resourcePathStr = codePathStr;
2761            }
2762            if (realName != null) {
2763                realName = realName.intern();
2764            }
2765            if (name == null) {
2766                PackageManagerService.reportSettingsProblem(Log.WARN,
2767                        "Error in package manager settings: <package> has no name at "
2768                                + parser.getPositionDescription());
2769            } else if (codePathStr == null) {
2770                PackageManagerService.reportSettingsProblem(Log.WARN,
2771                        "Error in package manager settings: <package> has no codePath at "
2772                                + parser.getPositionDescription());
2773            } else if (userId > 0) {
2774                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
2775                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
2776                        secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags);
2777                if (PackageManagerService.DEBUG_SETTINGS)
2778                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
2779                            + userId + " pkg=" + packageSetting);
2780                if (packageSetting == null) {
2781                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
2782                            + userId + " while parsing settings at "
2783                            + parser.getPositionDescription());
2784                } else {
2785                    packageSetting.setTimeStamp(timeStamp);
2786                    packageSetting.firstInstallTime = firstInstallTime;
2787                    packageSetting.lastUpdateTime = lastUpdateTime;
2788                }
2789            } else if (sharedIdStr != null) {
2790                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
2791                if (userId > 0) {
2792                    packageSetting = new PendingPackage(name.intern(), realName, new File(
2793                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
2794                            primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
2795                            userId, versionCode, pkgFlags);
2796                    packageSetting.setTimeStamp(timeStamp);
2797                    packageSetting.firstInstallTime = firstInstallTime;
2798                    packageSetting.lastUpdateTime = lastUpdateTime;
2799                    mPendingPackages.add((PendingPackage) packageSetting);
2800                    if (PackageManagerService.DEBUG_SETTINGS)
2801                        Log.i(PackageManagerService.TAG, "Reading package " + name
2802                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
2803                } else {
2804                    PackageManagerService.reportSettingsProblem(Log.WARN,
2805                            "Error in package manager settings: package " + name
2806                                    + " has bad sharedId " + sharedIdStr + " at "
2807                                    + parser.getPositionDescription());
2808                }
2809            } else {
2810                PackageManagerService.reportSettingsProblem(Log.WARN,
2811                        "Error in package manager settings: package " + name + " has bad userId "
2812                                + idStr + " at " + parser.getPositionDescription());
2813            }
2814        } catch (NumberFormatException e) {
2815            PackageManagerService.reportSettingsProblem(Log.WARN,
2816                    "Error in package manager settings: package " + name + " has bad userId "
2817                            + idStr + " at " + parser.getPositionDescription());
2818        }
2819        if (packageSetting != null) {
2820            packageSetting.uidError = "true".equals(uidError);
2821            packageSetting.installerPackageName = installerPackageName;
2822            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
2823            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
2824            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
2825            // Handle legacy string here for single-user mode
2826            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
2827            if (enabledStr != null) {
2828                try {
2829                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
2830                } catch (NumberFormatException e) {
2831                    if (enabledStr.equalsIgnoreCase("true")) {
2832                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
2833                    } else if (enabledStr.equalsIgnoreCase("false")) {
2834                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
2835                    } else if (enabledStr.equalsIgnoreCase("default")) {
2836                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2837                    } else {
2838                        PackageManagerService.reportSettingsProblem(Log.WARN,
2839                                "Error in package manager settings: package " + name
2840                                        + " has bad enabled value: " + idStr + " at "
2841                                        + parser.getPositionDescription());
2842                    }
2843                }
2844            } else {
2845                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
2846            }
2847
2848            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
2849            if (installStatusStr != null) {
2850                if (installStatusStr.equalsIgnoreCase("false")) {
2851                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
2852                } else {
2853                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
2854                }
2855            }
2856
2857            int outerDepth = parser.getDepth();
2858            int type;
2859            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2860                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2861                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2862                    continue;
2863                }
2864
2865                String tagName = parser.getName();
2866                // Legacy
2867                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
2868                    readDisabledComponentsLPw(packageSetting, parser, 0);
2869                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
2870                    readEnabledComponentsLPw(packageSetting, parser, 0);
2871                } else if (tagName.equals("sigs")) {
2872                    packageSetting.signatures.readXml(parser, mPastSignatures);
2873                } else if (tagName.equals("perms")) {
2874                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
2875                    packageSetting.permissionsFixed = true;
2876                } else if (tagName.equals("proper-signing-keyset")) {
2877                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2878                    packageSetting.keySetData.setProperSigningKeySet(id);
2879                } else if (tagName.equals("signing-keyset")) {
2880                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2881                    packageSetting.keySetData.addSigningKeySet(id);
2882                } else if (tagName.equals("upgrade-keyset")) {
2883                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2884                    packageSetting.keySetData.addUpgradeKeySetById(id);
2885                } else if (tagName.equals("defined-keyset")) {
2886                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
2887                    String alias = parser.getAttributeValue(null, "alias");
2888                    packageSetting.keySetData.addDefinedKeySet(id, alias);
2889                } else {
2890                    PackageManagerService.reportSettingsProblem(Log.WARN,
2891                            "Unknown element under <package>: " + parser.getName());
2892                    XmlUtils.skipCurrentTag(parser);
2893                }
2894            }
2895
2896
2897        } else {
2898            XmlUtils.skipCurrentTag(parser);
2899        }
2900    }
2901
2902    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2903            int userId) throws IOException, XmlPullParserException {
2904        int outerDepth = parser.getDepth();
2905        int type;
2906        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2907                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2908            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2909                continue;
2910            }
2911
2912            String tagName = parser.getName();
2913            if (tagName.equals(TAG_ITEM)) {
2914                String name = parser.getAttributeValue(null, ATTR_NAME);
2915                if (name != null) {
2916                    packageSetting.addDisabledComponent(name.intern(), userId);
2917                } else {
2918                    PackageManagerService.reportSettingsProblem(Log.WARN,
2919                            "Error in package manager settings: <disabled-components> has"
2920                                    + " no name at " + parser.getPositionDescription());
2921                }
2922            } else {
2923                PackageManagerService.reportSettingsProblem(Log.WARN,
2924                        "Unknown element under <disabled-components>: " + parser.getName());
2925            }
2926            XmlUtils.skipCurrentTag(parser);
2927        }
2928    }
2929
2930    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
2931            int userId) throws IOException, XmlPullParserException {
2932        int outerDepth = parser.getDepth();
2933        int type;
2934        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2935                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2936            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2937                continue;
2938            }
2939
2940            String tagName = parser.getName();
2941            if (tagName.equals(TAG_ITEM)) {
2942                String name = parser.getAttributeValue(null, ATTR_NAME);
2943                if (name != null) {
2944                    packageSetting.addEnabledComponent(name.intern(), userId);
2945                } else {
2946                    PackageManagerService.reportSettingsProblem(Log.WARN,
2947                            "Error in package manager settings: <enabled-components> has"
2948                                    + " no name at " + parser.getPositionDescription());
2949                }
2950            } else {
2951                PackageManagerService.reportSettingsProblem(Log.WARN,
2952                        "Unknown element under <enabled-components>: " + parser.getName());
2953            }
2954            XmlUtils.skipCurrentTag(parser);
2955        }
2956    }
2957
2958    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
2959        String name = null;
2960        String idStr = null;
2961        int pkgFlags = 0;
2962        SharedUserSetting su = null;
2963        try {
2964            name = parser.getAttributeValue(null, ATTR_NAME);
2965            idStr = parser.getAttributeValue(null, "userId");
2966            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
2967            if ("true".equals(parser.getAttributeValue(null, "system"))) {
2968                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
2969            }
2970            if (name == null) {
2971                PackageManagerService.reportSettingsProblem(Log.WARN,
2972                        "Error in package manager settings: <shared-user> has no name at "
2973                                + parser.getPositionDescription());
2974            } else if (userId == 0) {
2975                PackageManagerService.reportSettingsProblem(Log.WARN,
2976                        "Error in package manager settings: shared-user " + name
2977                                + " has bad userId " + idStr + " at "
2978                                + parser.getPositionDescription());
2979            } else {
2980                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
2981                    PackageManagerService
2982                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
2983                                    + parser.getPositionDescription());
2984                }
2985            }
2986        } catch (NumberFormatException e) {
2987            PackageManagerService.reportSettingsProblem(Log.WARN,
2988                    "Error in package manager settings: package " + name + " has bad userId "
2989                            + idStr + " at " + parser.getPositionDescription());
2990        }
2991        ;
2992
2993        if (su != null) {
2994            int outerDepth = parser.getDepth();
2995            int type;
2996            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2997                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
2998                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
2999                    continue;
3000                }
3001
3002                String tagName = parser.getName();
3003                if (tagName.equals("sigs")) {
3004                    su.signatures.readXml(parser, mPastSignatures);
3005                } else if (tagName.equals("perms")) {
3006                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
3007                } else {
3008                    PackageManagerService.reportSettingsProblem(Log.WARN,
3009                            "Unknown element under <shared-user>: " + parser.getName());
3010                    XmlUtils.skipCurrentTag(parser);
3011                }
3012            }
3013
3014        } else {
3015            XmlUtils.skipCurrentTag(parser);
3016        }
3017    }
3018
3019    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
3020            throws IOException, XmlPullParserException {
3021        int outerDepth = parser.getDepth();
3022        int type;
3023        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3024                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3025            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3026                continue;
3027            }
3028
3029            String tagName = parser.getName();
3030            if (tagName.equals(TAG_ITEM)) {
3031                String name = parser.getAttributeValue(null, ATTR_NAME);
3032                if (name != null) {
3033                    outPerms.add(name.intern());
3034                } else {
3035                    PackageManagerService.reportSettingsProblem(Log.WARN,
3036                            "Error in package manager settings: <perms> has" + " no name at "
3037                                    + parser.getPositionDescription());
3038                }
3039            } else {
3040                PackageManagerService.reportSettingsProblem(Log.WARN,
3041                        "Unknown element under <perms>: " + parser.getName());
3042            }
3043            XmlUtils.skipCurrentTag(parser);
3044        }
3045    }
3046
3047    void createNewUserLILPw(PackageManagerService service, Installer installer,
3048            int userHandle, File path) {
3049        path.mkdir();
3050        FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
3051                | FileUtils.S_IXOTH, -1, -1);
3052        for (PackageSetting ps : mPackages.values()) {
3053            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
3054                continue;
3055            }
3056            // Only system apps are initially installed.
3057            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
3058            // Need to create a data directory for all apps under this user.
3059            installer.createUserData(ps.name,
3060                    UserHandle.getUid(userHandle, ps.appId), userHandle,
3061                    ps.pkg.applicationInfo.seinfo);
3062        }
3063        readDefaultPreferredAppsLPw(service, userHandle);
3064        writePackageRestrictionsLPr(userHandle);
3065    }
3066
3067    void removeUserLPw(int userId) {
3068        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
3069        for (Entry<String, PackageSetting> entry : entries) {
3070            entry.getValue().removeUser(userId);
3071        }
3072        mPreferredActivities.remove(userId);
3073        File file = getUserPackagesStateFile(userId);
3074        file.delete();
3075        file = getUserPackagesStateBackupFile(userId);
3076        file.delete();
3077        removeCrossProfileIntentFiltersLPw(userId);
3078    }
3079
3080    void removeCrossProfileIntentFiltersLPw(int userId) {
3081        synchronized (mCrossProfileIntentResolvers) {
3082            // userId is the source user
3083            if (mCrossProfileIntentResolvers.get(userId) != null) {
3084                mCrossProfileIntentResolvers.remove(userId);
3085                writePackageRestrictionsLPr(userId);
3086            }
3087            // userId is the target user
3088            int count = mCrossProfileIntentResolvers.size();
3089            for (int i = 0; i < count; i++) {
3090                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
3091                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
3092                boolean needsWriting = false;
3093                HashSet<CrossProfileIntentFilter> cpifs =
3094                        new HashSet<CrossProfileIntentFilter>(cpir.filterSet());
3095                for (CrossProfileIntentFilter cpif : cpifs) {
3096                    if (cpif.getTargetUserId() == userId) {
3097                        needsWriting = true;
3098                        cpir.removeFilter(cpif);
3099                    }
3100                }
3101                if (needsWriting) {
3102                    writePackageRestrictionsLPr(sourceUserId);
3103                }
3104            }
3105        }
3106    }
3107
3108    // This should be called (at least) whenever an application is removed
3109    private void setFirstAvailableUid(int uid) {
3110        if (uid > mFirstAvailableUid) {
3111            mFirstAvailableUid = uid;
3112        }
3113    }
3114
3115    // Returns -1 if we could not find an available UserId to assign
3116    private int newUserIdLPw(Object obj) {
3117        // Let's be stupidly inefficient for now...
3118        final int N = mUserIds.size();
3119        for (int i = mFirstAvailableUid; i < N; i++) {
3120            if (mUserIds.get(i) == null) {
3121                mUserIds.set(i, obj);
3122                return Process.FIRST_APPLICATION_UID + i;
3123            }
3124        }
3125
3126        // None left?
3127        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
3128            return -1;
3129        }
3130
3131        mUserIds.add(obj);
3132        return Process.FIRST_APPLICATION_UID + N;
3133    }
3134
3135    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
3136        if (mVerifierDeviceIdentity == null) {
3137            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
3138
3139            writeLPr();
3140        }
3141
3142        return mVerifierDeviceIdentity;
3143    }
3144
3145    public PackageSetting getDisabledSystemPkgLPr(String name) {
3146        PackageSetting ps = mDisabledSysPackages.get(name);
3147        return ps;
3148    }
3149
3150    private String compToString(HashSet<String> cmp) {
3151        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
3152    }
3153
3154    boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
3155        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
3156            return true;
3157        }
3158        final String pkgName = componentInfo.packageName;
3159        final PackageSetting packageSettings = mPackages.get(pkgName);
3160        if (PackageManagerService.DEBUG_SETTINGS) {
3161            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
3162                    + componentInfo.packageName + " componentName = " + componentInfo.name);
3163            Log.v(PackageManagerService.TAG, "enabledComponents: "
3164                    + compToString(packageSettings.getEnabledComponents(userId)));
3165            Log.v(PackageManagerService.TAG, "disabledComponents: "
3166                    + compToString(packageSettings.getDisabledComponents(userId)));
3167        }
3168        if (packageSettings == null) {
3169            return false;
3170        }
3171        PackageUserState ustate = packageSettings.readUserState(userId);
3172        if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
3173            if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
3174                return true;
3175            }
3176        }
3177        if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
3178                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
3179                || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
3180                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
3181                    && ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
3182            return false;
3183        }
3184        if (ustate.enabledComponents != null
3185                && ustate.enabledComponents.contains(componentInfo.name)) {
3186            return true;
3187        }
3188        if (ustate.disabledComponents != null
3189                && ustate.disabledComponents.contains(componentInfo.name)) {
3190            return false;
3191        }
3192        return componentInfo.enabled;
3193    }
3194
3195    String getInstallerPackageNameLPr(String packageName) {
3196        final PackageSetting pkg = mPackages.get(packageName);
3197        if (pkg == null) {
3198            throw new IllegalArgumentException("Unknown package: " + packageName);
3199        }
3200        return pkg.installerPackageName;
3201    }
3202
3203    int getApplicationEnabledSettingLPr(String packageName, int userId) {
3204        final PackageSetting pkg = mPackages.get(packageName);
3205        if (pkg == null) {
3206            throw new IllegalArgumentException("Unknown package: " + packageName);
3207        }
3208        return pkg.getEnabled(userId);
3209    }
3210
3211    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
3212        final String packageName = componentName.getPackageName();
3213        final PackageSetting pkg = mPackages.get(packageName);
3214        if (pkg == null) {
3215            throw new IllegalArgumentException("Unknown component: " + componentName);
3216        }
3217        final String classNameStr = componentName.getClassName();
3218        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
3219    }
3220
3221    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
3222            boolean allowedByPermission, int uid, int userId) {
3223        int appId = UserHandle.getAppId(uid);
3224        final PackageSetting pkgSetting = mPackages.get(packageName);
3225        if (pkgSetting == null) {
3226            throw new IllegalArgumentException("Unknown package: " + packageName);
3227        }
3228        if (!allowedByPermission && (appId != pkgSetting.appId)) {
3229            throw new SecurityException(
3230                    "Permission Denial: attempt to change stopped state from pid="
3231                    + Binder.getCallingPid()
3232                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
3233        }
3234        if (DEBUG_STOPPED) {
3235            if (stopped) {
3236                RuntimeException e = new RuntimeException("here");
3237                e.fillInStackTrace();
3238                Slog.i(TAG, "Stopping package " + packageName, e);
3239            }
3240        }
3241        if (pkgSetting.getStopped(userId) != stopped) {
3242            pkgSetting.setStopped(stopped, userId);
3243            // pkgSetting.pkg.mSetStopped = stopped;
3244            if (pkgSetting.getNotLaunched(userId)) {
3245                if (pkgSetting.installerPackageName != null) {
3246                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
3247                            pkgSetting.name, null,
3248                            pkgSetting.installerPackageName, null, new int[] {userId});
3249                }
3250                pkgSetting.setNotLaunched(false, userId);
3251            }
3252            return true;
3253        }
3254        return false;
3255    }
3256
3257    private List<UserInfo> getAllUsers() {
3258        long id = Binder.clearCallingIdentity();
3259        try {
3260            return UserManagerService.getInstance().getUsers(false);
3261        } catch (NullPointerException npe) {
3262            // packagemanager not yet initialized
3263        } finally {
3264            Binder.restoreCallingIdentity(id);
3265        }
3266        return null;
3267    }
3268
3269    static final void printFlags(PrintWriter pw, int val, Object[] spec) {
3270        pw.print("[ ");
3271        for (int i=0; i<spec.length; i+=2) {
3272            int mask = (Integer)spec[i];
3273            if ((val & mask) != 0) {
3274                pw.print(spec[i+1]);
3275                pw.print(" ");
3276            }
3277        }
3278        pw.print("]");
3279    }
3280
3281    static final Object[] FLAG_DUMP_SPEC = new Object[] {
3282        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
3283        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
3284        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
3285        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
3286        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
3287        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
3288        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
3289        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
3290        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
3291        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
3292        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
3293        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
3294        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
3295        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
3296        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
3297        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
3298        ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
3299        ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
3300    };
3301
3302    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
3303            SimpleDateFormat sdf, Date date, List<UserInfo> users) {
3304        if (checkinTag != null) {
3305            pw.print(checkinTag);
3306            pw.print(",");
3307            pw.print(ps.realName != null ? ps.realName : ps.name);
3308            pw.print(",");
3309            pw.print(ps.appId);
3310            pw.print(",");
3311            pw.print(ps.versionCode);
3312            pw.print(",");
3313            pw.print(ps.firstInstallTime);
3314            pw.print(",");
3315            pw.print(ps.lastUpdateTime);
3316            pw.print(",");
3317            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
3318            pw.println();
3319            for (UserInfo user : users) {
3320                pw.print(checkinTag);
3321                pw.print("-");
3322                pw.print("usr");
3323                pw.print(",");
3324                pw.print(user.id);
3325                pw.print(",");
3326                pw.print(ps.getInstalled(user.id) ? "I" : "i");
3327                pw.print(ps.getHidden(user.id) ? "B" : "b");
3328                pw.print(ps.getStopped(user.id) ? "S" : "s");
3329                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
3330                pw.print(",");
3331                pw.print(ps.getEnabled(user.id));
3332                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3333                pw.print(",");
3334                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
3335                pw.println();
3336            }
3337            return;
3338        }
3339
3340        pw.print(prefix); pw.print("Package [");
3341            pw.print(ps.realName != null ? ps.realName : ps.name);
3342            pw.print("] (");
3343            pw.print(Integer.toHexString(System.identityHashCode(ps)));
3344            pw.println("):");
3345
3346        if (ps.realName != null) {
3347            pw.print(prefix); pw.print("  compat name=");
3348            pw.println(ps.name);
3349        }
3350
3351        pw.print(prefix); pw.print("  userId="); pw.print(ps.appId);
3352                pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
3353        if (ps.sharedUser != null) {
3354            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
3355        }
3356        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
3357        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
3358        pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
3359        pw.print(prefix); pw.print("  legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString);
3360        pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
3361        pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
3362        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
3363        if (ps.pkg != null) {
3364            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
3365        }
3366        pw.println();
3367        if (ps.pkg != null) {
3368            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
3369            pw.print(prefix); pw.print("  applicationInfo=");
3370                pw.println(ps.pkg.applicationInfo.toString());
3371            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
3372                    FLAG_DUMP_SPEC); pw.println();
3373            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
3374            if (ps.pkg.mOperationPending) {
3375                pw.print(prefix); pw.println("  mOperationPending=true");
3376            }
3377            pw.print(prefix); pw.print("  supportsScreens=[");
3378            boolean first = true;
3379            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
3380                if (!first)
3381                    pw.print(", ");
3382                first = false;
3383                pw.print("small");
3384            }
3385            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
3386                if (!first)
3387                    pw.print(", ");
3388                first = false;
3389                pw.print("medium");
3390            }
3391            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
3392                if (!first)
3393                    pw.print(", ");
3394                first = false;
3395                pw.print("large");
3396            }
3397            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
3398                if (!first)
3399                    pw.print(", ");
3400                first = false;
3401                pw.print("xlarge");
3402            }
3403            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
3404                if (!first)
3405                    pw.print(", ");
3406                first = false;
3407                pw.print("resizeable");
3408            }
3409            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
3410                if (!first)
3411                    pw.print(", ");
3412                first = false;
3413                pw.print("anyDensity");
3414            }
3415            pw.println("]");
3416            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
3417                pw.print(prefix); pw.println("  libraries:");
3418                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
3419                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
3420                }
3421            }
3422            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
3423                pw.print(prefix); pw.println("  usesLibraries:");
3424                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
3425                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
3426                }
3427            }
3428            if (ps.pkg.usesOptionalLibraries != null
3429                    && ps.pkg.usesOptionalLibraries.size() > 0) {
3430                pw.print(prefix); pw.println("  usesOptionalLibraries:");
3431                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
3432                    pw.print(prefix); pw.print("    ");
3433                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
3434                }
3435            }
3436            if (ps.pkg.usesLibraryFiles != null
3437                    && ps.pkg.usesLibraryFiles.length > 0) {
3438                pw.print(prefix); pw.println("  usesLibraryFiles:");
3439                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
3440                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
3441                }
3442            }
3443        }
3444        pw.print(prefix); pw.print("  timeStamp=");
3445            date.setTime(ps.timeStamp);
3446            pw.println(sdf.format(date));
3447        pw.print(prefix); pw.print("  firstInstallTime=");
3448            date.setTime(ps.firstInstallTime);
3449            pw.println(sdf.format(date));
3450        pw.print(prefix); pw.print("  lastUpdateTime=");
3451            date.setTime(ps.lastUpdateTime);
3452            pw.println(sdf.format(date));
3453        if (ps.installerPackageName != null) {
3454            pw.print(prefix); pw.print("  installerPackageName=");
3455                    pw.println(ps.installerPackageName);
3456        }
3457        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
3458        pw.print(prefix); pw.print("  permissionsFixed="); pw.print(ps.permissionsFixed);
3459                pw.print(" haveGids="); pw.print(ps.haveGids);
3460                pw.print(" installStatus="); pw.println(ps.installStatus);
3461        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
3462                pw.println();
3463        for (UserInfo user : users) {
3464            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
3465            pw.print(" installed=");
3466            pw.print(ps.getInstalled(user.id));
3467            pw.print(" hidden=");
3468            pw.print(ps.getHidden(user.id));
3469            pw.print(" stopped=");
3470            pw.print(ps.getStopped(user.id));
3471            pw.print(" notLaunched=");
3472            pw.print(ps.getNotLaunched(user.id));
3473            pw.print(" enabled=");
3474            pw.println(ps.getEnabled(user.id));
3475            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
3476            if (lastDisabledAppCaller != null) {
3477                pw.print(prefix); pw.print("    lastDisabledCaller: ");
3478                        pw.println(lastDisabledAppCaller);
3479            }
3480            HashSet<String> cmp = ps.getDisabledComponents(user.id);
3481            if (cmp != null && cmp.size() > 0) {
3482                pw.print(prefix); pw.println("    disabledComponents:");
3483                for (String s : cmp) {
3484                    pw.print(prefix); pw.print("    "); pw.println(s);
3485                }
3486            }
3487            cmp = ps.getEnabledComponents(user.id);
3488            if (cmp != null && cmp.size() > 0) {
3489                pw.print(prefix); pw.println("    enabledComponents:");
3490                for (String s : cmp) {
3491                    pw.print(prefix); pw.print("    "); pw.println(s);
3492                }
3493            }
3494        }
3495        if (ps.grantedPermissions.size() > 0) {
3496            pw.print(prefix); pw.println("  grantedPermissions:");
3497            for (String s : ps.grantedPermissions) {
3498                pw.print(prefix); pw.print("    "); pw.println(s);
3499            }
3500        }
3501    }
3502
3503    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
3504        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3505        final Date date = new Date();
3506        boolean printedSomething = false;
3507        List<UserInfo> users = getAllUsers();
3508        for (final PackageSetting ps : mPackages.values()) {
3509            if (packageName != null && !packageName.equals(ps.realName)
3510                    && !packageName.equals(ps.name)) {
3511                continue;
3512            }
3513
3514            if (!checkin && packageName != null) {
3515                dumpState.setSharedUser(ps.sharedUser);
3516            }
3517
3518            if (!checkin && !printedSomething) {
3519                if (dumpState.onTitlePrinted())
3520                    pw.println();
3521                pw.println("Packages:");
3522                printedSomething = true;
3523            }
3524            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, ps, sdf, date, users);
3525        }
3526
3527        printedSomething = false;
3528        if (!checkin && mRenamedPackages.size() > 0) {
3529            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
3530                if (packageName != null && !packageName.equals(e.getKey())
3531                        && !packageName.equals(e.getValue())) {
3532                    continue;
3533                }
3534                if (!checkin) {
3535                    if (!printedSomething) {
3536                        if (dumpState.onTitlePrinted())
3537                            pw.println();
3538                        pw.println("Renamed packages:");
3539                        printedSomething = true;
3540                    }
3541                    pw.print("  ");
3542                } else {
3543                    pw.print("ren,");
3544                }
3545                pw.print(e.getKey());
3546                pw.print(checkin ? " -> " : ",");
3547                pw.println(e.getValue());
3548            }
3549        }
3550
3551        printedSomething = false;
3552        if (mDisabledSysPackages.size() > 0) {
3553            for (final PackageSetting ps : mDisabledSysPackages.values()) {
3554                if (packageName != null && !packageName.equals(ps.realName)
3555                        && !packageName.equals(ps.name)) {
3556                    continue;
3557                }
3558                if (!checkin && !printedSomething) {
3559                    if (dumpState.onTitlePrinted())
3560                        pw.println();
3561                    pw.println("Hidden system packages:");
3562                    printedSomething = true;
3563                }
3564                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, ps, sdf, date, users);
3565            }
3566        }
3567    }
3568
3569    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3570        boolean printedSomething = false;
3571        for (BasePermission p : mPermissions.values()) {
3572            if (packageName != null && !packageName.equals(p.sourcePackage)) {
3573                continue;
3574            }
3575            if (!printedSomething) {
3576                if (dumpState.onTitlePrinted())
3577                    pw.println();
3578                pw.println("Permissions:");
3579                printedSomething = true;
3580            }
3581            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
3582                    pw.print(Integer.toHexString(System.identityHashCode(p)));
3583                    pw.println("):");
3584            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
3585            pw.print("    uid="); pw.print(p.uid);
3586                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
3587                    pw.print(" type="); pw.print(p.type);
3588                    pw.print(" prot=");
3589                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
3590            if (p.packageSetting != null) {
3591                pw.print("    packageSetting="); pw.println(p.packageSetting);
3592            }
3593            if (p.perm != null) {
3594                pw.print("    perm="); pw.println(p.perm);
3595            }
3596            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
3597                pw.print("    enforced=");
3598                pw.println(mReadExternalStorageEnforced);
3599            }
3600        }
3601    }
3602
3603    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
3604        boolean printedSomething = false;
3605        for (SharedUserSetting su : mSharedUsers.values()) {
3606            if (packageName != null && su != dumpState.getSharedUser()) {
3607                continue;
3608            }
3609            if (!printedSomething) {
3610                if (dumpState.onTitlePrinted())
3611                    pw.println();
3612                pw.println("Shared users:");
3613                printedSomething = true;
3614            }
3615            pw.print("  SharedUser [");
3616            pw.print(su.name);
3617            pw.print("] (");
3618            pw.print(Integer.toHexString(System.identityHashCode(su)));
3619                    pw.println("):");
3620            pw.print("    userId=");
3621            pw.print(su.userId);
3622            pw.print(" gids=");
3623            pw.println(PackageManagerService.arrayToString(su.gids));
3624            pw.println("    grantedPermissions:");
3625            for (String s : su.grantedPermissions) {
3626                pw.print("      ");
3627                pw.println(s);
3628            }
3629        }
3630    }
3631
3632    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
3633        pw.println("Settings parse messages:");
3634        pw.print(mReadMessages.toString());
3635    }
3636}
3637