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