return ret;
}
}
}
private static final String SD_ENCRYPTION_ALGORITHM = "AES";
<<<<<<< HEAD:services/java/com/android/server/pm/PackageManagerService.java
=======
static class PackageSignatures {
private Signature[] mSignatures;
PackageSignatures(PackageSignatures orig) {
if (orig != null && orig.mSignatures != null) {
mSignatures = orig.mSignatures.clone();
}
}
PackageSignatures(Signature[] sigs) {
assignSignatures(sigs);
}
PackageSignatures() {
}
void writeXml(XmlSerializer serializer, String tagName,
ArrayList pastSignatures) throws IOException {
if (mSignatures == null) {
return;
}
serializer.startTag(null, tagName);
serializer.attribute(null, "count",
Integer.toString(mSignatures.length));
for (int i=0; i= numPast) {
pastSignatures.add(sig);
serializer.attribute(null, "index", Integer.toString(numPast));
serializer.attribute(null, "key", sig.toCharsString());
}
serializer.endTag(null, "cert");
}
serializer.endTag(null, tagName);
}
void readXml(XmlPullParser parser, ArrayList pastSignatures)
throws IOException, XmlPullParserException {
String countStr = parser.getAttributeValue(null, "count");
if (countStr == null) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has"
+ " no count at " + parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
}
final int count = Integer.parseInt(countStr);
mSignatures = new Signature[count];
int pos = 0;
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("cert")) {
if (pos < count) {
String index = parser.getAttributeValue(null, "index");
if (index != null) {
try {
int idx = Integer.parseInt(index);
String key = parser.getAttributeValue(null, "key");
if (key == null) {
if (idx >= 0 && idx < pastSignatures.size()) {
Signature sig = pastSignatures.get(idx);
if (sig != null) {
mSignatures[pos] = pastSignatures.get(idx);
pos++;
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: "
+ "index " + index + " is not defined at "
+ parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: "
+ "index " + index + " is out of bounds at "
+ parser.getPositionDescription());
}
} else {
while (pastSignatures.size() <= idx) {
pastSignatures.add(null);
}
Signature sig = new Signature(key);
pastSignatures.set(idx, sig);
mSignatures[pos] = sig;
pos++;
}
} catch (NumberFormatException e) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: "
+ "index " + index + " is not a number at "
+ parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has"
+ " no index at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: too "
+ "many tags, expected " + count
+ " at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
if (pos < count) {
// Should never happen -- there is an error in the written
// settings -- but if it does we don't want to generate
// a bad array.
Signature[] newSigs = new Signature[pos];
System.arraycopy(mSignatures, 0, newSigs, 0, pos);
mSignatures = newSigs;
}
}
private void assignSignatures(Signature[] sigs) {
if (sigs == null) {
mSignatures = null;
return;
}
mSignatures = new Signature[sigs.length];
for (int i=0; i 0) buf.append(", ");
buf.append(Integer.toHexString(
System.identityHashCode(mSignatures[i])));
}
}
buf.append("]}");
return buf.toString();
}
}
static class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks {
final PreferredComponent mPref;
PreferredActivity(IntentFilter filter, int match, ComponentName[] set,
ComponentName activity) {
super(filter);
mPref = new PreferredComponent(this, match, set, activity);
}
PreferredActivity(XmlPullParser parser) throws XmlPullParserException,
IOException {
mPref = new PreferredComponent(this, parser);
}
public void writeToXml(XmlSerializer serializer) throws IOException {
mPref.writeToXml(serializer);
serializer.startTag(null, "filter");
super.writeToXml(serializer);
serializer.endTag(null, "filter");
}
public boolean onReadTag(String tagName, XmlPullParser parser)
throws XmlPullParserException, IOException {
if (tagName.equals("filter")) {
//Log.i(TAG, "Starting to parse filter...");
readFromXml(parser);
//Log.i(TAG, "Finished filter: outerDepth=" + outerDepth + " depth="
// + parser.getDepth() + " tag=" + parser.getName());
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
return true;
}
}
static class GrantedPermissions {
int pkgFlags;
HashSet grantedPermissions = new HashSet();
int[] gids;
GrantedPermissions(int pkgFlags) {
setFlags(pkgFlags);
}
GrantedPermissions(GrantedPermissions base) {
pkgFlags = base.pkgFlags;
grantedPermissions = (HashSet) base.grantedPermissions.clone();
if (base.gids != null) {
gids = base.gids.clone();
}
}
void setFlags(int pkgFlags) {
this.pkgFlags = pkgFlags & (
ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_FORWARD_LOCK |
ApplicationInfo.FLAG_EXTERNAL_STORAGE);
}
}
/**
* Settings base class for pending and resolved classes.
*/
static class PackageSettingBase extends GrantedPermissions {
final String name;
final String realName;
File codePath;
String codePathString;
File resourcePath;
String resourcePathString;
String nativeLibraryPathString;
long timeStamp;
long firstInstallTime;
long lastUpdateTime;
int versionCode;
boolean uidError;
PackageSignatures signatures = new PackageSignatures();
boolean permissionsFixed;
boolean haveGids;
// Whether this package is currently stopped, thus can not be
// started until explicitly launched by the user.
public boolean stopped;
// Set to true if we have never launched this app.
public boolean notLaunched;
/* Explicitly disabled components */
HashSet disabledComponents = new HashSet(0);
/* Explicitly enabled components */
HashSet enabledComponents = new HashSet(0);
int enabled = COMPONENT_ENABLED_STATE_DEFAULT;
int installStatus = PKG_INSTALL_COMPLETE;
PackageSettingBase origPackage;
/* package name of the app that installed this package */
String installerPackageName;
PackageSettingBase(String name, String realName, File codePath, File resourcePath,
String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
super(pkgFlags);
this.name = name;
this.realName = realName;
init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
}
/**
* New instance of PackageSetting with one-level-deep cloning.
*/
PackageSettingBase(PackageSettingBase base) {
super(base);
name = base.name;
realName = base.realName;
codePath = base.codePath;
codePathString = base.codePathString;
resourcePath = base.resourcePath;
resourcePathString = base.resourcePathString;
nativeLibraryPathString = base.nativeLibraryPathString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
versionCode = base.versionCode;
uidError = base.uidError;
signatures = new PackageSignatures(base.signatures);
permissionsFixed = base.permissionsFixed;
haveGids = base.haveGids;
stopped = base.stopped;
notLaunched = base.notLaunched;
disabledComponents = (HashSet) base.disabledComponents.clone();
enabledComponents = (HashSet) base.enabledComponents.clone();
enabled = base.enabled;
installStatus = base.installStatus;
origPackage = base.origPackage;
installerPackageName = base.installerPackageName;
}
void init(File codePath, File resourcePath, String nativeLibraryPathString,
int pVersionCode) {
this.codePath = codePath;
this.codePathString = codePath.toString();
this.resourcePath = resourcePath;
this.resourcePathString = resourcePath.toString();
this.nativeLibraryPathString = nativeLibraryPathString;
this.versionCode = pVersionCode;
}
public void setInstallerPackageName(String packageName) {
installerPackageName = packageName;
}
String getInstallerPackageName() {
return installerPackageName;
}
public void setInstallStatus(int newStatus) {
installStatus = newStatus;
}
public int getInstallStatus() {
return installStatus;
}
public void setTimeStamp(long newStamp) {
timeStamp = newStamp;
}
/**
* Make a shallow copy of this package settings.
*/
public void copyFrom(PackageSettingBase base) {
grantedPermissions = base.grantedPermissions;
gids = base.gids;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
signatures = base.signatures;
permissionsFixed = base.permissionsFixed;
haveGids = base.haveGids;
stopped = base.stopped;
notLaunched = base.notLaunched;
disabledComponents = base.disabledComponents;
enabledComponents = base.enabledComponents;
enabled = base.enabled;
installStatus = base.installStatus;
}
boolean enableComponentLP(String componentClassName) {
boolean changed = disabledComponents.remove(componentClassName);
changed |= enabledComponents.add(componentClassName);
return changed;
}
boolean disableComponentLP(String componentClassName) {
boolean changed = enabledComponents.remove(componentClassName);
changed |= disabledComponents.add(componentClassName);
return changed;
}
boolean restoreComponentLP(String componentClassName) {
boolean changed = enabledComponents.remove(componentClassName);
changed |= disabledComponents.remove(componentClassName);
return changed;
}
int currentEnabledStateLP(String componentName) {
if (enabledComponents.contains(componentName)) {
return COMPONENT_ENABLED_STATE_ENABLED;
} else if (disabledComponents.contains(componentName)) {
return COMPONENT_ENABLED_STATE_DISABLED;
} else {
return COMPONENT_ENABLED_STATE_DEFAULT;
}
}
}
/**
* Settings data for a particular package we know about.
*/
static final class PackageSetting extends PackageSettingBase {
int userId;
PackageParser.Package pkg;
SharedUserSetting sharedUser;
PackageSetting(String name, String realName, File codePath, File resourcePath,
String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
pkgFlags);
}
/**
* New instance of PackageSetting replicating the original settings.
* Note that it keeps the same PackageParser.Package instance.
*/
PackageSetting(PackageSetting orig) {
super(orig);
userId = orig.userId;
pkg = orig.pkg;
sharedUser = orig.sharedUser;
}
@Override
public String toString() {
return "PackageSetting{"
+ Integer.toHexString(System.identityHashCode(this))
+ " " + name + "/" + userId + "}";
}
}
/**
* Settings data for a particular shared user ID we know about.
*/
static final class SharedUserSetting extends GrantedPermissions {
final String name;
int userId;
final HashSet packages = new HashSet();
final PackageSignatures signatures = new PackageSignatures();
SharedUserSetting(String _name, int _pkgFlags) {
super(_pkgFlags);
name = _name;
}
@Override
public String toString() {
return "SharedUserSetting{"
systemDir.mkdirs();
+ Integer.toHexString(System.identityHashCode(this))
+ " " + name + "/" + userId + "}";
}
}
/**
* Holds information about dynamic settings.
*/
private static final class Settings {
private final File mSettingsFilename;
private final File mBackupSettingsFilename;
private final File mPackageListFilename;
private final File mStoppedPackagesFilename;
private final File mBackupStoppedPackagesFilename;
private final HashMap mPackages =
new HashMap();
// List of replaced system applications
final HashMap mDisabledSysPackages =
new HashMap();
// These are the last platform API version we were using for
// the apps installed on internal and external storage. It is
// used to grant newer permissions one time during a system upgrade.
int mInternalSdkPlatform;
int mExternalSdkPlatform;
// The user's preferred activities associated with particular intent
// filters.
private final IntentResolver mPreferredActivities =
new IntentResolver() {
@Override
protected String packageForFilter(PreferredActivity filter) {
return filter.mPref.mComponent.getPackageName();
}
@Override
protected void dumpFilter(PrintWriter out, String prefix,
PreferredActivity filter) {
filter.mPref.dump(out, prefix, filter);
}
};
private final HashMap mSharedUsers =
new HashMap();
private final ArrayList mUserIds = new ArrayList();
private final SparseArray mOtherUserIds =
new SparseArray();
// For reading/writing settings file.
private final ArrayList mPastSignatures =
new ArrayList();
// Mapping from permission names to info about them.
final HashMap mPermissions =
new HashMap();
// Mapping from permission tree names to info about them.
final HashMap mPermissionTrees =
new HashMap();
// Packages that have been uninstalled and still need their external
// storage data deleted.
final ArrayList mPackagesToBeCleaned = new ArrayList();
// Packages that have been renamed since they were first installed.
// Keys are the new names of the packages, values are the original
// names. The packages appear everwhere else under their original
// names.
final HashMap mRenamedPackages = new HashMap();
private final StringBuilder mReadMessages = new StringBuilder();
private static final class PendingPackage extends PackageSettingBase {
final int sharedId;
PendingPackage(String name, String realName, File codePath, File resourcePath,
String nativeLibraryPathString, int sharedId, int pVersionCode, int pkgFlags) {
super(name, realName, codePath, resourcePath, nativeLibraryPathString,
pVersionCode, pkgFlags);
this.sharedId = sharedId;
}
}
private final ArrayList mPendingPackages
= new ArrayList();
Settings() {
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
FileUtils.setPermissions(systemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
mSettingsFilename = new File(systemDir, "packages.xml");
mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
mPackageListFilename = new File(systemDir, "packages.list");
mStoppedPackagesFilename = new File(systemDir, "packages-stopped.xml");
mBackupStoppedPackagesFilename = new File(systemDir, "packages-stopped-backup.xml");
}
PackageSetting getPackageLP(PackageParser.Package pkg, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
String nativeLibraryPathString, int pkgFlags, boolean create, boolean add) {
final String name = pkg.packageName;
PackageSetting p = getPackageLP(name, origPackage, realName, sharedUser, codePath,
resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, create, add);
return p;
}
PackageSetting peekPackageLP(String name) {
return mPackages.get(name);
/*
PackageSetting p = mPackages.get(name);
if (p != null && p.codePath.getPath().equals(codePath)) {
return p;
}
return null;
*/
}
void setInstallStatus(String pkgName, int status) {
PackageSetting p = mPackages.get(pkgName);
if(p != null) {
if(p.getInstallStatus() != status) {
p.setInstallStatus(status);
}
}
}
void setInstallerPackageName(String pkgName,
String installerPkgName) {
PackageSetting p = mPackages.get(pkgName);
if(p != null) {
p.setInstallerPackageName(installerPkgName);
}
}
String getInstallerPackageName(String pkgName) {
PackageSetting p = mPackages.get(pkgName);
return (p == null) ? null : p.getInstallerPackageName();
}
int getInstallStatus(String pkgName) {
PackageSetting p = mPackages.get(pkgName);
if(p != null) {
return p.getInstallStatus();
}
return -1;
}
SharedUserSetting getSharedUserLP(String name,
int pkgFlags, boolean create) {
SharedUserSetting s = mSharedUsers.get(name);
if (s == null) {
if (!create) {
return null;
}
s = new SharedUserSetting(name, pkgFlags);
if (MULTIPLE_APPLICATION_UIDS) {
s.userId = newUserIdLP(s);
} else {
s.userId = FIRST_APPLICATION_UID;
}
Log.i(TAG, "New shared user " + name + ": id=" + s.userId);
// < 0 means we couldn't assign a userid; fall out and return
// s, which is currently null
if (s.userId >= 0) {
mSharedUsers.put(name, s);
}
}
return s;
}
boolean disableSystemPackageLP(String name) {
PackageSetting p = mPackages.get(name);
if(p == null) {
Log.w(TAG, "Package:"+name+" is not an installed package");
return false;
}
PackageSetting dp = mDisabledSysPackages.get(name);
bp.perm = null;
// always make sure the system package code and resource paths dont change
if (dp == null) {
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
mDisabledSysPackages.put(name, p);
// a little trick... when we install the new package, we don't
// want to modify the existing PackageSetting for the built-in
// version. so at this point we need a new PackageSetting that
// is okay to muck with.
PackageSetting newp = new PackageSetting(p);
replacePackageLP(name, newp);
return true;
}
return false;
}
PackageSetting enableSystemPackageLP(String name) {
PackageSetting p = mDisabledSysPackages.get(name);
if(p == null) {
Log.w(TAG, "Package:"+name+" is not disabled");
return null;
}
// Reset flag in ApplicationInfo object
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
PackageSetting ret = addPackageLP(name, p.realName, p.codePath, p.resourcePath,
p.nativeLibraryPathString, p.userId, p.versionCode, p.pkgFlags);
mDisabledSysPackages.remove(name);
PackageSetting addPackageLP(String name, String realName, File codePath, File resourcePath,
String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.userId == uid) {
return p;
}
reportSettingsProblem(Log.ERROR,
"Adding duplicate package, keeping first: " + name);
return null;
}
p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
vc, pkgFlags);
p.userId = uid;
if (addUserIdLP(uid, p, name)) {
mPackages.put(name, p);
return p;
}
return null;
}
SharedUserSetting addSharedUserLP(String name, int uid, int pkgFlags) {
SharedUserSetting s = mSharedUsers.get(name);
if (s != null) {
if (s.userId == uid) {
return s;
}
reportSettingsProblem(Log.ERROR,
"Adding duplicate shared user, keeping first: " + name);
return null;
}
s = new SharedUserSetting(name, pkgFlags);
s.userId = uid;
if (addUserIdLP(uid, s, name)) {
mSharedUsers.put(name, s);
return s;
}
return null;
}
// Transfer ownership of permissions from one package to another.
private void transferPermissions(String origPkg, String newPkg) {
// Transfer ownership of permissions to the new package.
for (int i=0; i<2; i++) {
HashMap permissions =
i == 0 ? mPermissionTrees : mPermissions;
for (BasePermission bp : permissions.values()) {
if (origPkg.equals(bp.sourcePackage)) {
if (DEBUG_UPGRADE) Log.v(TAG,
"Moving permission " + bp.name
+ " from pkg " + bp.sourcePackage
+ " to " + newPkg);
bp.sourcePackage = newPkg;
bp.packageSetting = null;
if (bp.pendingInfo != null) {
bp.pendingInfo.packageName = newPkg;
}
bp.uid = 0;
bp.gids = null;
}
}
}
}
private PackageSetting getPackageLP(String name, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) {
PackageSetting p = mPackages.get(name);
if (p != null) {
if (!p.codePath.equals(codePath)) {
// Check to see if its a disabled system app
if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
// This is an updated system app with versions in both system
// and data partition. Just let the most recent version
// take precedence.
Slog.w(TAG, "Trying to update system app code path from " +
p.codePathString + " to " + codePath.toString());
} else {
// Just a change in the code path is not an issue, but
// let's log a message about it.
Slog.i(TAG, "Package " + name + " codePath changed from " + p.codePath
+ " to " + codePath + "; Retaining data and using new");
/*
* Since we've changed paths, we need to prefer the new
* native library path over the one stored in the
* package settings since we might have moved from
* internal to external storage or vice versa.
*/
p.nativeLibraryPathString = nativeLibraryPathString;
}
}
if (p.sharedUser != sharedUser) {
reportSettingsProblem(Log.WARN,
"Package " + name + " shared user changed from "
+ (p.sharedUser != null ? p.sharedUser.name : "")
+ " to "
+ (sharedUser != null ? sharedUser.name : "")
+ "; replacing with new");
p = null;
} else {
if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// If what we are scanning is a system package, then
// make it so, regardless of whether it was previously
// installed only in the data partition.
p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
}
}
}
if (p == null) {
// Create a new PackageSettings entry. this can end up here because
// of code path mismatch or user id mismatch of an updated system partition
if (!create) {
return null;
}
if (origPackage != null) {
// We are consuming the data from an existing package.
p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
nativeLibraryPathString, vc, pkgFlags);
if (DEBUG_UPGRADE) Log.v(TAG, "Package " + name
+ " is adopting original package " + origPackage.name);
// Note that we will retain the new package's signature so
// that we can keep its data.
PackageSignatures s = p.signatures;
p.copyFrom(origPackage);
p.signatures = s;
p.sharedUser = origPackage.sharedUser;
p.userId = origPackage.userId;
p.origPackage = origPackage;
mRenamedPackages.put(name, origPackage.name);
name = origPackage.name;
// Update new package state.
p.setTimeStamp(codePath.lastModified());
} else {
p = new PackageSetting(name, realName, codePath, resourcePath,
nativeLibraryPathString, vc, pkgFlags);
p.setTimeStamp(codePath.lastModified());
p.sharedUser = sharedUser;
// If this is not a system app, it starts out stopped.
if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
if (DEBUG_STOPPED) {
RuntimeException e = new RuntimeException("here");
e.fillInStackTrace();
Slog.i(TAG, "Stopping package " + name, e);
}
p.stopped = true;
p.notLaunched = true;
}
if (sharedUser != null) {
p.userId = sharedUser.userId;
} else if (MULTIPLE_APPLICATION_UIDS) {
// Clone the setting here for disabled system packages
PackageSetting dis = mDisabledSysPackages.get(name);
if (dis != null) {
// For disabled packages a new setting is created
// from the existing user id. This still has to be
// added to list of user id's
// Copy signatures from previous setting
if (dis.signatures.mSignatures != null) {
p.signatures.mSignatures = dis.signatures.mSignatures.clone();
}
p.userId = dis.userId;
// Clone permissions
p.grantedPermissions = new HashSet(dis.grantedPermissions);
// Clone component info
p.disabledComponents = new HashSet(dis.disabledComponents);
p.enabledComponents = new HashSet(dis.enabledComponents);
// Add new setting to list of user ids
addUserIdLP(p.userId, p, name);
} else {
// Assign new user id
p.userId = newUserIdLP(p);
}
} else {
p.userId = FIRST_APPLICATION_UID;
}
}
if (p.userId < 0) {
reportSettingsProblem(Log.WARN,
"Package " + name + " could not be assigned a valid uid");
return null;
}
if (add) {
// Finish adding new package by adding it and updating shared
// user preferences
addPackageSettingLP(p, name, sharedUser);
}
}
return p;
}
private void insertPackageSettingLP(PackageSetting p, PackageParser.Package pkg) {
p.pkg = pkg;
pkg.mSetEnabled = p.enabled;
pkg.mSetStopped = p.stopped;
final String codePath = pkg.applicationInfo.sourceDir;
final String resourcePath = pkg.applicationInfo.publicSourceDir;
// Update code path if needed
if (!codePath.equalsIgnoreCase(p.codePathString)) {
Slog.w(TAG, "Code path for pkg : " + p.pkg.packageName +
" changing from " + p.codePathString + " to " + codePath);
p.codePath = new File(codePath);
p.codePathString = codePath;
}
//Update resource path if needed
if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) {
Slog.w(TAG, "Resource path for pkg : " + p.pkg.packageName +
" changing from " + p.resourcePathString + " to " + resourcePath);
p.resourcePath = new File(resourcePath);
p.resourcePathString = resourcePath;
}
// Update the native library path if needed
final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
if (nativeLibraryPath != null
&& !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
p.nativeLibraryPathString = nativeLibraryPath;
}
// Update version code if needed
if (pkg.mVersionCode != p.versionCode) {
p.versionCode = pkg.mVersionCode;
}
// Update signatures if needed.
if (p.signatures.mSignatures == null) {
p.signatures.assignSignatures(pkg.mSignatures);
}
// If this app defines a shared user id initialize
// the shared user signatures as well.
if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
}
addPackageSettingLP(p, pkg.packageName, p.sharedUser);
}
// Utility method that adds a PackageSetting to mPackages and
// completes updating the shared user attributes
private void addPackageSettingLP(PackageSetting p, String name,
SharedUserSetting sharedUser) {
mPackages.put(name, p);
if (sharedUser != null) {
if (p.sharedUser != null && p.sharedUser != sharedUser) {
reportSettingsProblem(Log.ERROR,
"Package " + p.name + " was user "
+ p.sharedUser + " but is now " + sharedUser
+ "; I am not changing its files so it will probably fail!");
p.sharedUser.packages.remove(p);
} else if (p.userId != sharedUser.userId) {
reportSettingsProblem(Log.ERROR,
"Package " + p.name + " was user id " + p.userId
+ " but is now user " + sharedUser
+ " with id " + sharedUser.userId
+ "; I am not changing its files so it will probably fail!");
}
sharedUser.packages.add(p);
p.sharedUser = sharedUser;
p.userId = sharedUser.userId;
}
}
/*
* Update the shared user setting when a package using
* specifying the shared user id is removed. The gids
* associated with each permission of the deleted package
* are removed from the shared user's gid list only if its
* not in use by other permissions of packages in the
* shared user setting.
*/
private void updateSharedUserPermsLP(PackageSetting deletedPs, int[] globalGids) {
if ( (deletedPs == null) || (deletedPs.pkg == null)) {
Slog.i(TAG, "Trying to update info for null package. Just ignoring");
return;
}
// No sharedUserId
if (deletedPs.sharedUser == null) {
return;
}
SharedUserSetting sus = deletedPs.sharedUser;
// Update permissions
for (String eachPerm: deletedPs.pkg.requestedPermissions) {
boolean used = false;
if (!sus.grantedPermissions.contains (eachPerm)) {
continue;
}
for (PackageSetting pkg:sus.packages) {
if (pkg.pkg != null &&
!pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
pkg.pkg.requestedPermissions.contains(eachPerm)) {
used = true;
break;
}
}
if (!used) {
// can safely delete this permission from list
sus.grantedPermissions.remove(eachPerm);
}
}
// Update gids
int newGids[] = globalGids;
for (String eachPerm : sus.grantedPermissions) {
BasePermission bp = mPermissions.get(eachPerm);
if (bp != null) {
newGids = appendInts(newGids, bp.gids);
}
}
sus.gids = newGids;
}
private int removePackageLP(String name) {
PackageSetting p = mPackages.get(name);
if (p != null) {
mPackages.remove(name);
if (p.sharedUser != null) {
p.sharedUser.packages.remove(p);
if (p.sharedUser.packages.size() == 0) {
mSharedUsers.remove(p.sharedUser.name);
removeUserIdLP(p.sharedUser.userId);
return p.sharedUser.userId;
}
} else {
removeUserIdLP(p.userId);
return p.userId;
}
}
return -1;
}
private void replacePackageLP(String name, PackageSetting newp) {
PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.sharedUser != null) {
p.sharedUser.packages.remove(p);
p.sharedUser.packages.add(newp);
} else {
replaceUserIdLP(p.userId, newp);
}
}
mPackages.put(name, newp);
private boolean addUserIdLP(int uid, Object obj, Object name) {
if (uid >= FIRST_APPLICATION_UID + MAX_APPLICATION_UIDS) {
return false;
}
if (uid >= FIRST_APPLICATION_UID) {
int N = mUserIds.size();
final int index = uid - FIRST_APPLICATION_UID;
while (index >= N) {
mUserIds.add(null);
N++;
}
if (mUserIds.get(index) != null) {
reportSettingsProblem(Log.ERROR,
"Adding duplicate user id: " + uid
+ " name=" + name);
return false;
}
mUserIds.set(index, obj);
} else {
if (mOtherUserIds.get(uid) != null) {
reportSettingsProblem(Log.ERROR,
"Adding duplicate shared id: " + uid
+ " name=" + name);
return false;
}
mOtherUserIds.put(uid, obj);
}
return true;
}
public Object getUserIdLP(int uid) {
if (uid >= FIRST_APPLICATION_UID) {
int N = mUserIds.size();
final int index = uid - FIRST_APPLICATION_UID;
return index < N ? mUserIds.get(index) : null;
} else {
return mOtherUserIds.get(uid);
}
}
private Set findPackagesWithFlag(int flag) {
Set ret = new HashSet();
for (PackageSetting ps : mPackages.values()) {
// Has to match atleast all the flag bits set on flag
if ((ps.pkgFlags & flag) == flag) {
ret.add(ps.name);
}
}
return ret;
}
private void removeUserIdLP(int uid) {
if (uid >= FIRST_APPLICATION_UID) {
int N = mUserIds.size();
final int index = uid - FIRST_APPLICATION_UID;
if (index < N) mUserIds.set(index, null);
} else {
mOtherUserIds.remove(uid);
}
}
private void replaceUserIdLP(int uid, Object obj) {
if (uid >= FIRST_APPLICATION_UID) {
int N = mUserIds.size();
final int index = uid - FIRST_APPLICATION_UID;
if (index < N) mUserIds.set(index, obj);
} else {
mOtherUserIds.put(uid, obj);
}
}
void writeStoppedLP() {
// Keep the old stopped packages around until we know the new ones have
// been successfully written.
if (mStoppedPackagesFilename.exists()) {
// Presence of backup settings file indicates that we failed
// to persist packages earlier. So preserve the older
// backup for future reference since the current packages
// might have been corrupted.
if (!mBackupStoppedPackagesFilename.exists()) {
if (!mStoppedPackagesFilename.renameTo(mBackupStoppedPackagesFilename)) {
Log.wtf(TAG, "Unable to backup package manager stopped packages, "
+ "current changes will be lost at reboot");
return;
}
} else {
mStoppedPackagesFilename.delete();
Slog.w(TAG, "Preserving older stopped packages backup");
}
}
try {
FileOutputStream fstr = new FileOutputStream(mStoppedPackagesFilename);
BufferedOutputStream str = new BufferedOutputStream(fstr);
//XmlSerializer serializer = XmlUtils.serializerInstance();
XmlSerializer serializer = new FastXmlSerializer();
serializer.setOutput(str, "utf-8");
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "stopped-packages");
for (PackageSetting pkg : mPackages.values()) {
if (pkg.stopped) {
serializer.startTag(null, "pkg");
serializer.attribute(null, "name", pkg.name);
if (pkg.notLaunched) {
serializer.attribute(null, "nl", "1");
}
serializer.endTag(null, "pkg");
}
}
serializer.endTag(null, "stopped-packages");
serializer.endDocument();
str.flush();
FileUtils.sync(fstr);
str.close();
// New settings successfully written, old ones are no longer
// needed.
mBackupStoppedPackagesFilename.delete();
FileUtils.setPermissions(mStoppedPackagesFilename.toString(),
FileUtils.S_IRUSR|FileUtils.S_IWUSR
|FileUtils.S_IRGRP|FileUtils.S_IWGRP
|FileUtils.S_IROTH,
-1, -1);
// Done, all is good!
return;
} catch(java.io.IOException e) {
Log.wtf(TAG, "Unable to write package manager stopped packages, "
+ " current changes will be lost at reboot", e);
}
// Clean up partially written files
if (mStoppedPackagesFilename.exists()) {
if (!mStoppedPackagesFilename.delete()) {
Log.i(TAG, "Failed to clean up mangled file: " + mStoppedPackagesFilename);
}
}
}
// Note: assumed "stopped" field is already cleared in all packages.
void readStoppedLP() {
FileInputStream str = null;
if (mBackupStoppedPackagesFilename.exists()) {
try {
str = new FileInputStream(mBackupStoppedPackagesFilename);
mReadMessages.append("Reading from backup stopped packages file\n");
reportSettingsProblem(Log.INFO, "Need to read from backup stopped packages file");
if (mSettingsFilename.exists()) {
// If both the backup and normal file exist, we
// ignore the normal one since it might have been
// corrupted.
Slog.w(TAG, "Cleaning up stopped packages file "
+ mStoppedPackagesFilename);
mStoppedPackagesFilename.delete();
}
} catch (java.io.IOException e) {
// We'll try for the normal settings file.
}
}
try {
if (str == null) {
if (!mStoppedPackagesFilename.exists()) {
mReadMessages.append("No stopped packages file found\n");
reportSettingsProblem(Log.INFO, "No stopped packages file file; "
+ "assuming all started");
// At first boot, make sure no packages are stopped.
// We usually want to have third party apps initialize
// in the stopped state, but not at first boot.
serializer.endDocument();
for (PackageSetting pkg : mPackages.values()) {
pkg.stopped = false;
pkg.notLaunched = false;
}
return;
}
str = new FileInputStream(mStoppedPackagesFilename);
}
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null);
int type;
while ((type=parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
mReadMessages.append("No start tag found in stopped packages file\n");
reportSettingsProblem(Log.WARN,
"No start tag found in package manager stopped packages");
return;
}
int outerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("pkg")) {
String name = parser.getAttributeValue(null, "name");
PackageSetting ps = mPackages.get(name);
if (ps != null) {
ps.stopped = true;
if ("1".equals(parser.getAttributeValue(null, "nl"))) {
ps.notLaunched = true;
}
} else {
Slog.w(TAG, "No package known for stopped package: " + name);
}
XmlUtils.skipCurrentTag(parser);
} else {
Slog.w(TAG, "Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
str.close();
} catch(XmlPullParserException e) {
mReadMessages.append("Error reading: " + e.toString());
reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e);
Log.wtf(TAG, "Error reading package manager stopped packages", e);
} catch(java.io.IOException e) {
mReadMessages.append("Error reading: " + e.toString());
reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
Log.wtf(TAG, "Error reading package manager stopped packages", e);
}
}
void writeLP() {
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
// Keep the old settings around until we know the new ones have
// been successfully written.
if (mSettingsFilename.exists()) {
// Presence of backup settings file indicates that we failed
// to persist settings earlier. So preserve the older
// backup for future reference since the current settings
// might have been corrupted.
if (!mBackupSettingsFilename.exists()) {
if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
Log.wtf(TAG, "Unable to backup package manager settings, "
+ " current changes will be lost at reboot");
return;
}
} else {
mSettingsFilename.delete();
Slog.w(TAG, "Preserving older settings backup");
}
}
mPastSignatures.clear();
try {
FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
BufferedOutputStream str = new BufferedOutputStream(fstr);
//XmlSerializer serializer = XmlUtils.serializerInstance();
XmlSerializer serializer = new FastXmlSerializer();
serializer.setOutput(str, "utf-8");
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "packages");
serializer.startTag(null, "last-platform-version");
serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
serializer.endTag(null, "last-platform-version");
serializer.startTag(null, "permission-trees");
for (BasePermission bp : mPermissionTrees.values()) {
writePermission(serializer, bp);
}
serializer.endTag(null, "permission-trees");
serializer.startTag(null, "permissions");
for (BasePermission bp : mPermissions.values()) {
writePermission(serializer, bp);
}
serializer.endTag(null, "permissions");
for (PackageSetting pkg : mPackages.values()) {
writePackage(serializer, pkg);
}
for (PackageSetting pkg : mDisabledSysPackages.values()) {
writeDisabledSysPackage(serializer, pkg);
}
serializer.startTag(null, "preferred-activities");
for (PreferredActivity pa : mPreferredActivities.filterSet()) {
serializer.startTag(null, "item");
pa.writeToXml(serializer);
serializer.endTag(null, "item");
}
serializer.endTag(null, "preferred-activities");
for (SharedUserSetting usr : mSharedUsers.values()) {
serializer.startTag(null, "shared-user");
serializer.attribute(null, "name", usr.name);
serializer.attribute(null, "userId",
Integer.toString(usr.userId));
usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
serializer.startTag(null, "perms");
for (String name : usr.grantedPermissions) {
serializer.startTag(null, "item");
serializer.attribute(null, "name", name);
serializer.endTag(null, "item");
}
serializer.endTag(null, "perms");
serializer.endTag(null, "shared-user");
}
if (mPackagesToBeCleaned.size() > 0) {
for (int i=0; i 0) {
for (HashMap.Entry e : mRenamedPackages.entrySet()) {
serializer.startTag(null, "renamed-package");
serializer.attribute(null, "new", e.getKey());
serializer.attribute(null, "old", e.getValue());
serializer.endTag(null, "renamed-package");
}
}
serializer.endTag(null, "packages");
str.flush();
FileUtils.sync(fstr);
str.close();
// New settings successfully written, old ones are no longer
// needed.
mBackupSettingsFilename.delete();
FileUtils.setPermissions(mSettingsFilename.toString(),
FileUtils.S_IRUSR|FileUtils.S_IWUSR
|FileUtils.S_IRGRP|FileUtils.S_IWGRP
|FileUtils.S_IROTH,
-1, -1);
// Write package list file now, use a JournaledFile.
//
File tempFile = new File(mPackageListFilename.toString() + ".tmp");
JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
fstr = new FileOutputStream(journal.chooseForWrite());
str = new BufferedOutputStream(fstr);
try {
StringBuilder sb = new StringBuilder();
for (PackageSetting pkg : mPackages.values()) {
ApplicationInfo ai = pkg.pkg.applicationInfo;
String dataPath = ai.dataDir;
boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
// Avoid any application that has a space in its path
// or that is handled by the system.
if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
continue;
// we store on each line the following information for now:
//
// pkgName - package name
// userId - application-specific user id
// debugFlag - 0 or 1 if the package is debuggable.
// dataPath - path to package's data path
//
// NOTE: We prefer not to expose all ApplicationInfo flags for now.
//
// DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
// FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
// system/core/run-as/run-as.c
//
sb.setLength(0);
sb.append(ai.packageName);
sb.append(" ");
sb.append((int)ai.uid);
sb.append(isDebug ? " 1 " : " 0 ");
sb.append(dataPath);
sb.append("\n");
str.write(sb.toString().getBytes());
}
str.flush();
FileUtils.sync(fstr);
str.close();
journal.commit();
}
catch (Exception e) {
journal.rollback();
}
FileUtils.setPermissions(mPackageListFilename.toString(),
FileUtils.S_IRUSR|FileUtils.S_IWUSR
|FileUtils.S_IRGRP|FileUtils.S_IWGRP
|FileUtils.S_IROTH,
-1, -1);
writeStoppedLP();
return;
} catch(XmlPullParserException e) {
Log.wtf(TAG, "Unable to write package manager settings, "
+ "current changes will be lost at reboot", e);
} catch(java.io.IOException e) {
Log.wtf(TAG, "Unable to write package manager settings, "
+ "current changes will be lost at reboot", e);
}
// Clean up partially written files
if (mSettingsFilename.exists()) {
if (!mSettingsFilename.delete()) {
Log.wtf(TAG, "Failed to clean up mangled file: " + mSettingsFilename);
}
//Debug.stopMethodTracing();
}
void writeDisabledSysPackage(XmlSerializer serializer, final PackageSetting pkg)
throws java.io.IOException {
serializer.startTag(null, "updated-package");
serializer.attribute(null, "name", pkg.name);
if (pkg.realName != null) {
serializer.attribute(null, "realName", pkg.realName);
}
serializer.attribute(null, "codePath", pkg.codePathString);
serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
if (!pkg.resourcePathString.equals(pkg.codePathString)) {
serializer.attribute(null, "resourcePath", pkg.resourcePathString);
}
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
if (pkg.sharedUser == null) {
serializer.attribute(null, "userId",
Integer.toString(pkg.userId));
} else {
serializer.attribute(null, "sharedUserId",
Integer.toString(pkg.userId));
}
serializer.startTag(null, "perms");
if (pkg.sharedUser == null) {
// If this is a shared user, the permissions will
// be written there. We still need to write an
// empty permissions list so permissionsFixed will
// be set.
for (final String name : pkg.grantedPermissions) {
BasePermission bp = mPermissions.get(name);
if (bp != null) {
// We only need to write signature or system permissions but this wont
// match the semantics of grantedPermissions. So write all permissions.
serializer.startTag(null, "item");
serializer.attribute(null, "name", name);
serializer.endTag(null, "item");
}
}
}
serializer.endTag(null, "perms");
serializer.endTag(null, "updated-package");
}
void writePackage(XmlSerializer serializer, final PackageSetting pkg)
throws java.io.IOException {
serializer.startTag(null, "package");
serializer.attribute(null, "name", pkg.name);
if (pkg.realName != null) {
serializer.attribute(null, "realName", pkg.realName);
}
serializer.attribute(null, "codePath", pkg.codePathString);
if (!pkg.resourcePathString.equals(pkg.codePathString)) {
serializer.attribute(null, "resourcePath", pkg.resourcePathString);
}
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
serializer.attribute(null, "flags",
Integer.toString(pkg.pkgFlags));
serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
if (pkg.sharedUser == null) {
serializer.attribute(null, "userId",
Integer.toString(pkg.userId));
} else {
serializer.attribute(null, "sharedUserId",
Integer.toString(pkg.userId));
}
if (pkg.uidError) {
serializer.attribute(null, "uidError", "true");
}
if (pkg.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
serializer.attribute(null, "enabled",
pkg.enabled == COMPONENT_ENABLED_STATE_ENABLED
? "true" : "false");
}
if(pkg.installStatus == PKG_INSTALL_INCOMPLETE) {
serializer.attribute(null, "installStatus", "false");
}
if (pkg.installerPackageName != null) {
serializer.attribute(null, "installer", pkg.installerPackageName);
}
pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
if ((pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
serializer.startTag(null, "perms");
if (pkg.sharedUser == null) {
// If this is a shared user, the permissions will
// be written there. We still need to write an
// empty permissions list so permissionsFixed will
// be set.
for (final String name : pkg.grantedPermissions) {
serializer.startTag(null, "item");
serializer.attribute(null, "name", name);
serializer.endTag(null, "item");
}
}
serializer.endTag(null, "perms");
}
if (pkg.disabledComponents.size() > 0) {
serializer.startTag(null, "disabled-components");
for (final String name : pkg.disabledComponents) {
serializer.startTag(null, "item");
serializer.attribute(null, "name", name);
serializer.endTag(null, "item");
}
serializer.endTag(null, "disabled-components");
}
if (pkg.enabledComponents.size() > 0) {
serializer.startTag(null, "enabled-components");
for (final String name : pkg.enabledComponents) {
serializer.startTag(null, "item");
serializer.attribute(null, "name", name);
serializer.endTag(null, "item");
}
serializer.endTag(null, "enabled-components");
}
serializer.endTag(null, "package");
}
void writePermission(XmlSerializer serializer, BasePermission bp)
throws XmlPullParserException, java.io.IOException {
if (bp.type != BasePermission.TYPE_BUILTIN
&& bp.sourcePackage != null) {
serializer.startTag(null, "item");
serializer.attribute(null, "name", bp.name);
serializer.attribute(null, "package", bp.sourcePackage);
if (bp.protectionLevel !=
PermissionInfo.PROTECTION_NORMAL) {
serializer.attribute(null, "protection",
Integer.toString(bp.protectionLevel));
}
if (DEBUG_SETTINGS) Log.v(TAG,
"Writing perm: name=" + bp.name + " type=" + bp.type);
if (bp.type == BasePermission.TYPE_DYNAMIC) {
PermissionInfo pi = bp.perm != null ? bp.perm.info
: bp.pendingInfo;
if (pi != null) {
serializer.attribute(null, "type", "dynamic");
if (pi.icon != 0) {
serializer.attribute(null, "icon",
Integer.toString(pi.icon));
}
if (pi.nonLocalizedLabel != null) {
serializer.attribute(null, "label",
pi.nonLocalizedLabel.toString());
}
}
}
serializer.endTag(null, "item");
}
}
String getReadMessagesLP() {
return mReadMessages.toString();
}
ArrayList getListOfIncompleteInstallPackages() {
HashSet kList = new HashSet(mPackages.keySet());
Iterator its = kList.iterator();
ArrayList ret = new ArrayList();
while(its.hasNext()) {
String key = its.next();
PackageSetting ps = mPackages.get(key);
if(ps.getInstallStatus() == PKG_INSTALL_INCOMPLETE) {
ret.add(ps);
}
}
return ret;
}
boolean readLP() {
FileInputStream str = null;
if (mBackupSettingsFilename.exists()) {
try {
str = new FileInputStream(mBackupSettingsFilename);
mReadMessages.append("Reading from backup settings file\n");
reportSettingsProblem(Log.INFO, "Need to read from backup settings file");
if (mSettingsFilename.exists()) {
// If both the backup and settings file exist, we
// ignore the settings since it might have been
// corrupted.
Slog.w(TAG, "Cleaning up settings file " + mSettingsFilename);
mSettingsFilename.delete();
}
} catch (java.io.IOException e) {
// We'll try for the normal settings file.
}
}
mPastSignatures.clear();
try {
if (str == null) {
if (!mSettingsFilename.exists()) {
mReadMessages.append("No settings file found\n");
reportSettingsProblem(Log.INFO, "No settings file; creating initial state");
return false;
}
str = new FileInputStream(mSettingsFilename);
}
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null);
int type;
while ((type=parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
mReadMessages.append("No start tag found in settings file\n");
reportSettingsProblem(Log.WARN, "No start tag found in package manager settings");
Log.wtf(TAG, "No start tag found in package manager settings");
return false;
}
int outerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("package")) {
readPackageLP(parser);
} else if (tagName.equals("permissions")) {
readPermissionsLP(mPermissions, parser);
} else if (tagName.equals("permission-trees")) {
readPermissionsLP(mPermissionTrees, parser);
} else if (tagName.equals("shared-user")) {
readSharedUserLP(parser);
} else if (tagName.equals("preferred-packages")) {
// no longer used.
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLP(parser);
} else if(tagName.equals("updated-package")) {
readDisabledSysPackageLP(parser);
} else if (tagName.equals("cleaning-package")) {
String name = parser.getAttributeValue(null, "name");
if (name != null) {
mPackagesToBeCleaned.add(name);
}
} else if (tagName.equals("renamed-package")) {
String nname = parser.getAttributeValue(null, "new");
String oname = parser.getAttributeValue(null, "old");
if (nname != null && oname != null) {
mRenamedPackages.put(nname, oname);
}
} else if (tagName.equals("last-platform-version")) {
mInternalSdkPlatform = mExternalSdkPlatform = 0;
try {
String internal = parser.getAttributeValue(null, "internal");
if (internal != null) {
mInternalSdkPlatform = Integer.parseInt(internal);
}
String external = parser.getAttributeValue(null, "external");
if (external != null) {
mExternalSdkPlatform = Integer.parseInt(external);
}
} catch (NumberFormatException e) {
}
} else {
Slog.w(TAG, "Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
str.close();
} catch(XmlPullParserException e) {
mReadMessages.append("Error reading: " + e.toString());
reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
Log.wtf(TAG, "Error reading package manager settings", e);
} catch(java.io.IOException e) {
mReadMessages.append("Error reading: " + e.toString());
reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
Log.wtf(TAG, "Error reading package manager settings", e);
}
int N = mPendingPackages.size();
for (int i=0; i disabledIt = mDisabledSysPackages.values().iterator();
while (disabledIt.hasNext()) {
final PackageSetting disabledPs = disabledIt.next();
final Object id = getUserIdLP(disabledPs.userId);
if (id != null && id instanceof SharedUserSetting) {
disabledPs.sharedUser = (SharedUserSetting) id;
}
}
readStoppedLP();
mReadMessages.append("Read completed successfully: "
+ mPackages.size() + " packages, "
+ mSharedUsers.size() + " shared uids\n");
return true;
}
private int readInt(XmlPullParser parser, String ns, String name,
int defValue) {
String v = parser.getAttributeValue(ns, name);
try {
if (v == null) {
return defValue;
}
return Integer.parseInt(v);
} catch (NumberFormatException e) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: attribute " +
name + " has bad integer value " + v + " at "
+ parser.getPositionDescription());
}
return defValue;
}
private void readPermissionsLP(HashMap out,
XmlPullParser parser)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("item")) {
String name = parser.getAttributeValue(null, "name");
String sourcePackage = parser.getAttributeValue(null, "package");
String ptype = parser.getAttributeValue(null, "type");
if (name != null && sourcePackage != null) {
boolean dynamic = "dynamic".equals(ptype);
BasePermission bp = new BasePermission(name, sourcePackage,
dynamic
? BasePermission.TYPE_DYNAMIC
}
: BasePermission.TYPE_NORMAL);
bp.protectionLevel = readInt(parser, null, "protection",
PermissionInfo.PROTECTION_NORMAL);
if (dynamic) {
PermissionInfo pi = new PermissionInfo();
pi.packageName = sourcePackage.intern();
pi.name = name.intern();
pi.icon = readInt(parser, null, "icon", 0);
pi.nonLocalizedLabel = parser.getAttributeValue(
null, "label");
pi.protectionLevel = bp.protectionLevel;
bp.pendingInfo = pi;
}
out.put(bp.name, bp);
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: permissions has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element reading permissions: "
+ parser.getName() + " at "
+ parser.getPositionDescription());
}
XmlUtils.skipCurrentTag(parser);
}
}
private void readDisabledSysPackageLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = parser.getAttributeValue(null, "name");
String nativeLibraryPathStr = null;
String realName = parser.getAttributeValue(null, "realName");
String codePathStr = parser.getAttributeValue(null, "codePath");
String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
String version = parser.getAttributeValue(null, "version");
int versionCode = 0;
if (version != null) {
try {
versionCode = Integer.parseInt(version);
} catch (NumberFormatException e) {
}
}
int pkgFlags = 0;
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
String timeStampStr = parser.getAttributeValue(null, "ft");
if (timeStampStr != null) {
try {
long timeStamp = Long.parseLong(timeStampStr, 16);
ps.setTimeStamp(timeStamp);
} catch (NumberFormatException e) {
}
} else {
timeStampStr = parser.getAttributeValue(null, "ts");
if (timeStampStr != null) {
try {
long timeStamp = Long.parseLong(timeStampStr);
ps.setTimeStamp(timeStamp);
} catch (NumberFormatException e) {
}
}
}
timeStampStr = parser.getAttributeValue(null, "it");
if (timeStampStr != null) {
try {
ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
} catch (NumberFormatException e) {
}
}
timeStampStr = parser.getAttributeValue(null, "ut");
if (timeStampStr != null) {
try {
ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
} catch (NumberFormatException e) {
}
}
String idStr = parser.getAttributeValue(null, "userId");
ps.userId = idStr != null ? Integer.parseInt(idStr) : 0;
String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
ps.userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
}
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("perms")) {
readGrantedPermissionsLP(parser,
ps.grantedPermissions);
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
mDisabledSysPackages.put(name, ps);
}
private void readPackageLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = null;
String realName = null;
String idStr = null;
String sharedIdStr = null;
String codePathStr = null;
String resourcePathStr = null;
}
String systemStr = null;
String installerPackageName = null;
String uidError = null;
int pkgFlags = 0;
long timeStamp = 0;
long firstInstallTime = 0;
long lastUpdateTime = 0;
PackageSettingBase packageSetting = null;
String version = null;
int versionCode = 0;
try {
name = parser.getAttributeValue(null, "name");
realName = parser.getAttributeValue(null, "realName");
idStr = parser.getAttributeValue(null, "userId");
uidError = parser.getAttributeValue(null, "uidError");
sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
codePathStr = parser.getAttributeValue(null, "codePath");
resourcePathStr = parser.getAttributeValue(null, "resourcePath");
nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
version = parser.getAttributeValue(null, "version");
if (version != null) {
try {
versionCode = Integer.parseInt(version);
} catch (NumberFormatException e) {
}
}
installerPackageName = parser.getAttributeValue(null, "installer");
systemStr = parser.getAttributeValue(null, "flags");
if (systemStr != null) {
try {
pkgFlags = Integer.parseInt(systemStr);
} catch (NumberFormatException e) {
}
} else {
// For backward compatibility
systemStr = parser.getAttributeValue(null, "system");
if (systemStr != null) {
pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM : 0;
} else {
// Old settings that don't specify system... just treat
// them as system, good enough.
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
}
}
String timeStampStr = parser.getAttributeValue(null, "ft");
if (timeStampStr != null) {
try {
timeStamp = Long.parseLong(timeStampStr, 16);
} catch (NumberFormatException e) {
} else {
timeStampStr = parser.getAttributeValue(null, "ts");
if (timeStampStr != null) {
try {
timeStamp = Long.parseLong(timeStampStr);
} catch (NumberFormatException e) {
}
}
}
timeStampStr = parser.getAttributeValue(null, "it");
if (timeStampStr != null) {
try {
firstInstallTime = Long.parseLong(timeStampStr, 16);
} catch (NumberFormatException e) {
}
}
timeStampStr = parser.getAttributeValue(null, "ut");
if (timeStampStr != null) {
try {
lastUpdateTime = Long.parseLong(timeStampStr, 16);
} catch (NumberFormatException e) {
}
}
if (DEBUG_SETTINGS) Log.v(TAG, "Reading package: " + name
+ " userId=" + idStr + " sharedUserId=" + sharedIdStr);
int userId = idStr != null ? Integer.parseInt(idStr) : 0;
if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
if (realName != null) {
realName = realName.intern();
}
if (name == null) {
reportSettingsProblem(Log.WARN,
}
"Error in package manager settings: has no name at "
+ parser.getPositionDescription());
} else if (codePathStr == null) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has no codePath at "
+ parser.getPositionDescription());
} else if (userId > 0) {
packageSetting = addPackageLP(name.intern(), realName, new File(codePathStr),
new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
pkgFlags);
if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
+ ": userId=" + userId + " pkg=" + packageSetting);
if (packageSetting == null) {
reportSettingsProblem(Log.ERROR,
"Failure adding uid " + userId
+ " while parsing settings at "
+ parser.getPositionDescription());
} else {
packageSetting.setTimeStamp(timeStamp);
packageSetting.firstInstallTime = firstInstallTime;
packageSetting.lastUpdateTime = lastUpdateTime;
}
} else if (sharedIdStr != null) {
userId = sharedIdStr != null
? Integer.parseInt(sharedIdStr) : 0;
if (userId > 0) {
packageSetting = new PendingPackage(name.intern(), realName,
new File(codePathStr), new File(resourcePathStr),
nativeLibraryPathStr, userId, versionCode, pkgFlags);
packageSetting.setTimeStamp(timeStamp);
packageSetting.firstInstallTime = firstInstallTime;
packageSetting.lastUpdateTime = lastUpdateTime;
mPendingPackages.add((PendingPackage) packageSetting);
if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
+ ": sharedUserId=" + userId + " pkg="
+ packageSetting);
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad sharedId " + sharedIdStr
+ " at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
}
} catch (NumberFormatException e) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
}
if (packageSetting != null) {
packageSetting.uidError = "true".equals(uidError);
packageSetting.installerPackageName = installerPackageName;
packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
final String enabledStr = parser.getAttributeValue(null, "enabled");
if (enabledStr != null) {
if (enabledStr.equalsIgnoreCase("true")) {
packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED;
} else if (enabledStr.equalsIgnoreCase("false")) {
packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED;
} else if (enabledStr.equalsIgnoreCase("default")) {
packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad enabled value: " + idStr
+ " at " + parser.getPositionDescription());
}
} else {
packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
final String installStatusStr = parser.getAttributeValue(null, "installStatus");
if (installStatusStr != null) {
if (installStatusStr.equalsIgnoreCase("false")) {
packageSetting.installStatus = PKG_INSTALL_INCOMPLETE;
} else {
packageSetting.installStatus = PKG_INSTALL_COMPLETE;
}
}
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("disabled-components")) {
readDisabledComponentsLP(packageSetting, parser);
} else if (tagName.equals("enabled-components")) {
readEnabledComponentsLP(packageSetting, parser);
} else if (tagName.equals("sigs")) {
packageSetting.signatures.readXml(parser, mPastSignatures);
} else if (tagName.equals("perms")) {
readGrantedPermissionsLP(parser,
packageSetting.grantedPermissions);
packageSetting.permissionsFixed = true;
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
} else {
XmlUtils.skipCurrentTag(parser);
}
}
private void readDisabledComponentsLP(PackageSettingBase packageSetting,
XmlPullParser parser)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("item")) {
String name = parser.getAttributeValue(null, "name");
if (name != null) {
packageSetting.disabledComponents.add(name.intern());
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
}
private void readEnabledComponentsLP(PackageSettingBase packageSetting,
XmlPullParser parser)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("item")) {
String name = parser.getAttributeValue(null, "name");
if (name != null) {
packageSetting.enabledComponents.add(name.intern());
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
}
private void readSharedUserLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = null;
String idStr = null;
int pkgFlags = 0;
SharedUserSetting su = null;
try {
name = parser.getAttributeValue(null, "name");
idStr = parser.getAttributeValue(null, "userId");
int userId = idStr != null ? Integer.parseInt(idStr) : 0;
if ("true".equals(parser.getAttributeValue(null, "system"))) {
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
}
if (name == null) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has no name at "
+ parser.getPositionDescription());
} else if (userId == 0) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: shared-user "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
} else {
if ((su=addSharedUserLP(name.intern(), userId, pkgFlags)) == null) {
reportSettingsProblem(Log.ERROR,
"Occurred while parsing settings at "
+ parser.getPositionDescription());
}
}
} catch (NumberFormatException e) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: package "
+ name + " has bad userId " + idStr + " at "
+ parser.getPositionDescription());
};
if (su != null) {
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("sigs")) {
su.signatures.readXml(parser, mPastSignatures);
} else if (tagName.equals("perms")) {
readGrantedPermissionsLP(parser, su.grantedPermissions);
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
} else {
XmlUtils.skipCurrentTag(parser);
}
private void readGrantedPermissionsLP(XmlPullParser parser,
HashSet outPerms) throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("item")) {
String name = parser.getAttributeValue(null, "name");
if (name != null) {
outPerms.add(name.intern());
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: has"
+ " no name at " + parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
}
private void readPreferredActivitiesLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("item")) {
PreferredActivity pa = new PreferredActivity(parser);
if (pa.mPref.getParseError() == null) {
mPreferredActivities.addFilter(pa);
} else {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: "
+ pa.mPref.getParseError() + " at "
+ parser.getPositionDescription());
}
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
}
// Returns -1 if we could not find an available UserId to assign
private int newUserIdLP(Object obj) {
// Let's be stupidly inefficient for now...
final int N = mUserIds.size();
for (int i=0; i= MAX_APPLICATION_UIDS) {
return -1;
}
mUserIds.add(obj);
return FIRST_APPLICATION_UID + N;
}
public PackageSetting getDisabledSystemPkg(String name) {
synchronized(mPackages) {
PackageSetting ps = mDisabledSysPackages.get(name);
return ps;
}
}
boolean isEnabledLP(ComponentInfo componentInfo, int flags) {
if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
return true;
}
final PackageSetting packageSettings = mPackages.get(componentInfo.packageName);
if (Config.LOGV) {
Log.v(TAG, "isEnabledLock - packageName = " + componentInfo.packageName
+ " componentName = " + componentInfo.name);
Log.v(TAG, "enabledComponents: "
+ Arrays.toString(packageSettings.enabledComponents.toArray()));
Log.v(TAG, "disabledComponents: "
+ Arrays.toString(packageSettings.disabledComponents.toArray()));
}
if (packageSettings == null) {
if (false) {
Log.w(TAG, "WAITING FOR DEBUGGER");
Debug.waitForDebugger();
Log.i(TAG, "We will crash!");
}
return false;
}
if (packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED
|| (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
&& packageSettings.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
return false;
}
if (packageSettings.enabledComponents.contains(componentInfo.name)) {
return true;
}
if (packageSettings.disabledComponents.contains(componentInfo.name)) {
return false;
}
return componentInfo.enabled;
}
}
// ------- apps on sdcard specific code -------
static final boolean DEBUG_SD_INSTALL = false;
private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
private static final String SD_ENCRYPTION_ALGORITHM = "AES";
static final int MAX_CONTAINERS = 250;
>>>>>>> 0e59729b104e48c7d935026f565c4b45f1f37d12:services/java/com/android/server/PackageManagerService.java
private boolean mMediaMounted = false;
private String getEncryptKey() {