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