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