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