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