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