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