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_USER;
     22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     23 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
     24 
     25 import com.android.internal.util.FastXmlSerializer;
     26 import com.android.internal.util.JournaledFile;
     27 import com.android.internal.util.XmlUtils;
     28 import com.android.server.IntentResolver;
     29 import com.android.server.pm.PackageManagerService.DumpState;
     30 
     31 import org.xmlpull.v1.XmlPullParser;
     32 import org.xmlpull.v1.XmlPullParserException;
     33 import org.xmlpull.v1.XmlSerializer;
     34 
     35 import android.app.AppGlobals;
     36 import android.content.ComponentName;
     37 import android.content.Intent;
     38 import android.content.pm.ApplicationInfo;
     39 import android.content.pm.ComponentInfo;
     40 import android.content.pm.PackageManager;
     41 import android.content.pm.PackageParser;
     42 import android.content.pm.PermissionInfo;
     43 import android.content.pm.Signature;
     44 import android.content.pm.UserInfo;
     45 import android.content.pm.VerifierDeviceIdentity;
     46 import android.os.Binder;
     47 import android.os.Environment;
     48 import android.os.FileUtils;
     49 import android.os.Process;
     50 import android.os.RemoteException;
     51 import android.os.UserId;
     52 import android.util.Log;
     53 import android.util.Slog;
     54 import android.util.SparseArray;
     55 import android.util.Xml;
     56 
     57 import java.io.BufferedOutputStream;
     58 import java.io.File;
     59 import java.io.FileInputStream;
     60 import java.io.FileOutputStream;
     61 import java.io.IOException;
     62 import java.io.PrintWriter;
     63 import java.text.SimpleDateFormat;
     64 import java.util.ArrayList;
     65 import java.util.Arrays;
     66 import java.util.Date;
     67 import java.util.HashMap;
     68 import java.util.HashSet;
     69 import java.util.Iterator;
     70 import java.util.List;
     71 import java.util.Map;
     72 
     73 import libcore.io.IoUtils;
     74 
     75 /**
     76  * Holds information about dynamic settings.
     77  */
     78 final class Settings {
     79     private static final String TAG = "PackageSettings";
     80 
     81     private static final boolean DEBUG_STOPPED = false;
     82 
     83     private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
     84     private static final String ATTR_ENFORCEMENT = "enforcement";
     85 
     86     private static final String TAG_ITEM = "item";
     87     private static final String TAG_DISABLED_COMPONENTS = "disabled-components";
     88     private static final String TAG_ENABLED_COMPONENTS = "enabled-components";
     89     private static final String TAG_PACKAGE_RESTRICTIONS = "package-restrictions";
     90     private static final String TAG_PACKAGE = "pkg";
     91 
     92     private static final String ATTR_NAME = "name";
     93     private static final String ATTR_NOT_LAUNCHED = "nl";
     94     private static final String ATTR_ENABLED = "enabled";
     95     private static final String ATTR_STOPPED = "stopped";
     96 
     97     private final File mSettingsFilename;
     98     private final File mBackupSettingsFilename;
     99     private final File mPackageListFilename;
    100     private final File mStoppedPackagesFilename;
    101     private final File mBackupStoppedPackagesFilename;
    102     final HashMap<String, PackageSetting> mPackages =
    103             new HashMap<String, PackageSetting>();
    104     // List of replaced system applications
    105     private final HashMap<String, PackageSetting> mDisabledSysPackages =
    106         new HashMap<String, PackageSetting>();
    107 
    108     // These are the last platform API version we were using for
    109     // the apps installed on internal and external storage.  It is
    110     // used to grant newer permissions one time during a system upgrade.
    111     int mInternalSdkPlatform;
    112     int mExternalSdkPlatform;
    113 
    114     Boolean mReadExternalStorageEnforced;
    115 
    116     /** Device identity for the purpose of package verification. */
    117     private VerifierDeviceIdentity mVerifierDeviceIdentity;
    118 
    119     // The user's preferred activities associated with particular intent
    120     // filters.
    121     final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities =
    122                 new IntentResolver<PreferredActivity, PreferredActivity>() {
    123         @Override
    124         protected String packageForFilter(PreferredActivity filter) {
    125             return filter.mPref.mComponent.getPackageName();
    126         }
    127         @Override
    128         protected void dumpFilter(PrintWriter out, String prefix,
    129                 PreferredActivity filter) {
    130             filter.mPref.dump(out, prefix, filter);
    131         }
    132     };
    133     final HashMap<String, SharedUserSetting> mSharedUsers =
    134             new HashMap<String, SharedUserSetting>();
    135     private final ArrayList<Object> mUserIds = new ArrayList<Object>();
    136     private final SparseArray<Object> mOtherUserIds =
    137             new SparseArray<Object>();
    138 
    139     // For reading/writing settings file.
    140     private final ArrayList<Signature> mPastSignatures =
    141             new ArrayList<Signature>();
    142 
    143     // Mapping from permission names to info about them.
    144     final HashMap<String, BasePermission> mPermissions =
    145             new HashMap<String, BasePermission>();
    146 
    147     // Mapping from permission tree names to info about them.
    148     final HashMap<String, BasePermission> mPermissionTrees =
    149             new HashMap<String, BasePermission>();
    150 
    151     // Packages that have been uninstalled and still need their external
    152     // storage data deleted.
    153     final ArrayList<String> mPackagesToBeCleaned = new ArrayList<String>();
    154 
    155     // Packages that have been renamed since they were first installed.
    156     // Keys are the new names of the packages, values are the original
    157     // names.  The packages appear everwhere else under their original
    158     // names.
    159     final HashMap<String, String> mRenamedPackages = new HashMap<String, String>();
    160 
    161     final StringBuilder mReadMessages = new StringBuilder();
    162 
    163     /**
    164      * Used to track packages that have a shared user ID that hasn't been read
    165      * in yet.
    166      * <p>
    167      * TODO: make this just a local variable that is passed in during package
    168      * scanning to make it less confusing.
    169      */
    170     private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
    171 
    172     private final File mSystemDir;
    173     Settings() {
    174         this(Environment.getDataDirectory());
    175     }
    176 
    177     Settings(File dataDir) {
    178         mSystemDir = new File(dataDir, "system");
    179         mSystemDir.mkdirs();
    180         FileUtils.setPermissions(mSystemDir.toString(),
    181                 FileUtils.S_IRWXU|FileUtils.S_IRWXG
    182                 |FileUtils.S_IROTH|FileUtils.S_IXOTH,
    183                 -1, -1);
    184         mSettingsFilename = new File(mSystemDir, "packages.xml");
    185         mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
    186         mPackageListFilename = new File(mSystemDir, "packages.list");
    187         // Deprecated: Needed for migration
    188         mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
    189         mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
    190     }
    191 
    192     PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
    193             String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
    194             String nativeLibraryPathString, int pkgFlags, boolean create, boolean add) {
    195         final String name = pkg.packageName;
    196         PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
    197                 resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, create, add);
    198         return p;
    199     }
    200 
    201     PackageSetting peekPackageLPr(String name) {
    202         return mPackages.get(name);
    203     }
    204 
    205     void setInstallStatus(String pkgName, int status) {
    206         PackageSetting p = mPackages.get(pkgName);
    207         if(p != null) {
    208             if(p.getInstallStatus() != status) {
    209                 p.setInstallStatus(status);
    210             }
    211         }
    212     }
    213 
    214     void setInstallerPackageName(String pkgName,
    215             String installerPkgName) {
    216         PackageSetting p = mPackages.get(pkgName);
    217         if(p != null) {
    218             p.setInstallerPackageName(installerPkgName);
    219         }
    220     }
    221 
    222     SharedUserSetting getSharedUserLPw(String name,
    223             int pkgFlags, boolean create) {
    224         SharedUserSetting s = mSharedUsers.get(name);
    225         if (s == null) {
    226             if (!create) {
    227                 return null;
    228             }
    229             s = new SharedUserSetting(name, pkgFlags);
    230             s.userId = newUserIdLPw(s);
    231             Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
    232             // < 0 means we couldn't assign a userid; fall out and return
    233             // s, which is currently null
    234             if (s.userId >= 0) {
    235                 mSharedUsers.put(name, s);
    236             }
    237         }
    238 
    239         return s;
    240     }
    241 
    242     boolean disableSystemPackageLPw(String name) {
    243         final PackageSetting p = mPackages.get(name);
    244         if(p == null) {
    245             Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
    246             return false;
    247         }
    248         final PackageSetting dp = mDisabledSysPackages.get(name);
    249         // always make sure the system package code and resource paths dont change
    250         if (dp == null) {
    251             if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
    252                 p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
    253             }
    254             mDisabledSysPackages.put(name, p);
    255 
    256             // a little trick...  when we install the new package, we don't
    257             // want to modify the existing PackageSetting for the built-in
    258             // version.  so at this point we need a new PackageSetting that
    259             // is okay to muck with.
    260             PackageSetting newp = new PackageSetting(p);
    261             replacePackageLPw(name, newp);
    262             return true;
    263         }
    264         return false;
    265     }
    266 
    267     PackageSetting enableSystemPackageLPw(String name) {
    268         PackageSetting p = mDisabledSysPackages.get(name);
    269         if(p == null) {
    270             Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
    271             return null;
    272         }
    273         // Reset flag in ApplicationInfo object
    274         if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
    275             p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
    276         }
    277         PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
    278                 p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
    279         mDisabledSysPackages.remove(name);
    280         return ret;
    281     }
    282 
    283     boolean isDisabledSystemPackageLPr(String name) {
    284         return mDisabledSysPackages.containsKey(name);
    285     }
    286 
    287     void removeDisabledSystemPackageLPw(String name) {
    288         mDisabledSysPackages.remove(name);
    289     }
    290 
    291     PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
    292             String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
    293         PackageSetting p = mPackages.get(name);
    294         if (p != null) {
    295             if (p.appId == uid) {
    296                 return p;
    297             }
    298             PackageManagerService.reportSettingsProblem(Log.ERROR,
    299                     "Adding duplicate package, keeping first: " + name);
    300             return null;
    301         }
    302         p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
    303                 vc, pkgFlags);
    304         p.appId = uid;
    305         if (addUserIdLPw(uid, p, name)) {
    306             mPackages.put(name, p);
    307             return p;
    308         }
    309         return null;
    310     }
    311 
    312     SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
    313         SharedUserSetting s = mSharedUsers.get(name);
    314         if (s != null) {
    315             if (s.userId == uid) {
    316                 return s;
    317             }
    318             PackageManagerService.reportSettingsProblem(Log.ERROR,
    319                     "Adding duplicate shared user, keeping first: " + name);
    320             return null;
    321         }
    322         s = new SharedUserSetting(name, pkgFlags);
    323         s.userId = uid;
    324         if (addUserIdLPw(uid, s, name)) {
    325             mSharedUsers.put(name, s);
    326             return s;
    327         }
    328         return null;
    329     }
    330 
    331     // Transfer ownership of permissions from one package to another.
    332     void transferPermissionsLPw(String origPkg, String newPkg) {
    333         // Transfer ownership of permissions to the new package.
    334         for (int i=0; i<2; i++) {
    335             HashMap<String, BasePermission> permissions =
    336                     i == 0 ? mPermissionTrees : mPermissions;
    337             for (BasePermission bp : permissions.values()) {
    338                 if (origPkg.equals(bp.sourcePackage)) {
    339                     if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG,
    340                             "Moving permission " + bp.name
    341                             + " from pkg " + bp.sourcePackage
    342                             + " to " + newPkg);
    343                     bp.sourcePackage = newPkg;
    344                     bp.packageSetting = null;
    345                     bp.perm = null;
    346                     if (bp.pendingInfo != null) {
    347                         bp.pendingInfo.packageName = newPkg;
    348                     }
    349                     bp.uid = 0;
    350                     bp.gids = null;
    351                 }
    352             }
    353         }
    354     }
    355 
    356     private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
    357             String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
    358             String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) {
    359         PackageSetting p = mPackages.get(name);
    360         if (p != null) {
    361             if (!p.codePath.equals(codePath)) {
    362                 // Check to see if its a disabled system app
    363                 if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
    364                     // This is an updated system app with versions in both system
    365                     // and data partition. Just let the most recent version
    366                     // take precedence.
    367                     Slog.w(PackageManagerService.TAG, "Trying to update system app code path from "
    368                             + p.codePathString + " to " + codePath.toString());
    369                 } else {
    370                     // Just a change in the code path is not an issue, but
    371                     // let's log a message about it.
    372                     Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from "
    373                             + p.codePath + " to " + codePath + "; Retaining data and using new");
    374                     /*
    375                      * Since we've changed paths, we need to prefer the new
    376                      * native library path over the one stored in the
    377                      * package settings since we might have moved from
    378                      * internal to external storage or vice versa.
    379                      */
    380                     p.nativeLibraryPathString = nativeLibraryPathString;
    381                 }
    382             }
    383             if (p.sharedUser != sharedUser) {
    384                 PackageManagerService.reportSettingsProblem(Log.WARN,
    385                         "Package " + name + " shared user changed from "
    386                         + (p.sharedUser != null ? p.sharedUser.name : "<nothing>")
    387                         + " to "
    388                         + (sharedUser != null ? sharedUser.name : "<nothing>")
    389                         + "; replacing with new");
    390                 p = null;
    391             } else {
    392                 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
    393                     // If what we are scanning is a system package, then
    394                     // make it so, regardless of whether it was previously
    395                     // installed only in the data partition.
    396                     p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
    397                 }
    398             }
    399         }
    400         if (p == null) {
    401             // Create a new PackageSettings entry. this can end up here because
    402             // of code path mismatch or user id mismatch of an updated system partition
    403             if (!create) {
    404                 return null;
    405             }
    406             if (origPackage != null) {
    407                 // We are consuming the data from an existing package.
    408                 p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
    409                         nativeLibraryPathString, vc, pkgFlags);
    410                 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
    411                         + name + " is adopting original package " + origPackage.name);
    412                 // Note that we will retain the new package's signature so
    413                 // that we can keep its data.
    414                 PackageSignatures s = p.signatures;
    415                 p.copyFrom(origPackage);
    416                 p.signatures = s;
    417                 p.sharedUser = origPackage.sharedUser;
    418                 p.appId = origPackage.appId;
    419                 p.origPackage = origPackage;
    420                 mRenamedPackages.put(name, origPackage.name);
    421                 name = origPackage.name;
    422                 // Update new package state.
    423                 p.setTimeStamp(codePath.lastModified());
    424             } else {
    425                 p = new PackageSetting(name, realName, codePath, resourcePath,
    426                         nativeLibraryPathString, vc, pkgFlags);
    427                 p.setTimeStamp(codePath.lastModified());
    428                 p.sharedUser = sharedUser;
    429                 // If this is not a system app, it starts out stopped.
    430                 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
    431                     if (DEBUG_STOPPED) {
    432                         RuntimeException e = new RuntimeException("here");
    433                         e.fillInStackTrace();
    434                         Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
    435                     }
    436                     List<UserInfo> users = getAllUsers();
    437                     if (users != null) {
    438                         for (UserInfo user : users) {
    439                             p.setStopped(true, user.id);
    440                             p.setNotLaunched(true, user.id);
    441                             writePackageRestrictionsLPr(user.id);
    442                         }
    443                     }
    444                 }
    445                 if (sharedUser != null) {
    446                     p.appId = sharedUser.userId;
    447                 } else {
    448                     // Clone the setting here for disabled system packages
    449                     PackageSetting dis = mDisabledSysPackages.get(name);
    450                     if (dis != null) {
    451                         // For disabled packages a new setting is created
    452                         // from the existing user id. This still has to be
    453                         // added to list of user id's
    454                         // Copy signatures from previous setting
    455                         if (dis.signatures.mSignatures != null) {
    456                             p.signatures.mSignatures = dis.signatures.mSignatures.clone();
    457                         }
    458                         p.appId = dis.appId;
    459                         // Clone permissions
    460                         p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
    461                         // Clone component info
    462                         List<UserInfo> users = getAllUsers();
    463                         if (users != null) {
    464                             for (UserInfo user : users) {
    465                                 int userId = user.id;
    466                                 p.setDisabledComponents(
    467                                         new HashSet<String>(dis.getDisabledComponents(userId)),
    468                                         userId);
    469                                 p.setEnabledComponents(
    470                                         new HashSet<String>(dis.getEnabledComponents(userId)),
    471                                         userId);
    472                             }
    473                         }
    474                         // Add new setting to list of user ids
    475                         addUserIdLPw(p.appId, p, name);
    476                     } else {
    477                         // Assign new user id
    478                         p.appId = newUserIdLPw(p);
    479                     }
    480                 }
    481             }
    482             if (p.appId < 0) {
    483                 PackageManagerService.reportSettingsProblem(Log.WARN,
    484                         "Package " + name + " could not be assigned a valid uid");
    485                 return null;
    486             }
    487             if (add) {
    488                 // Finish adding new package by adding it and updating shared
    489                 // user preferences
    490                 addPackageSettingLPw(p, name, sharedUser);
    491             }
    492         }
    493         return p;
    494     }
    495 
    496     void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
    497         p.pkg = pkg;
    498         // pkg.mSetEnabled = p.getEnabled(userId);
    499         // pkg.mSetStopped = p.getStopped(userId);
    500         final String codePath = pkg.applicationInfo.sourceDir;
    501         final String resourcePath = pkg.applicationInfo.publicSourceDir;
    502         // Update code path if needed
    503         if (!codePath.equalsIgnoreCase(p.codePathString)) {
    504             Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName +
    505                     " changing from " + p.codePathString + " to " + codePath);
    506             p.codePath = new File(codePath);
    507             p.codePathString = codePath;
    508         }
    509         //Update resource path if needed
    510         if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) {
    511             Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName +
    512                     " changing from " + p.resourcePathString + " to " + resourcePath);
    513             p.resourcePath = new File(resourcePath);
    514             p.resourcePathString = resourcePath;
    515         }
    516         // Update the native library path if needed
    517         final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
    518         if (nativeLibraryPath != null
    519                 && !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
    520             p.nativeLibraryPathString = nativeLibraryPath;
    521         }
    522         // Update version code if needed
    523         if (pkg.mVersionCode != p.versionCode) {
    524             p.versionCode = pkg.mVersionCode;
    525         }
    526         // Update signatures if needed.
    527         if (p.signatures.mSignatures == null) {
    528             p.signatures.assignSignatures(pkg.mSignatures);
    529         }
    530         // If this app defines a shared user id initialize
    531         // the shared user signatures as well.
    532         if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
    533             p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
    534         }
    535         addPackageSettingLPw(p, pkg.packageName, p.sharedUser);
    536     }
    537 
    538     // Utility method that adds a PackageSetting to mPackages and
    539     // completes updating the shared user attributes
    540     private void addPackageSettingLPw(PackageSetting p, String name,
    541             SharedUserSetting sharedUser) {
    542         mPackages.put(name, p);
    543         if (sharedUser != null) {
    544             if (p.sharedUser != null && p.sharedUser != sharedUser) {
    545                 PackageManagerService.reportSettingsProblem(Log.ERROR,
    546                         "Package " + p.name + " was user "
    547                         + p.sharedUser + " but is now " + sharedUser
    548                         + "; I am not changing its files so it will probably fail!");
    549                 p.sharedUser.packages.remove(p);
    550             } else if (p.appId != sharedUser.userId) {
    551                 PackageManagerService.reportSettingsProblem(Log.ERROR,
    552                     "Package " + p.name + " was user id " + p.appId
    553                     + " but is now user " + sharedUser
    554                     + " with id " + sharedUser.userId
    555                     + "; I am not changing its files so it will probably fail!");
    556             }
    557 
    558             sharedUser.packages.add(p);
    559             p.sharedUser = sharedUser;
    560             p.appId = sharedUser.userId;
    561         }
    562     }
    563 
    564     /*
    565      * Update the shared user setting when a package using
    566      * specifying the shared user id is removed. The gids
    567      * associated with each permission of the deleted package
    568      * are removed from the shared user's gid list only if its
    569      * not in use by other permissions of packages in the
    570      * shared user setting.
    571      */
    572     void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
    573         if ((deletedPs == null) || (deletedPs.pkg == null)) {
    574             Slog.i(PackageManagerService.TAG,
    575                     "Trying to update info for null package. Just ignoring");
    576             return;
    577         }
    578         // No sharedUserId
    579         if (deletedPs.sharedUser == null) {
    580             return;
    581         }
    582         SharedUserSetting sus = deletedPs.sharedUser;
    583         // Update permissions
    584         for (String eachPerm : deletedPs.pkg.requestedPermissions) {
    585             boolean used = false;
    586             if (!sus.grantedPermissions.contains(eachPerm)) {
    587                 continue;
    588             }
    589             for (PackageSetting pkg:sus.packages) {
    590                 if (pkg.pkg != null &&
    591                         !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
    592                         pkg.pkg.requestedPermissions.contains(eachPerm)) {
    593                     used = true;
    594                     break;
    595                 }
    596             }
    597             if (!used) {
    598                 // can safely delete this permission from list
    599                 sus.grantedPermissions.remove(eachPerm);
    600             }
    601         }
    602         // Update gids
    603         int newGids[] = globalGids;
    604         for (String eachPerm : sus.grantedPermissions) {
    605             BasePermission bp = mPermissions.get(eachPerm);
    606             if (bp != null) {
    607                 newGids = PackageManagerService.appendInts(newGids, bp.gids);
    608             }
    609         }
    610         sus.gids = newGids;
    611     }
    612 
    613     int removePackageLPw(String name) {
    614         final PackageSetting p = mPackages.get(name);
    615         if (p != null) {
    616             mPackages.remove(name);
    617             if (p.sharedUser != null) {
    618                 p.sharedUser.packages.remove(p);
    619                 if (p.sharedUser.packages.size() == 0) {
    620                     mSharedUsers.remove(p.sharedUser.name);
    621                     removeUserIdLPw(p.sharedUser.userId);
    622                     return p.sharedUser.userId;
    623                 }
    624             } else {
    625                 removeUserIdLPw(p.appId);
    626                 return p.appId;
    627             }
    628         }
    629         return -1;
    630     }
    631 
    632     private void replacePackageLPw(String name, PackageSetting newp) {
    633         final PackageSetting p = mPackages.get(name);
    634         if (p != null) {
    635             if (p.sharedUser != null) {
    636                 p.sharedUser.packages.remove(p);
    637                 p.sharedUser.packages.add(newp);
    638             } else {
    639                 replaceUserIdLPw(p.appId, newp);
    640             }
    641         }
    642         mPackages.put(name, newp);
    643     }
    644 
    645     private boolean addUserIdLPw(int uid, Object obj, Object name) {
    646         if (uid > Process.LAST_APPLICATION_UID) {
    647             return false;
    648         }
    649 
    650         if (uid >= Process.FIRST_APPLICATION_UID) {
    651             int N = mUserIds.size();
    652             final int index = uid - Process.FIRST_APPLICATION_UID;
    653             while (index >= N) {
    654                 mUserIds.add(null);
    655                 N++;
    656             }
    657             if (mUserIds.get(index) != null) {
    658                 PackageManagerService.reportSettingsProblem(Log.ERROR,
    659                         "Adding duplicate user id: " + uid
    660                         + " name=" + name);
    661                 return false;
    662             }
    663             mUserIds.set(index, obj);
    664         } else {
    665             if (mOtherUserIds.get(uid) != null) {
    666                 PackageManagerService.reportSettingsProblem(Log.ERROR,
    667                         "Adding duplicate shared id: " + uid
    668                         + " name=" + name);
    669                 return false;
    670             }
    671             mOtherUserIds.put(uid, obj);
    672         }
    673         return true;
    674     }
    675 
    676     public Object getUserIdLPr(int uid) {
    677         if (uid >= Process.FIRST_APPLICATION_UID) {
    678             final int N = mUserIds.size();
    679             final int index = uid - Process.FIRST_APPLICATION_UID;
    680             return index < N ? mUserIds.get(index) : null;
    681         } else {
    682             return mOtherUserIds.get(uid);
    683         }
    684     }
    685 
    686     private void removeUserIdLPw(int uid) {
    687         if (uid >= Process.FIRST_APPLICATION_UID) {
    688             final int N = mUserIds.size();
    689             final int index = uid - Process.FIRST_APPLICATION_UID;
    690             if (index < N) mUserIds.set(index, null);
    691         } else {
    692             mOtherUserIds.remove(uid);
    693         }
    694     }
    695 
    696     private void replaceUserIdLPw(int uid, Object obj) {
    697         if (uid >= Process.FIRST_APPLICATION_UID) {
    698             final int N = mUserIds.size();
    699             final int index = uid - Process.FIRST_APPLICATION_UID;
    700             if (index < N) mUserIds.set(index, obj);
    701         } else {
    702             mOtherUserIds.put(uid, obj);
    703         }
    704     }
    705 
    706     private File getUserPackagesStateFile(int userId) {
    707         return new File(mSystemDir,
    708                 "users/" + userId + "/package-restrictions.xml");
    709     }
    710 
    711     private File getUserPackagesStateBackupFile(int userId) {
    712         return new File(mSystemDir,
    713                 "users/" + userId + "/package-restrictions-backup.xml");
    714     }
    715 
    716     void writeAllUsersPackageRestrictionsLPr() {
    717         List<UserInfo> users = getAllUsers();
    718         if (users == null) return;
    719 
    720         for (UserInfo user : users) {
    721             writePackageRestrictionsLPr(user.id);
    722         }
    723     }
    724 
    725     void readAllUsersPackageRestrictionsLPr() {
    726         List<UserInfo> users = getAllUsers();
    727         if (users == null) {
    728             readPackageRestrictionsLPr(0);
    729             return;
    730         }
    731 
    732         for (UserInfo user : users) {
    733             readPackageRestrictionsLPr(user.id);
    734         }
    735     }
    736 
    737     void readPackageRestrictionsLPr(int userId) {
    738         FileInputStream str = null;
    739         File userPackagesStateFile = getUserPackagesStateFile(userId);
    740         File backupFile = getUserPackagesStateBackupFile(userId);
    741         if (backupFile.exists()) {
    742             try {
    743                 str = new FileInputStream(backupFile);
    744                 mReadMessages.append("Reading from backup stopped packages file\n");
    745                 PackageManagerService.reportSettingsProblem(Log.INFO,
    746                         "Need to read from backup stopped packages file");
    747                 if (userPackagesStateFile.exists()) {
    748                     // If both the backup and normal file exist, we
    749                     // ignore the normal one since it might have been
    750                     // corrupted.
    751                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
    752                             + userPackagesStateFile);
    753                     userPackagesStateFile.delete();
    754                 }
    755             } catch (java.io.IOException e) {
    756                 // We'll try for the normal settings file.
    757             }
    758         }
    759 
    760         try {
    761             if (str == null) {
    762                 if (!userPackagesStateFile.exists()) {
    763                     mReadMessages.append("No stopped packages file found\n");
    764                     PackageManagerService.reportSettingsProblem(Log.INFO,
    765                             "No stopped packages file; "
    766                             + "assuming all started");
    767                     // At first boot, make sure no packages are stopped.
    768                     // We usually want to have third party apps initialize
    769                     // in the stopped state, but not at first boot.
    770                     for (PackageSetting pkg : mPackages.values()) {
    771                         pkg.setStopped(false, userId);
    772                         pkg.setNotLaunched(false, userId);
    773                     }
    774                     return;
    775                 }
    776                 str = new FileInputStream(userPackagesStateFile);
    777             }
    778             final XmlPullParser parser = Xml.newPullParser();
    779             parser.setInput(str, null);
    780 
    781             int type;
    782             while ((type=parser.next()) != XmlPullParser.START_TAG
    783                        && type != XmlPullParser.END_DOCUMENT) {
    784                 ;
    785             }
    786 
    787             if (type != XmlPullParser.START_TAG) {
    788                 mReadMessages.append("No start tag found in package restrictions file\n");
    789                 PackageManagerService.reportSettingsProblem(Log.WARN,
    790                         "No start tag found in package manager stopped packages");
    791                 return;
    792             }
    793 
    794             int outerDepth = parser.getDepth();
    795             PackageSetting ps = null;
    796             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
    797                    && (type != XmlPullParser.END_TAG
    798                            || parser.getDepth() > outerDepth)) {
    799                 if (type == XmlPullParser.END_TAG
    800                         || type == XmlPullParser.TEXT) {
    801                     continue;
    802                 }
    803 
    804                 String tagName = parser.getName();
    805                 if (tagName.equals(TAG_PACKAGE)) {
    806                     String name = parser.getAttributeValue(null, ATTR_NAME);
    807                     ps = mPackages.get(name);
    808                     if (ps == null) {
    809                         Slog.w(PackageManagerService.TAG, "No package known for stopped package: "
    810                                 + name);
    811                         XmlUtils.skipCurrentTag(parser);
    812                         continue;
    813                     }
    814                     String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
    815                     int enabled = enabledStr == null ? COMPONENT_ENABLED_STATE_DEFAULT
    816                             : Integer.parseInt(enabledStr);
    817                     ps.setEnabled(enabled, userId);
    818                     String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
    819                     boolean stopped = stoppedStr == null ? false : Boolean.parseBoolean(stoppedStr);
    820                     ps.setStopped(stopped, userId);
    821                     String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
    822                     boolean notLaunched = stoppedStr == null ? false
    823                             : Boolean.parseBoolean(notLaunchedStr);
    824                     ps.setNotLaunched(notLaunched, userId);
    825 
    826                     int packageDepth = parser.getDepth();
    827                     while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
    828                             && (type != XmlPullParser.END_TAG
    829                             || parser.getDepth() > packageDepth)) {
    830                         if (type == XmlPullParser.END_TAG
    831                                 || type == XmlPullParser.TEXT) {
    832                             continue;
    833                         }
    834                         tagName = parser.getName();
    835                         if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
    836                             HashSet<String> components = readComponentsLPr(parser);
    837                             ps.setEnabledComponents(components, userId);
    838                         } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
    839                             HashSet<String> components = readComponentsLPr(parser);
    840                             ps.setDisabledComponents(components, userId);
    841                         }
    842                     }
    843                 } else {
    844                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
    845                           + parser.getName());
    846                     XmlUtils.skipCurrentTag(parser);
    847                 }
    848             }
    849 
    850             str.close();
    851 
    852         } catch (XmlPullParserException e) {
    853             mReadMessages.append("Error reading: " + e.toString());
    854             PackageManagerService.reportSettingsProblem(Log.ERROR,
    855                     "Error reading stopped packages: " + e);
    856             Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
    857 
    858         } catch (java.io.IOException e) {
    859             mReadMessages.append("Error reading: " + e.toString());
    860             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
    861             Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
    862         }
    863     }
    864 
    865     private HashSet<String> readComponentsLPr(XmlPullParser parser)
    866             throws IOException, XmlPullParserException {
    867         HashSet<String> components = new HashSet<String>();
    868         int type;
    869         int outerDepth = parser.getDepth();
    870         String tagName;
    871         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
    872                 && (type != XmlPullParser.END_TAG
    873                 || parser.getDepth() > outerDepth)) {
    874             if (type == XmlPullParser.END_TAG
    875                     || type == XmlPullParser.TEXT) {
    876                 continue;
    877             }
    878             tagName = parser.getName();
    879             if (tagName.equals(TAG_ITEM)) {
    880                 String componentName = parser.getAttributeValue(null, ATTR_NAME);
    881                 if (componentName != null) {
    882                     components.add(componentName);
    883                 }
    884             }
    885         }
    886         return components;
    887     }
    888 
    889     void writePackageRestrictionsLPr(int userId) {
    890         // Keep the old stopped packages around until we know the new ones have
    891         // been successfully written.
    892         File userPackagesStateFile = getUserPackagesStateFile(userId);
    893         File backupFile = getUserPackagesStateBackupFile(userId);
    894         new File(userPackagesStateFile.getParent()).mkdirs();
    895         if (userPackagesStateFile.exists()) {
    896             // Presence of backup settings file indicates that we failed
    897             // to persist packages earlier. So preserve the older
    898             // backup for future reference since the current packages
    899             // might have been corrupted.
    900             if (!backupFile.exists()) {
    901                 if (!userPackagesStateFile.renameTo(backupFile)) {
    902                     Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, "
    903                             + "current changes will be lost at reboot");
    904                     return;
    905                 }
    906             } else {
    907                 userPackagesStateFile.delete();
    908                 Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
    909             }
    910         }
    911 
    912         try {
    913             final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);
    914             final BufferedOutputStream str = new BufferedOutputStream(fstr);
    915 
    916             final XmlSerializer serializer = new FastXmlSerializer();
    917             serializer.setOutput(str, "utf-8");
    918             serializer.startDocument(null, true);
    919             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
    920 
    921             serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
    922 
    923             for (final PackageSetting pkg : mPackages.values()) {
    924                 if (pkg.getStopped(userId)
    925                         || pkg.getNotLaunched(userId)
    926                         || pkg.getEnabled(userId) != COMPONENT_ENABLED_STATE_DEFAULT
    927                         || pkg.getEnabledComponents(userId).size() > 0
    928                         || pkg.getDisabledComponents(userId).size() > 0) {
    929                     serializer.startTag(null, TAG_PACKAGE);
    930                     serializer.attribute(null, ATTR_NAME, pkg.name);
    931                     boolean stopped = pkg.getStopped(userId);
    932                     boolean notLaunched = pkg.getNotLaunched(userId);
    933                     int enabled = pkg.getEnabled(userId);
    934                     HashSet<String> enabledComponents = pkg.getEnabledComponents(userId);
    935                     HashSet<String> disabledComponents = pkg.getDisabledComponents(userId);
    936 
    937                     if (stopped) {
    938                         serializer.attribute(null, ATTR_STOPPED, "true");
    939                     }
    940                     if (notLaunched) {
    941                         serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
    942                     }
    943                     if (enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
    944                         serializer.attribute(null, ATTR_ENABLED, Integer.toString(enabled));
    945                     }
    946                     if (enabledComponents.size() > 0) {
    947                         serializer.startTag(null, TAG_ENABLED_COMPONENTS);
    948                         for (final String name : enabledComponents) {
    949                             serializer.startTag(null, TAG_ITEM);
    950                             serializer.attribute(null, ATTR_NAME, name);
    951                             serializer.endTag(null, TAG_ITEM);
    952                         }
    953                         serializer.endTag(null, TAG_ENABLED_COMPONENTS);
    954                     }
    955                     if (disabledComponents.size() > 0) {
    956                         serializer.startTag(null, TAG_DISABLED_COMPONENTS);
    957                         for (final String name : disabledComponents) {
    958                             serializer.startTag(null, TAG_ITEM);
    959                             serializer.attribute(null, ATTR_NAME, name);
    960                             serializer.endTag(null, TAG_ITEM);
    961                         }
    962                         serializer.endTag(null, TAG_DISABLED_COMPONENTS);
    963                     }
    964                     serializer.endTag(null, TAG_PACKAGE);
    965                 }
    966             }
    967 
    968             serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
    969 
    970             serializer.endDocument();
    971 
    972             str.flush();
    973             FileUtils.sync(fstr);
    974             str.close();
    975 
    976             // New settings successfully written, old ones are no longer
    977             // needed.
    978             backupFile.delete();
    979             FileUtils.setPermissions(userPackagesStateFile.toString(),
    980                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
    981                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
    982                     -1, -1);
    983 
    984             // Done, all is good!
    985             return;
    986         } catch(java.io.IOException e) {
    987             Log.wtf(PackageManagerService.TAG,
    988                     "Unable to write package manager user packages state, "
    989                     + " current changes will be lost at reboot", e);
    990         }
    991 
    992         // Clean up partially written files
    993         if (userPackagesStateFile.exists()) {
    994             if (!userPackagesStateFile.delete()) {
    995                 Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
    996                         + mStoppedPackagesFilename);
    997             }
    998         }
    999     }
   1000 
   1001     // Note: assumed "stopped" field is already cleared in all packages.
   1002     // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
   1003     void readStoppedLPw() {
   1004         FileInputStream str = null;
   1005         if (mBackupStoppedPackagesFilename.exists()) {
   1006             try {
   1007                 str = new FileInputStream(mBackupStoppedPackagesFilename);
   1008                 mReadMessages.append("Reading from backup stopped packages file\n");
   1009                 PackageManagerService.reportSettingsProblem(Log.INFO,
   1010                         "Need to read from backup stopped packages file");
   1011                 if (mSettingsFilename.exists()) {
   1012                     // If both the backup and normal file exist, we
   1013                     // ignore the normal one since it might have been
   1014                     // corrupted.
   1015                     Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
   1016                             + mStoppedPackagesFilename);
   1017                     mStoppedPackagesFilename.delete();
   1018                 }
   1019             } catch (java.io.IOException e) {
   1020                 // We'll try for the normal settings file.
   1021             }
   1022         }
   1023 
   1024         try {
   1025             if (str == null) {
   1026                 if (!mStoppedPackagesFilename.exists()) {
   1027                     mReadMessages.append("No stopped packages file found\n");
   1028                     PackageManagerService.reportSettingsProblem(Log.INFO,
   1029                             "No stopped packages file file; assuming all started");
   1030                     // At first boot, make sure no packages are stopped.
   1031                     // We usually want to have third party apps initialize
   1032                     // in the stopped state, but not at first boot.
   1033                     for (PackageSetting pkg : mPackages.values()) {
   1034                         pkg.setStopped(false, 0);
   1035                         pkg.setNotLaunched(false, 0);
   1036                     }
   1037                     return;
   1038                 }
   1039                 str = new FileInputStream(mStoppedPackagesFilename);
   1040             }
   1041             final XmlPullParser parser = Xml.newPullParser();
   1042             parser.setInput(str, null);
   1043 
   1044             int type;
   1045             while ((type=parser.next()) != XmlPullParser.START_TAG
   1046                        && type != XmlPullParser.END_DOCUMENT) {
   1047                 ;
   1048             }
   1049 
   1050             if (type != XmlPullParser.START_TAG) {
   1051                 mReadMessages.append("No start tag found in stopped packages file\n");
   1052                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1053                         "No start tag found in package manager stopped packages");
   1054                 return;
   1055             }
   1056 
   1057             int outerDepth = parser.getDepth();
   1058             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
   1059                    && (type != XmlPullParser.END_TAG
   1060                            || parser.getDepth() > outerDepth)) {
   1061                 if (type == XmlPullParser.END_TAG
   1062                         || type == XmlPullParser.TEXT) {
   1063                     continue;
   1064                 }
   1065 
   1066                 String tagName = parser.getName();
   1067                 if (tagName.equals(TAG_PACKAGE)) {
   1068                     String name = parser.getAttributeValue(null, ATTR_NAME);
   1069                     PackageSetting ps = mPackages.get(name);
   1070                     if (ps != null) {
   1071                         ps.setStopped(true, 0);
   1072                         if ("1".equals(parser.getAttributeValue(null, ATTR_NOT_LAUNCHED))) {
   1073                             ps.setNotLaunched(true, 0);
   1074                         }
   1075                     } else {
   1076                         Slog.w(PackageManagerService.TAG,
   1077                                 "No package known for stopped package: " + name);
   1078                     }
   1079                     XmlUtils.skipCurrentTag(parser);
   1080                 } else {
   1081                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
   1082                           + parser.getName());
   1083                     XmlUtils.skipCurrentTag(parser);
   1084                 }
   1085             }
   1086 
   1087             str.close();
   1088 
   1089         } catch (XmlPullParserException e) {
   1090             mReadMessages.append("Error reading: " + e.toString());
   1091             PackageManagerService.reportSettingsProblem(Log.ERROR,
   1092                     "Error reading stopped packages: " + e);
   1093             Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
   1094 
   1095         } catch (java.io.IOException e) {
   1096             mReadMessages.append("Error reading: " + e.toString());
   1097             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
   1098             Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
   1099 
   1100         }
   1101     }
   1102 
   1103     void writeLPr() {
   1104         //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
   1105 
   1106         // Keep the old settings around until we know the new ones have
   1107         // been successfully written.
   1108         if (mSettingsFilename.exists()) {
   1109             // Presence of backup settings file indicates that we failed
   1110             // to persist settings earlier. So preserve the older
   1111             // backup for future reference since the current settings
   1112             // might have been corrupted.
   1113             if (!mBackupSettingsFilename.exists()) {
   1114                 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
   1115                     Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
   1116                             + " current changes will be lost at reboot");
   1117                     return;
   1118                 }
   1119             } else {
   1120                 mSettingsFilename.delete();
   1121                 Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
   1122             }
   1123         }
   1124 
   1125         mPastSignatures.clear();
   1126 
   1127         try {
   1128             FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
   1129             BufferedOutputStream str = new BufferedOutputStream(fstr);
   1130 
   1131             //XmlSerializer serializer = XmlUtils.serializerInstance();
   1132             XmlSerializer serializer = new FastXmlSerializer();
   1133             serializer.setOutput(str, "utf-8");
   1134             serializer.startDocument(null, true);
   1135             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
   1136 
   1137             serializer.startTag(null, "packages");
   1138 
   1139             serializer.startTag(null, "last-platform-version");
   1140             serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
   1141             serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
   1142             serializer.endTag(null, "last-platform-version");
   1143 
   1144             if (mVerifierDeviceIdentity != null) {
   1145                 serializer.startTag(null, "verifier");
   1146                 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
   1147                 serializer.endTag(null, "verifier");
   1148             }
   1149 
   1150             if (mReadExternalStorageEnforced != null) {
   1151                 serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
   1152                 serializer.attribute(
   1153                         null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
   1154                 serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
   1155             }
   1156 
   1157             serializer.startTag(null, "permission-trees");
   1158             for (BasePermission bp : mPermissionTrees.values()) {
   1159                 writePermissionLPr(serializer, bp);
   1160             }
   1161             serializer.endTag(null, "permission-trees");
   1162 
   1163             serializer.startTag(null, "permissions");
   1164             for (BasePermission bp : mPermissions.values()) {
   1165                 writePermissionLPr(serializer, bp);
   1166             }
   1167             serializer.endTag(null, "permissions");
   1168 
   1169             for (final PackageSetting pkg : mPackages.values()) {
   1170                 writePackageLPr(serializer, pkg);
   1171             }
   1172 
   1173             for (final PackageSetting pkg : mDisabledSysPackages.values()) {
   1174                 writeDisabledSysPackageLPr(serializer, pkg);
   1175             }
   1176 
   1177             writePreferredActivitiesLPr(serializer);
   1178 
   1179             for (final SharedUserSetting usr : mSharedUsers.values()) {
   1180                 serializer.startTag(null, "shared-user");
   1181                 serializer.attribute(null, ATTR_NAME, usr.name);
   1182                 serializer.attribute(null, "userId",
   1183                         Integer.toString(usr.userId));
   1184                 usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
   1185                 serializer.startTag(null, "perms");
   1186                 for (String name : usr.grantedPermissions) {
   1187                     serializer.startTag(null, TAG_ITEM);
   1188                     serializer.attribute(null, ATTR_NAME, name);
   1189                     serializer.endTag(null, TAG_ITEM);
   1190                 }
   1191                 serializer.endTag(null, "perms");
   1192                 serializer.endTag(null, "shared-user");
   1193             }
   1194 
   1195             if (mPackagesToBeCleaned.size() > 0) {
   1196                 for (int i=0; i<mPackagesToBeCleaned.size(); i++) {
   1197                     serializer.startTag(null, "cleaning-package");
   1198                     serializer.attribute(null, ATTR_NAME, mPackagesToBeCleaned.get(i));
   1199                     serializer.endTag(null, "cleaning-package");
   1200                 }
   1201             }
   1202 
   1203             if (mRenamedPackages.size() > 0) {
   1204                 for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
   1205                     serializer.startTag(null, "renamed-package");
   1206                     serializer.attribute(null, "new", e.getKey());
   1207                     serializer.attribute(null, "old", e.getValue());
   1208                     serializer.endTag(null, "renamed-package");
   1209                 }
   1210             }
   1211 
   1212             serializer.endTag(null, "packages");
   1213 
   1214             serializer.endDocument();
   1215 
   1216             str.flush();
   1217             FileUtils.sync(fstr);
   1218             str.close();
   1219 
   1220             // New settings successfully written, old ones are no longer
   1221             // needed.
   1222             mBackupSettingsFilename.delete();
   1223             FileUtils.setPermissions(mSettingsFilename.toString(),
   1224                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
   1225                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
   1226                     -1, -1);
   1227 
   1228             // Write package list file now, use a JournaledFile.
   1229             //
   1230             File tempFile = new File(mPackageListFilename.toString() + ".tmp");
   1231             JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
   1232 
   1233             fstr = new FileOutputStream(journal.chooseForWrite());
   1234             str = new BufferedOutputStream(fstr);
   1235             try {
   1236                 StringBuilder sb = new StringBuilder();
   1237                 for (final PackageSetting pkg : mPackages.values()) {
   1238                     ApplicationInfo ai = pkg.pkg.applicationInfo;
   1239                     String dataPath = ai.dataDir;
   1240                     boolean isDebug  = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
   1241 
   1242                     // Avoid any application that has a space in its path
   1243                     // or that is handled by the system.
   1244                     if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
   1245                         continue;
   1246 
   1247                     // we store on each line the following information for now:
   1248                     //
   1249                     // pkgName    - package name
   1250                     // userId     - application-specific user id
   1251                     // debugFlag  - 0 or 1 if the package is debuggable.
   1252                     // dataPath   - path to package's data path
   1253                     //
   1254                     // NOTE: We prefer not to expose all ApplicationInfo flags for now.
   1255                     //
   1256                     // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
   1257                     // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
   1258                     //   system/core/run-as/run-as.c
   1259                     //
   1260                     sb.setLength(0);
   1261                     sb.append(ai.packageName);
   1262                     sb.append(" ");
   1263                     sb.append((int)ai.uid);
   1264                     sb.append(isDebug ? " 1 " : " 0 ");
   1265                     sb.append(dataPath);
   1266                     sb.append("\n");
   1267                     str.write(sb.toString().getBytes());
   1268                 }
   1269                 str.flush();
   1270                 FileUtils.sync(fstr);
   1271                 str.close();
   1272                 journal.commit();
   1273             } catch (Exception e) {
   1274                 IoUtils.closeQuietly(str);
   1275                 journal.rollback();
   1276             }
   1277 
   1278             FileUtils.setPermissions(mPackageListFilename.toString(),
   1279                     FileUtils.S_IRUSR|FileUtils.S_IWUSR
   1280                     |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
   1281                     -1, -1);
   1282 
   1283             writeAllUsersPackageRestrictionsLPr();
   1284             return;
   1285 
   1286         } catch(XmlPullParserException e) {
   1287             Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
   1288                     + "current changes will be lost at reboot", e);
   1289         } catch(java.io.IOException e) {
   1290             Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
   1291                     + "current changes will be lost at reboot", e);
   1292         }
   1293         // Clean up partially written files
   1294         if (mSettingsFilename.exists()) {
   1295             if (!mSettingsFilename.delete()) {
   1296                 Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
   1297                         + mSettingsFilename);
   1298             }
   1299         }
   1300         //Debug.stopMethodTracing();
   1301     }
   1302 
   1303     void writePreferredActivitiesLPr(XmlSerializer serializer)
   1304             throws IllegalArgumentException, IllegalStateException, IOException {
   1305         serializer.startTag(null, "preferred-activities");
   1306         for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
   1307             serializer.startTag(null, TAG_ITEM);
   1308             pa.writeToXml(serializer);
   1309             serializer.endTag(null, TAG_ITEM);
   1310         }
   1311         serializer.endTag(null, "preferred-activities");
   1312     }
   1313 
   1314     void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
   1315             throws java.io.IOException {
   1316         serializer.startTag(null, "updated-package");
   1317         serializer.attribute(null, ATTR_NAME, pkg.name);
   1318         if (pkg.realName != null) {
   1319             serializer.attribute(null, "realName", pkg.realName);
   1320         }
   1321         serializer.attribute(null, "codePath", pkg.codePathString);
   1322         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
   1323         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
   1324         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
   1325         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
   1326         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
   1327             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
   1328         }
   1329         if (pkg.nativeLibraryPathString != null) {
   1330             serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
   1331         }
   1332         if (pkg.sharedUser == null) {
   1333             serializer.attribute(null, "userId", Integer.toString(pkg.appId));
   1334         } else {
   1335             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
   1336         }
   1337         serializer.startTag(null, "perms");
   1338         if (pkg.sharedUser == null) {
   1339             // If this is a shared user, the permissions will
   1340             // be written there. We still need to write an
   1341             // empty permissions list so permissionsFixed will
   1342             // be set.
   1343             for (final String name : pkg.grantedPermissions) {
   1344                 BasePermission bp = mPermissions.get(name);
   1345                 if (bp != null) {
   1346                     // We only need to write signature or system permissions but
   1347                     // this wont
   1348                     // match the semantics of grantedPermissions. So write all
   1349                     // permissions.
   1350                     serializer.startTag(null, TAG_ITEM);
   1351                     serializer.attribute(null, ATTR_NAME, name);
   1352                     serializer.endTag(null, TAG_ITEM);
   1353                 }
   1354             }
   1355         }
   1356         serializer.endTag(null, "perms");
   1357         serializer.endTag(null, "updated-package");
   1358     }
   1359 
   1360     void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
   1361             throws java.io.IOException {
   1362         serializer.startTag(null, "package");
   1363         serializer.attribute(null, ATTR_NAME, pkg.name);
   1364         if (pkg.realName != null) {
   1365             serializer.attribute(null, "realName", pkg.realName);
   1366         }
   1367         serializer.attribute(null, "codePath", pkg.codePathString);
   1368         if (!pkg.resourcePathString.equals(pkg.codePathString)) {
   1369             serializer.attribute(null, "resourcePath", pkg.resourcePathString);
   1370         }
   1371         if (pkg.nativeLibraryPathString != null) {
   1372             serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
   1373         }
   1374         serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
   1375         serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
   1376         serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
   1377         serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
   1378         serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
   1379         if (pkg.sharedUser == null) {
   1380             serializer.attribute(null, "userId", Integer.toString(pkg.appId));
   1381         } else {
   1382             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
   1383         }
   1384         if (pkg.uidError) {
   1385             serializer.attribute(null, "uidError", "true");
   1386         }
   1387         if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
   1388             serializer.attribute(null, "installStatus", "false");
   1389         }
   1390         if (pkg.installerPackageName != null) {
   1391             serializer.attribute(null, "installer", pkg.installerPackageName);
   1392         }
   1393         pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
   1394         if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   1395             serializer.startTag(null, "perms");
   1396             if (pkg.sharedUser == null) {
   1397                 // If this is a shared user, the permissions will
   1398                 // be written there. We still need to write an
   1399                 // empty permissions list so permissionsFixed will
   1400                 // be set.
   1401                 for (final String name : pkg.grantedPermissions) {
   1402                     serializer.startTag(null, TAG_ITEM);
   1403                     serializer.attribute(null, ATTR_NAME, name);
   1404                     serializer.endTag(null, TAG_ITEM);
   1405                 }
   1406             }
   1407             serializer.endTag(null, "perms");
   1408         }
   1409 
   1410         serializer.endTag(null, "package");
   1411     }
   1412 
   1413     void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
   1414             throws XmlPullParserException, java.io.IOException {
   1415         if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
   1416             serializer.startTag(null, TAG_ITEM);
   1417             serializer.attribute(null, ATTR_NAME, bp.name);
   1418             serializer.attribute(null, "package", bp.sourcePackage);
   1419             if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
   1420                 serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
   1421             }
   1422             if (PackageManagerService.DEBUG_SETTINGS)
   1423                 Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
   1424                         + bp.type);
   1425             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   1426                 final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
   1427                 if (pi != null) {
   1428                     serializer.attribute(null, "type", "dynamic");
   1429                     if (pi.icon != 0) {
   1430                         serializer.attribute(null, "icon", Integer.toString(pi.icon));
   1431                     }
   1432                     if (pi.nonLocalizedLabel != null) {
   1433                         serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
   1434                     }
   1435                 }
   1436             }
   1437             serializer.endTag(null, TAG_ITEM);
   1438         }
   1439     }
   1440 
   1441     ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
   1442         final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
   1443         final Iterator<String> its = kList.iterator();
   1444         final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
   1445         while (its.hasNext()) {
   1446             final String key = its.next();
   1447             final PackageSetting ps = mPackages.get(key);
   1448             if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
   1449                 ret.add(ps);
   1450             }
   1451         }
   1452         return ret;
   1453     }
   1454 
   1455     boolean readLPw(List<UserInfo> users) {
   1456         FileInputStream str = null;
   1457         if (mBackupSettingsFilename.exists()) {
   1458             try {
   1459                 str = new FileInputStream(mBackupSettingsFilename);
   1460                 mReadMessages.append("Reading from backup settings file\n");
   1461                 PackageManagerService.reportSettingsProblem(Log.INFO,
   1462                         "Need to read from backup settings file");
   1463                 if (mSettingsFilename.exists()) {
   1464                     // If both the backup and settings file exist, we
   1465                     // ignore the settings since it might have been
   1466                     // corrupted.
   1467                     Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
   1468                             + mSettingsFilename);
   1469                     mSettingsFilename.delete();
   1470                 }
   1471             } catch (java.io.IOException e) {
   1472                 // We'll try for the normal settings file.
   1473             }
   1474         }
   1475 
   1476         mPendingPackages.clear();
   1477         mPastSignatures.clear();
   1478 
   1479         try {
   1480             if (str == null) {
   1481                 if (!mSettingsFilename.exists()) {
   1482                     mReadMessages.append("No settings file found\n");
   1483                     PackageManagerService.reportSettingsProblem(Log.INFO,
   1484                             "No settings file; creating initial state");
   1485                     readDefaultPreferredAppsLPw();
   1486                     return false;
   1487                 }
   1488                 str = new FileInputStream(mSettingsFilename);
   1489             }
   1490             XmlPullParser parser = Xml.newPullParser();
   1491             parser.setInput(str, null);
   1492 
   1493             int type;
   1494             while ((type = parser.next()) != XmlPullParser.START_TAG
   1495                     && type != XmlPullParser.END_DOCUMENT) {
   1496                 ;
   1497             }
   1498 
   1499             if (type != XmlPullParser.START_TAG) {
   1500                 mReadMessages.append("No start tag found in settings file\n");
   1501                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1502                         "No start tag found in package manager settings");
   1503                 Log.wtf(PackageManagerService.TAG,
   1504                         "No start tag found in package manager settings");
   1505                 return false;
   1506             }
   1507 
   1508             int outerDepth = parser.getDepth();
   1509             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   1510                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   1511                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   1512                     continue;
   1513                 }
   1514 
   1515                 String tagName = parser.getName();
   1516                 if (tagName.equals("package")) {
   1517                     readPackageLPw(parser);
   1518                 } else if (tagName.equals("permissions")) {
   1519                     readPermissionsLPw(mPermissions, parser);
   1520                 } else if (tagName.equals("permission-trees")) {
   1521                     readPermissionsLPw(mPermissionTrees, parser);
   1522                 } else if (tagName.equals("shared-user")) {
   1523                     readSharedUserLPw(parser);
   1524                 } else if (tagName.equals("preferred-packages")) {
   1525                     // no longer used.
   1526                 } else if (tagName.equals("preferred-activities")) {
   1527                     readPreferredActivitiesLPw(parser);
   1528                 } else if (tagName.equals("updated-package")) {
   1529                     readDisabledSysPackageLPw(parser);
   1530                 } else if (tagName.equals("cleaning-package")) {
   1531                     String name = parser.getAttributeValue(null, ATTR_NAME);
   1532                     if (name != null) {
   1533                         mPackagesToBeCleaned.add(name);
   1534                     }
   1535                 } else if (tagName.equals("renamed-package")) {
   1536                     String nname = parser.getAttributeValue(null, "new");
   1537                     String oname = parser.getAttributeValue(null, "old");
   1538                     if (nname != null && oname != null) {
   1539                         mRenamedPackages.put(nname, oname);
   1540                     }
   1541                 } else if (tagName.equals("last-platform-version")) {
   1542                     mInternalSdkPlatform = mExternalSdkPlatform = 0;
   1543                     try {
   1544                         String internal = parser.getAttributeValue(null, "internal");
   1545                         if (internal != null) {
   1546                             mInternalSdkPlatform = Integer.parseInt(internal);
   1547                         }
   1548                         String external = parser.getAttributeValue(null, "external");
   1549                         if (external != null) {
   1550                             mExternalSdkPlatform = Integer.parseInt(external);
   1551                         }
   1552                     } catch (NumberFormatException e) {
   1553                     }
   1554                 } else if (tagName.equals("verifier")) {
   1555                     final String deviceIdentity = parser.getAttributeValue(null, "device");
   1556                     try {
   1557                         mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
   1558                     } catch (IllegalArgumentException e) {
   1559                         Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
   1560                                 + e.getMessage());
   1561                     }
   1562                 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
   1563                     final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
   1564                     mReadExternalStorageEnforced = "1".equals(enforcement);
   1565                 } else {
   1566                     Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
   1567                             + parser.getName());
   1568                     XmlUtils.skipCurrentTag(parser);
   1569                 }
   1570             }
   1571 
   1572             str.close();
   1573 
   1574         } catch (XmlPullParserException e) {
   1575             mReadMessages.append("Error reading: " + e.toString());
   1576             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
   1577             Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
   1578 
   1579         } catch (java.io.IOException e) {
   1580             mReadMessages.append("Error reading: " + e.toString());
   1581             PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
   1582             Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
   1583 
   1584         }
   1585 
   1586         final int N = mPendingPackages.size();
   1587         for (int i = 0; i < N; i++) {
   1588             final PendingPackage pp = mPendingPackages.get(i);
   1589             Object idObj = getUserIdLPr(pp.sharedId);
   1590             if (idObj != null && idObj instanceof SharedUserSetting) {
   1591                 PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
   1592                         (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
   1593                         pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags, true, true);
   1594                 if (p == null) {
   1595                     PackageManagerService.reportSettingsProblem(Log.WARN,
   1596                             "Unable to create application package for " + pp.name);
   1597                     continue;
   1598                 }
   1599                 p.copyFrom(pp);
   1600             } else if (idObj != null) {
   1601                 String msg = "Bad package setting: package " + pp.name + " has shared uid "
   1602                         + pp.sharedId + " that is not a shared uid\n";
   1603                 mReadMessages.append(msg);
   1604                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
   1605             } else {
   1606                 String msg = "Bad package setting: package " + pp.name + " has shared uid "
   1607                         + pp.sharedId + " that is not defined\n";
   1608                 mReadMessages.append(msg);
   1609                 PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
   1610             }
   1611         }
   1612         mPendingPackages.clear();
   1613 
   1614         /*
   1615          * Make sure all the updated system packages have their shared users
   1616          * associated with them.
   1617          */
   1618         final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
   1619         while (disabledIt.hasNext()) {
   1620             final PackageSetting disabledPs = disabledIt.next();
   1621             final Object id = getUserIdLPr(disabledPs.appId);
   1622             if (id != null && id instanceof SharedUserSetting) {
   1623                 disabledPs.sharedUser = (SharedUserSetting) id;
   1624             }
   1625         }
   1626 
   1627         if (mBackupStoppedPackagesFilename.exists()
   1628                 || mStoppedPackagesFilename.exists()) {
   1629             // Read old file
   1630             readStoppedLPw();
   1631             mBackupStoppedPackagesFilename.delete();
   1632             mStoppedPackagesFilename.delete();
   1633             // Migrate to new file format
   1634             writePackageRestrictionsLPr(0);
   1635         } else {
   1636             if (users == null) {
   1637                 readPackageRestrictionsLPr(0);
   1638             } else {
   1639                 for (UserInfo user : users) {
   1640                     readPackageRestrictionsLPr(user.id);
   1641                 }
   1642             }
   1643         }
   1644         mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
   1645                 + mSharedUsers.size() + " shared uids\n");
   1646 
   1647         return true;
   1648     }
   1649 
   1650     private void readDefaultPreferredAppsLPw() {
   1651         // Read preferred apps from .../etc/preferred-apps directory.
   1652         File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
   1653         if (!preferredDir.exists() || !preferredDir.isDirectory()) {
   1654             return;
   1655         }
   1656         if (!preferredDir.canRead()) {
   1657             Slog.w(TAG, "Directory " + preferredDir + " cannot be read");
   1658             return;
   1659         }
   1660 
   1661         // Iterate over the files in the directory and scan .xml files
   1662         for (File f : preferredDir.listFiles()) {
   1663             if (!f.getPath().endsWith(".xml")) {
   1664                 Slog.i(TAG, "Non-xml file " + f + " in " + preferredDir + " directory, ignoring");
   1665                 continue;
   1666             }
   1667             if (!f.canRead()) {
   1668                 Slog.w(TAG, "Preferred apps file " + f + " cannot be read");
   1669                 continue;
   1670             }
   1671 
   1672             FileInputStream str = null;
   1673             try {
   1674                 str = new FileInputStream(f);
   1675                 XmlPullParser parser = Xml.newPullParser();
   1676                 parser.setInput(str, null);
   1677 
   1678                 int type;
   1679                 while ((type = parser.next()) != XmlPullParser.START_TAG
   1680                         && type != XmlPullParser.END_DOCUMENT) {
   1681                     ;
   1682                 }
   1683 
   1684                 if (type != XmlPullParser.START_TAG) {
   1685                     Slog.w(TAG, "Preferred apps file " + f + " does not have start tag");
   1686                     continue;
   1687                 }
   1688                 if (!"preferred-activities".equals(parser.getName())) {
   1689                     Slog.w(TAG, "Preferred apps file " + f
   1690                             + " does not start with 'preferred-activities'");
   1691                     continue;
   1692                 }
   1693                 readPreferredActivitiesLPw(parser);
   1694             } catch (XmlPullParserException e) {
   1695                 Slog.w(TAG, "Error reading apps file " + f, e);
   1696             } catch (IOException e) {
   1697                 Slog.w(TAG, "Error reading apps file " + f, e);
   1698             } finally {
   1699                 if (str != null) {
   1700                     try {
   1701                         str.close();
   1702                     } catch (IOException e) {
   1703                     }
   1704                 }
   1705             }
   1706         }
   1707     }
   1708 
   1709     private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
   1710         String v = parser.getAttributeValue(ns, name);
   1711         try {
   1712             if (v == null) {
   1713                 return defValue;
   1714             }
   1715             return Integer.parseInt(v);
   1716         } catch (NumberFormatException e) {
   1717             PackageManagerService.reportSettingsProblem(Log.WARN,
   1718                     "Error in package manager settings: attribute " + name
   1719                             + " has bad integer value " + v + " at "
   1720                             + parser.getPositionDescription());
   1721         }
   1722         return defValue;
   1723     }
   1724 
   1725     private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
   1726             throws IOException, XmlPullParserException {
   1727         int outerDepth = parser.getDepth();
   1728         int type;
   1729         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   1730                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   1731             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   1732                 continue;
   1733             }
   1734 
   1735             final String tagName = parser.getName();
   1736             if (tagName.equals(TAG_ITEM)) {
   1737                 final String name = parser.getAttributeValue(null, ATTR_NAME);
   1738                 final String sourcePackage = parser.getAttributeValue(null, "package");
   1739                 final String ptype = parser.getAttributeValue(null, "type");
   1740                 if (name != null && sourcePackage != null) {
   1741                     final boolean dynamic = "dynamic".equals(ptype);
   1742                     final BasePermission bp = new BasePermission(name, sourcePackage,
   1743                             dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
   1744                     bp.protectionLevel = readInt(parser, null, "protection",
   1745                             PermissionInfo.PROTECTION_NORMAL);
   1746                     bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
   1747                     if (dynamic) {
   1748                         PermissionInfo pi = new PermissionInfo();
   1749                         pi.packageName = sourcePackage.intern();
   1750                         pi.name = name.intern();
   1751                         pi.icon = readInt(parser, null, "icon", 0);
   1752                         pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
   1753                         pi.protectionLevel = bp.protectionLevel;
   1754                         bp.pendingInfo = pi;
   1755                     }
   1756                     out.put(bp.name, bp);
   1757                 } else {
   1758                     PackageManagerService.reportSettingsProblem(Log.WARN,
   1759                             "Error in package manager settings: permissions has" + " no name at "
   1760                                     + parser.getPositionDescription());
   1761                 }
   1762             } else {
   1763                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1764                         "Unknown element reading permissions: " + parser.getName() + " at "
   1765                                 + parser.getPositionDescription());
   1766             }
   1767             XmlUtils.skipCurrentTag(parser);
   1768         }
   1769     }
   1770 
   1771     private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
   1772             IOException {
   1773         String name = parser.getAttributeValue(null, ATTR_NAME);
   1774         String realName = parser.getAttributeValue(null, "realName");
   1775         String codePathStr = parser.getAttributeValue(null, "codePath");
   1776         String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
   1777         String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
   1778         if (resourcePathStr == null) {
   1779             resourcePathStr = codePathStr;
   1780         }
   1781         String version = parser.getAttributeValue(null, "version");
   1782         int versionCode = 0;
   1783         if (version != null) {
   1784             try {
   1785                 versionCode = Integer.parseInt(version);
   1786             } catch (NumberFormatException e) {
   1787             }
   1788         }
   1789 
   1790         int pkgFlags = 0;
   1791         pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
   1792         PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
   1793                 new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
   1794         String timeStampStr = parser.getAttributeValue(null, "ft");
   1795         if (timeStampStr != null) {
   1796             try {
   1797                 long timeStamp = Long.parseLong(timeStampStr, 16);
   1798                 ps.setTimeStamp(timeStamp);
   1799             } catch (NumberFormatException e) {
   1800             }
   1801         } else {
   1802             timeStampStr = parser.getAttributeValue(null, "ts");
   1803             if (timeStampStr != null) {
   1804                 try {
   1805                     long timeStamp = Long.parseLong(timeStampStr);
   1806                     ps.setTimeStamp(timeStamp);
   1807                 } catch (NumberFormatException e) {
   1808                 }
   1809             }
   1810         }
   1811         timeStampStr = parser.getAttributeValue(null, "it");
   1812         if (timeStampStr != null) {
   1813             try {
   1814                 ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
   1815             } catch (NumberFormatException e) {
   1816             }
   1817         }
   1818         timeStampStr = parser.getAttributeValue(null, "ut");
   1819         if (timeStampStr != null) {
   1820             try {
   1821                 ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
   1822             } catch (NumberFormatException e) {
   1823             }
   1824         }
   1825         String idStr = parser.getAttributeValue(null, "userId");
   1826         ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
   1827         if (ps.appId <= 0) {
   1828             String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
   1829             ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
   1830         }
   1831         int outerDepth = parser.getDepth();
   1832         int type;
   1833         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   1834                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   1835             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   1836                 continue;
   1837             }
   1838 
   1839             String tagName = parser.getName();
   1840             if (tagName.equals("perms")) {
   1841                 readGrantedPermissionsLPw(parser, ps.grantedPermissions);
   1842             } else {
   1843                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1844                         "Unknown element under <updated-package>: " + parser.getName());
   1845                 XmlUtils.skipCurrentTag(parser);
   1846             }
   1847         }
   1848         mDisabledSysPackages.put(name, ps);
   1849     }
   1850 
   1851     private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
   1852         String name = null;
   1853         String realName = null;
   1854         String idStr = null;
   1855         String sharedIdStr = null;
   1856         String codePathStr = null;
   1857         String resourcePathStr = null;
   1858         String nativeLibraryPathStr = null;
   1859         String systemStr = null;
   1860         String installerPackageName = null;
   1861         String uidError = null;
   1862         int pkgFlags = 0;
   1863         long timeStamp = 0;
   1864         long firstInstallTime = 0;
   1865         long lastUpdateTime = 0;
   1866         PackageSettingBase packageSetting = null;
   1867         String version = null;
   1868         int versionCode = 0;
   1869         try {
   1870             name = parser.getAttributeValue(null, ATTR_NAME);
   1871             realName = parser.getAttributeValue(null, "realName");
   1872             idStr = parser.getAttributeValue(null, "userId");
   1873             uidError = parser.getAttributeValue(null, "uidError");
   1874             sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
   1875             codePathStr = parser.getAttributeValue(null, "codePath");
   1876             resourcePathStr = parser.getAttributeValue(null, "resourcePath");
   1877             nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
   1878             version = parser.getAttributeValue(null, "version");
   1879             if (version != null) {
   1880                 try {
   1881                     versionCode = Integer.parseInt(version);
   1882                 } catch (NumberFormatException e) {
   1883                 }
   1884             }
   1885             installerPackageName = parser.getAttributeValue(null, "installer");
   1886 
   1887             systemStr = parser.getAttributeValue(null, "flags");
   1888             if (systemStr != null) {
   1889                 try {
   1890                     pkgFlags = Integer.parseInt(systemStr);
   1891                 } catch (NumberFormatException e) {
   1892                 }
   1893             } else {
   1894                 // For backward compatibility
   1895                 systemStr = parser.getAttributeValue(null, "system");
   1896                 if (systemStr != null) {
   1897                     pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
   1898                             : 0;
   1899                 } else {
   1900                     // Old settings that don't specify system... just treat
   1901                     // them as system, good enough.
   1902                     pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
   1903                 }
   1904             }
   1905             String timeStampStr = parser.getAttributeValue(null, "ft");
   1906             if (timeStampStr != null) {
   1907                 try {
   1908                     timeStamp = Long.parseLong(timeStampStr, 16);
   1909                 } catch (NumberFormatException e) {
   1910                 }
   1911             } else {
   1912                 timeStampStr = parser.getAttributeValue(null, "ts");
   1913                 if (timeStampStr != null) {
   1914                     try {
   1915                         timeStamp = Long.parseLong(timeStampStr);
   1916                     } catch (NumberFormatException e) {
   1917                     }
   1918                 }
   1919             }
   1920             timeStampStr = parser.getAttributeValue(null, "it");
   1921             if (timeStampStr != null) {
   1922                 try {
   1923                     firstInstallTime = Long.parseLong(timeStampStr, 16);
   1924                 } catch (NumberFormatException e) {
   1925                 }
   1926             }
   1927             timeStampStr = parser.getAttributeValue(null, "ut");
   1928             if (timeStampStr != null) {
   1929                 try {
   1930                     lastUpdateTime = Long.parseLong(timeStampStr, 16);
   1931                 } catch (NumberFormatException e) {
   1932                 }
   1933             }
   1934             if (PackageManagerService.DEBUG_SETTINGS)
   1935                 Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
   1936                         + " sharedUserId=" + sharedIdStr);
   1937             int userId = idStr != null ? Integer.parseInt(idStr) : 0;
   1938             if (resourcePathStr == null) {
   1939                 resourcePathStr = codePathStr;
   1940             }
   1941             if (realName != null) {
   1942                 realName = realName.intern();
   1943             }
   1944             if (name == null) {
   1945                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1946                         "Error in package manager settings: <package> has no name at "
   1947                                 + parser.getPositionDescription());
   1948             } else if (codePathStr == null) {
   1949                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1950                         "Error in package manager settings: <package> has no codePath at "
   1951                                 + parser.getPositionDescription());
   1952             } else if (userId > 0) {
   1953                 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
   1954                         new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
   1955                         pkgFlags);
   1956                 if (PackageManagerService.DEBUG_SETTINGS)
   1957                     Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
   1958                             + userId + " pkg=" + packageSetting);
   1959                 if (packageSetting == null) {
   1960                     PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
   1961                             + userId + " while parsing settings at "
   1962                             + parser.getPositionDescription());
   1963                 } else {
   1964                     packageSetting.setTimeStamp(timeStamp);
   1965                     packageSetting.firstInstallTime = firstInstallTime;
   1966                     packageSetting.lastUpdateTime = lastUpdateTime;
   1967                 }
   1968             } else if (sharedIdStr != null) {
   1969                 userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
   1970                 if (userId > 0) {
   1971                     packageSetting = new PendingPackage(name.intern(), realName, new File(
   1972                             codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
   1973                             versionCode, pkgFlags);
   1974                     packageSetting.setTimeStamp(timeStamp);
   1975                     packageSetting.firstInstallTime = firstInstallTime;
   1976                     packageSetting.lastUpdateTime = lastUpdateTime;
   1977                     mPendingPackages.add((PendingPackage) packageSetting);
   1978                     if (PackageManagerService.DEBUG_SETTINGS)
   1979                         Log.i(PackageManagerService.TAG, "Reading package " + name
   1980                                 + ": sharedUserId=" + userId + " pkg=" + packageSetting);
   1981                 } else {
   1982                     PackageManagerService.reportSettingsProblem(Log.WARN,
   1983                             "Error in package manager settings: package " + name
   1984                                     + " has bad sharedId " + sharedIdStr + " at "
   1985                                     + parser.getPositionDescription());
   1986                 }
   1987             } else {
   1988                 PackageManagerService.reportSettingsProblem(Log.WARN,
   1989                         "Error in package manager settings: package " + name + " has bad userId "
   1990                                 + idStr + " at " + parser.getPositionDescription());
   1991             }
   1992         } catch (NumberFormatException e) {
   1993             PackageManagerService.reportSettingsProblem(Log.WARN,
   1994                     "Error in package manager settings: package " + name + " has bad userId "
   1995                             + idStr + " at " + parser.getPositionDescription());
   1996         }
   1997         if (packageSetting != null) {
   1998             packageSetting.uidError = "true".equals(uidError);
   1999             packageSetting.installerPackageName = installerPackageName;
   2000             packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
   2001             // Handle legacy string here for single-user mode
   2002             final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
   2003             if (enabledStr != null) {
   2004                 try {
   2005                     packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */);
   2006                 } catch (NumberFormatException e) {
   2007                     if (enabledStr.equalsIgnoreCase("true")) {
   2008                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0);
   2009                     } else if (enabledStr.equalsIgnoreCase("false")) {
   2010                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0);
   2011                     } else if (enabledStr.equalsIgnoreCase("default")) {
   2012                         packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0);
   2013                     } else {
   2014                         PackageManagerService.reportSettingsProblem(Log.WARN,
   2015                                 "Error in package manager settings: package " + name
   2016                                         + " has bad enabled value: " + idStr + " at "
   2017                                         + parser.getPositionDescription());
   2018                     }
   2019                 }
   2020             } else {
   2021                 packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0);
   2022             }
   2023 
   2024             final String installStatusStr = parser.getAttributeValue(null, "installStatus");
   2025             if (installStatusStr != null) {
   2026                 if (installStatusStr.equalsIgnoreCase("false")) {
   2027                     packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
   2028                 } else {
   2029                     packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
   2030                 }
   2031             }
   2032 
   2033             int outerDepth = parser.getDepth();
   2034             int type;
   2035             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   2036                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   2037                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   2038                     continue;
   2039                 }
   2040 
   2041                 String tagName = parser.getName();
   2042                 // Legacy
   2043                 if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
   2044                     readDisabledComponentsLPw(packageSetting, parser, 0);
   2045                 } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
   2046                     readEnabledComponentsLPw(packageSetting, parser, 0);
   2047                 } else if (tagName.equals("sigs")) {
   2048                     packageSetting.signatures.readXml(parser, mPastSignatures);
   2049                 } else if (tagName.equals("perms")) {
   2050                     readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
   2051                     packageSetting.permissionsFixed = true;
   2052                 } else {
   2053                     PackageManagerService.reportSettingsProblem(Log.WARN,
   2054                             "Unknown element under <package>: " + parser.getName());
   2055                     XmlUtils.skipCurrentTag(parser);
   2056                 }
   2057             }
   2058         } else {
   2059             XmlUtils.skipCurrentTag(parser);
   2060         }
   2061     }
   2062 
   2063     private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
   2064             int userId) throws IOException, XmlPullParserException {
   2065         int outerDepth = parser.getDepth();
   2066         int type;
   2067         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   2068                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   2069             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   2070                 continue;
   2071             }
   2072 
   2073             String tagName = parser.getName();
   2074             if (tagName.equals(TAG_ITEM)) {
   2075                 String name = parser.getAttributeValue(null, ATTR_NAME);
   2076                 if (name != null) {
   2077                     packageSetting.addDisabledComponent(name.intern(), userId);
   2078                 } else {
   2079                     PackageManagerService.reportSettingsProblem(Log.WARN,
   2080                             "Error in package manager settings: <disabled-components> has"
   2081                                     + " no name at " + parser.getPositionDescription());
   2082                 }
   2083             } else {
   2084                 PackageManagerService.reportSettingsProblem(Log.WARN,
   2085                         "Unknown element under <disabled-components>: " + parser.getName());
   2086             }
   2087             XmlUtils.skipCurrentTag(parser);
   2088         }
   2089     }
   2090 
   2091     private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
   2092             int userId) throws IOException, XmlPullParserException {
   2093         int outerDepth = parser.getDepth();
   2094         int type;
   2095         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   2096                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   2097             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   2098                 continue;
   2099             }
   2100 
   2101             String tagName = parser.getName();
   2102             if (tagName.equals(TAG_ITEM)) {
   2103                 String name = parser.getAttributeValue(null, ATTR_NAME);
   2104                 if (name != null) {
   2105                     packageSetting.addEnabledComponent(name.intern(), userId);
   2106                 } else {
   2107                     PackageManagerService.reportSettingsProblem(Log.WARN,
   2108                             "Error in package manager settings: <enabled-components> has"
   2109                                     + " no name at " + parser.getPositionDescription());
   2110                 }
   2111             } else {
   2112                 PackageManagerService.reportSettingsProblem(Log.WARN,
   2113                         "Unknown element under <enabled-components>: " + parser.getName());
   2114             }
   2115             XmlUtils.skipCurrentTag(parser);
   2116         }
   2117     }
   2118 
   2119     private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
   2120         String name = null;
   2121         String idStr = null;
   2122         int pkgFlags = 0;
   2123         SharedUserSetting su = null;
   2124         try {
   2125             name = parser.getAttributeValue(null, ATTR_NAME);
   2126             idStr = parser.getAttributeValue(null, "userId");
   2127             int userId = idStr != null ? Integer.parseInt(idStr) : 0;
   2128             if ("true".equals(parser.getAttributeValue(null, "system"))) {
   2129                 pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
   2130             }
   2131             if (name == null) {
   2132                 PackageManagerService.reportSettingsProblem(Log.WARN,
   2133                         "Error in package manager settings: <shared-user> has no name at "
   2134                                 + parser.getPositionDescription());
   2135             } else if (userId == 0) {
   2136                 PackageManagerService.reportSettingsProblem(Log.WARN,
   2137                         "Error in package manager settings: shared-user " + name
   2138                                 + " has bad userId " + idStr + " at "
   2139                                 + parser.getPositionDescription());
   2140             } else {
   2141                 if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
   2142                     PackageManagerService
   2143                             .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
   2144                                     + parser.getPositionDescription());
   2145                 }
   2146             }
   2147         } catch (NumberFormatException e) {
   2148             PackageManagerService.reportSettingsProblem(Log.WARN,
   2149                     "Error in package manager settings: package " + name + " has bad userId "
   2150                             + idStr + " at " + parser.getPositionDescription());
   2151         }
   2152         ;
   2153 
   2154         if (su != null) {
   2155             int outerDepth = parser.getDepth();
   2156             int type;
   2157             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   2158                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   2159                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   2160                     continue;
   2161                 }
   2162 
   2163                 String tagName = parser.getName();
   2164                 if (tagName.equals("sigs")) {
   2165                     su.signatures.readXml(parser, mPastSignatures);
   2166                 } else if (tagName.equals("perms")) {
   2167                     readGrantedPermissionsLPw(parser, su.grantedPermissions);
   2168                 } else {
   2169                     PackageManagerService.reportSettingsProblem(Log.WARN,
   2170                             "Unknown element under <shared-user>: " + parser.getName());
   2171                     XmlUtils.skipCurrentTag(parser);
   2172                 }
   2173             }
   2174 
   2175         } else {
   2176             XmlUtils.skipCurrentTag(parser);
   2177         }
   2178     }
   2179 
   2180     private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
   2181             throws IOException, XmlPullParserException {
   2182         int outerDepth = parser.getDepth();
   2183         int type;
   2184         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   2185                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   2186             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   2187                 continue;
   2188             }
   2189 
   2190             String tagName = parser.getName();
   2191             if (tagName.equals(TAG_ITEM)) {
   2192                 String name = parser.getAttributeValue(null, ATTR_NAME);
   2193                 if (name != null) {
   2194                     outPerms.add(name.intern());
   2195                 } else {
   2196                     PackageManagerService.reportSettingsProblem(Log.WARN,
   2197                             "Error in package manager settings: <perms> has" + " no name at "
   2198                                     + parser.getPositionDescription());
   2199                 }
   2200             } else {
   2201                 PackageManagerService.reportSettingsProblem(Log.WARN,
   2202                         "Unknown element under <perms>: " + parser.getName());
   2203             }
   2204             XmlUtils.skipCurrentTag(parser);
   2205         }
   2206     }
   2207 
   2208     private void readPreferredActivitiesLPw(XmlPullParser parser) throws XmlPullParserException,
   2209             IOException {
   2210         int outerDepth = parser.getDepth();
   2211         int type;
   2212         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
   2213                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
   2214             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
   2215                 continue;
   2216             }
   2217 
   2218             String tagName = parser.getName();
   2219             if (tagName.equals(TAG_ITEM)) {
   2220                 PreferredActivity pa = new PreferredActivity(parser);
   2221                 if (pa.mPref.getParseError() == null) {
   2222                     mPreferredActivities.addFilter(pa);
   2223                 } else {
   2224                     PackageManagerService.reportSettingsProblem(Log.WARN,
   2225                             "Error in package manager settings: <preferred-activity> "
   2226                                     + pa.mPref.getParseError() + " at "
   2227                                     + parser.getPositionDescription());
   2228                 }
   2229             } else {
   2230                 PackageManagerService.reportSettingsProblem(Log.WARN,
   2231                         "Unknown element under <preferred-activities>: " + parser.getName());
   2232                 XmlUtils.skipCurrentTag(parser);
   2233             }
   2234         }
   2235     }
   2236 
   2237     void removeUserLPr(int userId) {
   2238         File file = getUserPackagesStateFile(userId);
   2239         file.delete();
   2240         file = getUserPackagesStateBackupFile(userId);
   2241         file.delete();
   2242     }
   2243 
   2244     // Returns -1 if we could not find an available UserId to assign
   2245     private int newUserIdLPw(Object obj) {
   2246         // Let's be stupidly inefficient for now...
   2247         final int N = mUserIds.size();
   2248         for (int i = 0; i < N; i++) {
   2249             if (mUserIds.get(i) == null) {
   2250                 mUserIds.set(i, obj);
   2251                 return Process.FIRST_APPLICATION_UID + i;
   2252             }
   2253         }
   2254 
   2255         // None left?
   2256         if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
   2257             return -1;
   2258         }
   2259 
   2260         mUserIds.add(obj);
   2261         return Process.FIRST_APPLICATION_UID + N;
   2262     }
   2263 
   2264     public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
   2265         if (mVerifierDeviceIdentity == null) {
   2266             mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
   2267 
   2268             writeLPr();
   2269         }
   2270 
   2271         return mVerifierDeviceIdentity;
   2272     }
   2273 
   2274     public PackageSetting getDisabledSystemPkgLPr(String name) {
   2275         PackageSetting ps = mDisabledSysPackages.get(name);
   2276         return ps;
   2277     }
   2278 
   2279     boolean isEnabledLPr(ComponentInfo componentInfo, int flags, int userId) {
   2280         if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
   2281             return true;
   2282         }
   2283         final String pkgName = componentInfo.packageName;
   2284         final PackageSetting packageSettings = mPackages.get(pkgName);
   2285         if (PackageManagerService.DEBUG_SETTINGS) {
   2286             Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = "
   2287                     + componentInfo.packageName + " componentName = " + componentInfo.name);
   2288             Log.v(PackageManagerService.TAG, "enabledComponents: "
   2289                     + Arrays.toString(packageSettings.getEnabledComponents(userId).toArray()));
   2290             Log.v(PackageManagerService.TAG, "disabledComponents: "
   2291                     + Arrays.toString(packageSettings.getDisabledComponents(userId).toArray()));
   2292         }
   2293         if (packageSettings == null) {
   2294             return false;
   2295         }
   2296         final int enabled = packageSettings.getEnabled(userId);
   2297         if (enabled == COMPONENT_ENABLED_STATE_DISABLED
   2298                 || enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
   2299                 || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
   2300                     && enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
   2301             return false;
   2302         }
   2303         if (packageSettings.getEnabledComponents(userId).contains(componentInfo.name)) {
   2304             return true;
   2305         }
   2306         if (packageSettings.getDisabledComponents(userId).contains(componentInfo.name)) {
   2307             return false;
   2308         }
   2309         return componentInfo.enabled;
   2310     }
   2311 
   2312     String getInstallerPackageNameLPr(String packageName) {
   2313         final PackageSetting pkg = mPackages.get(packageName);
   2314         if (pkg == null) {
   2315             throw new IllegalArgumentException("Unknown package: " + packageName);
   2316         }
   2317         return pkg.installerPackageName;
   2318     }
   2319 
   2320     int getApplicationEnabledSettingLPr(String packageName, int userId) {
   2321         final PackageSetting pkg = mPackages.get(packageName);
   2322         if (pkg == null) {
   2323             throw new IllegalArgumentException("Unknown package: " + packageName);
   2324         }
   2325         return pkg.getEnabled(userId);
   2326     }
   2327 
   2328     int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
   2329         final String packageName = componentName.getPackageName();
   2330         final PackageSetting pkg = mPackages.get(packageName);
   2331         if (pkg == null) {
   2332             throw new IllegalArgumentException("Unknown component: " + componentName);
   2333         }
   2334         final String classNameStr = componentName.getClassName();
   2335         return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
   2336     }
   2337 
   2338     boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
   2339             boolean allowedByPermission, int uid, int userId) {
   2340         int appId = UserId.getAppId(uid);
   2341         final PackageSetting pkgSetting = mPackages.get(packageName);
   2342         if (pkgSetting == null) {
   2343             throw new IllegalArgumentException("Unknown package: " + packageName);
   2344         }
   2345         if (!allowedByPermission && (appId != pkgSetting.appId)) {
   2346             throw new SecurityException(
   2347                     "Permission Denial: attempt to change stopped state from pid="
   2348                     + Binder.getCallingPid()
   2349                     + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
   2350         }
   2351         if (DEBUG_STOPPED) {
   2352             if (stopped) {
   2353                 RuntimeException e = new RuntimeException("here");
   2354                 e.fillInStackTrace();
   2355                 Slog.i(TAG, "Stopping package " + packageName, e);
   2356             }
   2357         }
   2358         if (pkgSetting.getStopped(userId) != stopped) {
   2359             pkgSetting.setStopped(stopped, userId);
   2360             // pkgSetting.pkg.mSetStopped = stopped;
   2361             if (pkgSetting.getNotLaunched(userId)) {
   2362                 if (pkgSetting.installerPackageName != null) {
   2363                     PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
   2364                             pkgSetting.name, null,
   2365                             pkgSetting.installerPackageName, null, userId);
   2366                 }
   2367                 pkgSetting.setNotLaunched(false, userId);
   2368             }
   2369             return true;
   2370         }
   2371         return false;
   2372     }
   2373 
   2374     private List<UserInfo> getAllUsers() {
   2375         long id = Binder.clearCallingIdentity();
   2376         try {
   2377             return AppGlobals.getPackageManager().getUsers();
   2378         } catch (RemoteException re) {
   2379             // Local to system process, shouldn't happen
   2380         } catch (NullPointerException npe) {
   2381             // packagemanager not yet initialized
   2382         } finally {
   2383             Binder.restoreCallingIdentity(id);
   2384         }
   2385         return null;
   2386     }
   2387 
   2388     static final void printFlags(PrintWriter pw, int val, Object[] spec) {
   2389         pw.print("[ ");
   2390         for (int i=0; i<spec.length; i+=2) {
   2391             int mask = (Integer)spec[i];
   2392             if ((val & mask) != 0) {
   2393                 pw.print(spec[i+1]);
   2394                 pw.print(" ");
   2395             }
   2396         }
   2397         pw.print("]");
   2398     }
   2399 
   2400     static final Object[] FLAG_DUMP_SPEC = new Object[] {
   2401         ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
   2402         ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
   2403         ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
   2404         ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
   2405         ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
   2406         ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
   2407         ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
   2408         ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
   2409         ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
   2410         ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
   2411         ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
   2412         ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
   2413         ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
   2414         ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
   2415         ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
   2416         ApplicationInfo.FLAG_STOPPED, "STOPPED",
   2417         ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
   2418         ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
   2419     };
   2420 
   2421     void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState) {
   2422         final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   2423         final Date date = new Date();
   2424         boolean printedSomething = false;
   2425         List<UserInfo> users = getAllUsers();
   2426         for (final PackageSetting ps : mPackages.values()) {
   2427             if (packageName != null && !packageName.equals(ps.realName)
   2428                     && !packageName.equals(ps.name)) {
   2429                 continue;
   2430             }
   2431 
   2432             if (packageName != null) {
   2433                 dumpState.setSharedUser(ps.sharedUser);
   2434             }
   2435 
   2436             if (!printedSomething) {
   2437                 if (dumpState.onTitlePrinted())
   2438                     pw.println(" ");
   2439                 pw.println("Packages:");
   2440                 printedSomething = true;
   2441             }
   2442             pw.print("  Package [");
   2443                 pw.print(ps.realName != null ? ps.realName : ps.name);
   2444                 pw.print("] (");
   2445                 pw.print(Integer.toHexString(System.identityHashCode(ps)));
   2446                 pw.println("):");
   2447 
   2448             if (ps.realName != null) {
   2449                 pw.print("    compat name=");
   2450                 pw.println(ps.name);
   2451             }
   2452 
   2453             pw.print("    userId="); pw.print(ps.appId);
   2454             pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
   2455             pw.print("    sharedUser="); pw.println(ps.sharedUser);
   2456             pw.print("    pkg="); pw.println(ps.pkg);
   2457             pw.print("    codePath="); pw.println(ps.codePathString);
   2458             pw.print("    resourcePath="); pw.println(ps.resourcePathString);
   2459             pw.print("    nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
   2460             pw.print("    versionCode="); pw.println(ps.versionCode);
   2461             if (ps.pkg != null) {
   2462                 pw.print("    applicationInfo="); pw.println(ps.pkg.applicationInfo.toString());
   2463                 pw.print("    flags="); printFlags(pw, ps.pkg.applicationInfo.flags, FLAG_DUMP_SPEC); pw.println();
   2464                 pw.print("    versionName="); pw.println(ps.pkg.mVersionName);
   2465                 pw.print("    dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
   2466                 pw.print("    targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion);
   2467                 if (ps.pkg.mOperationPending) {
   2468                     pw.println("    mOperationPending=true");
   2469                 }
   2470                 pw.print("    supportsScreens=[");
   2471                 boolean first = true;
   2472                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
   2473                     if (!first)
   2474                         pw.print(", ");
   2475                     first = false;
   2476                     pw.print("small");
   2477                 }
   2478                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
   2479                     if (!first)
   2480                         pw.print(", ");
   2481                     first = false;
   2482                     pw.print("medium");
   2483                 }
   2484                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
   2485                     if (!first)
   2486                         pw.print(", ");
   2487                     first = false;
   2488                     pw.print("large");
   2489                 }
   2490                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
   2491                     if (!first)
   2492                         pw.print(", ");
   2493                     first = false;
   2494                     pw.print("xlarge");
   2495                 }
   2496                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
   2497                     if (!first)
   2498                         pw.print(", ");
   2499                     first = false;
   2500                     pw.print("resizeable");
   2501                 }
   2502                 if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
   2503                     if (!first)
   2504                         pw.print(", ");
   2505                     first = false;
   2506                     pw.print("anyDensity");
   2507                 }
   2508             }
   2509             pw.println("]");
   2510             pw.print("    timeStamp=");
   2511                 date.setTime(ps.timeStamp);
   2512                 pw.println(sdf.format(date));
   2513             pw.print("    firstInstallTime=");
   2514                 date.setTime(ps.firstInstallTime);
   2515                 pw.println(sdf.format(date));
   2516             pw.print("    lastUpdateTime=");
   2517                 date.setTime(ps.lastUpdateTime);
   2518                 pw.println(sdf.format(date));
   2519             if (ps.installerPackageName != null) {
   2520                 pw.print("    installerPackageName="); pw.println(ps.installerPackageName);
   2521             }
   2522             pw.print("    signatures="); pw.println(ps.signatures);
   2523             pw.print("    permissionsFixed="); pw.print(ps.permissionsFixed);
   2524             pw.print(" haveGids="); pw.println(ps.haveGids);
   2525             pw.print("    pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
   2526             pw.print(" installStatus="); pw.print(ps.installStatus);
   2527             for (UserInfo user : users) {
   2528                 pw.print(" User "); pw.print(user.id); pw.print(": ");
   2529                 pw.print(" stopped=");
   2530                 pw.print(ps.getStopped(user.id));
   2531                 pw.print(" enabled=");
   2532                 pw.println(ps.getEnabled(user.id));
   2533                 if (ps.getDisabledComponents(user.id).size() > 0) {
   2534                     pw.println("    disabledComponents:");
   2535                     for (String s : ps.getDisabledComponents(user.id)) {
   2536                         pw.print("      "); pw.println(s);
   2537                     }
   2538                 }
   2539                 if (ps.getEnabledComponents(user.id).size() > 0) {
   2540                     pw.println("    enabledComponents:");
   2541                     for (String s : ps.getEnabledComponents(user.id)) {
   2542                         pw.print("      "); pw.println(s);
   2543                     }
   2544                 }
   2545             }
   2546             if (ps.grantedPermissions.size() > 0) {
   2547                 pw.println("    grantedPermissions:");
   2548                 for (String s : ps.grantedPermissions) {
   2549                     pw.print("      "); pw.println(s);
   2550                 }
   2551             }
   2552         }
   2553 
   2554         printedSomething = false;
   2555         if (mRenamedPackages.size() > 0) {
   2556             for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
   2557                 if (packageName != null && !packageName.equals(e.getKey())
   2558                         && !packageName.equals(e.getValue())) {
   2559                     continue;
   2560                 }
   2561                 if (!printedSomething) {
   2562                     if (dumpState.onTitlePrinted())
   2563                         pw.println(" ");
   2564                     pw.println("Renamed packages:");
   2565                     printedSomething = true;
   2566                 }
   2567                 pw.print("  ");
   2568                 pw.print(e.getKey());
   2569                 pw.print(" -> ");
   2570                 pw.println(e.getValue());
   2571             }
   2572         }
   2573 
   2574         printedSomething = false;
   2575         if (mDisabledSysPackages.size() > 0) {
   2576             for (final PackageSetting ps : mDisabledSysPackages.values()) {
   2577                 if (packageName != null && !packageName.equals(ps.realName)
   2578                         && !packageName.equals(ps.name)) {
   2579                     continue;
   2580                 }
   2581                 if (!printedSomething) {
   2582                     if (dumpState.onTitlePrinted())
   2583                         pw.println(" ");
   2584                     pw.println("Hidden system packages:");
   2585                     printedSomething = true;
   2586                 }
   2587                 pw.print("  Package [");
   2588                 pw.print(ps.realName != null ? ps.realName : ps.name);
   2589                 pw.print("] (");
   2590                 pw.print(Integer.toHexString(System.identityHashCode(ps)));
   2591                 pw.println("):");
   2592                 if (ps.realName != null) {
   2593                     pw.print("    compat name=");
   2594                     pw.println(ps.name);
   2595                 }
   2596                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   2597                     pw.print("    applicationInfo=");
   2598                     pw.println(ps.pkg.applicationInfo.toString());
   2599                 }
   2600                 pw.print("    userId=");
   2601                 pw.println(ps.appId);
   2602                 pw.print("    sharedUser=");
   2603                 pw.println(ps.sharedUser);
   2604                 pw.print("    codePath=");
   2605                 pw.println(ps.codePathString);
   2606                 pw.print("    resourcePath=");
   2607                 pw.println(ps.resourcePathString);
   2608             }
   2609         }
   2610     }
   2611 
   2612     void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
   2613         boolean printedSomething = false;
   2614         for (BasePermission p : mPermissions.values()) {
   2615             if (packageName != null && !packageName.equals(p.sourcePackage)) {
   2616                 continue;
   2617             }
   2618             if (!printedSomething) {
   2619                 if (dumpState.onTitlePrinted())
   2620                     pw.println(" ");
   2621                 pw.println("Permissions:");
   2622                 printedSomething = true;
   2623             }
   2624             pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
   2625                     pw.print(Integer.toHexString(System.identityHashCode(p)));
   2626                     pw.println("):");
   2627             pw.print("    sourcePackage="); pw.println(p.sourcePackage);
   2628             pw.print("    uid="); pw.print(p.uid);
   2629                     pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
   2630                     pw.print(" type="); pw.print(p.type);
   2631                     pw.print(" prot=");
   2632                     pw.println(PermissionInfo.protectionToString(p.protectionLevel));
   2633             if (p.packageSetting != null) {
   2634                 pw.print("    packageSetting="); pw.println(p.packageSetting);
   2635             }
   2636             if (p.perm != null) {
   2637                 pw.print("    perm="); pw.println(p.perm);
   2638             }
   2639             if (READ_EXTERNAL_STORAGE.equals(p.name)) {
   2640                 pw.print("    enforced=");
   2641                 pw.println(mReadExternalStorageEnforced);
   2642             }
   2643         }
   2644     }
   2645 
   2646     void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
   2647         boolean printedSomething = false;
   2648         for (SharedUserSetting su : mSharedUsers.values()) {
   2649             if (packageName != null && su != dumpState.getSharedUser()) {
   2650                 continue;
   2651             }
   2652             if (!printedSomething) {
   2653                 if (dumpState.onTitlePrinted())
   2654                     pw.println(" ");
   2655                 pw.println("Shared users:");
   2656                 printedSomething = true;
   2657             }
   2658             pw.print("  SharedUser [");
   2659             pw.print(su.name);
   2660             pw.print("] (");
   2661             pw.print(Integer.toHexString(System.identityHashCode(su)));
   2662                     pw.println("):");
   2663             pw.print("    userId=");
   2664             pw.print(su.userId);
   2665             pw.print(" gids=");
   2666             pw.println(PackageManagerService.arrayToString(su.gids));
   2667             pw.println("    grantedPermissions:");
   2668             for (String s : su.grantedPermissions) {
   2669                 pw.print("      ");
   2670                 pw.println(s);
   2671             }
   2672         }
   2673     }
   2674 
   2675     void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
   2676         pw.println("Settings parse messages:");
   2677         pw.print(mReadMessages.toString());
   2678     }
   2679 }
   2680