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