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