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