summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageParser.java127
-rw-r--r--services/java/com/android/server/PackageManagerService.java404
2 files changed, 380 insertions, 151 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index d97b3dd..5823560 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -961,15 +961,15 @@ public class PackageParser {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestOriginalPackage);
- String name = sa.getNonResourceString(
+ String orig =sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestOriginalPackage_name);
+ if (!pkg.packageName.equals(orig)) {
+ pkg.mOriginalPackage = orig;
+ pkg.mRealPackage = pkg.packageName;
+ }
sa.recycle();
- if (name != null && (flags&PARSE_IS_SYSTEM) != 0) {
- pkg.mOriginalPackage = name;
- }
-
XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals("adopt-permissions")) {
@@ -981,7 +981,7 @@ public class PackageParser {
sa.recycle();
- if (name != null && (flags&PARSE_IS_SYSTEM) != 0) {
+ if (name != null) {
if (pkg.mAdoptPermissions == null) {
pkg.mAdoptPermissions = new ArrayList<String>();
}
@@ -2550,7 +2550,7 @@ public class PackageParser {
}
public final static class Package {
- public final String packageName;
+ public String packageName;
// For now we only support one application per package.
public final ApplicationInfo applicationInfo = new ApplicationInfo();
@@ -2572,6 +2572,7 @@ public class PackageParser {
public String[] usesLibraryFiles = null;
public String mOriginalPackage = null;
+ public String mRealPackage = null;
public ArrayList<String> mAdoptPermissions = null;
// We store the application meta-data independently to avoid multiple unwanted references
@@ -2628,6 +2629,32 @@ public class PackageParser {
applicationInfo.uid = -1;
}
+ public void setPackageName(String newName) {
+ packageName = newName;
+ applicationInfo.packageName = newName;
+ for (int i=permissions.size()-1; i>=0; i--) {
+ permissions.get(i).setPackageName(newName);
+ }
+ for (int i=permissionGroups.size()-1; i>=0; i--) {
+ permissionGroups.get(i).setPackageName(newName);
+ }
+ for (int i=activities.size()-1; i>=0; i--) {
+ activities.get(i).setPackageName(newName);
+ }
+ for (int i=receivers.size()-1; i>=0; i--) {
+ receivers.get(i).setPackageName(newName);
+ }
+ for (int i=providers.size()-1; i>=0; i--) {
+ providers.get(i).setPackageName(newName);
+ }
+ for (int i=services.size()-1; i>=0; i--) {
+ services.get(i).setPackageName(newName);
+ }
+ for (int i=instrumentation.size()-1; i>=0; i--) {
+ instrumentation.get(i).setPackageName(newName);
+ }
+ }
+
public String toString() {
return "Package{"
+ Integer.toHexString(System.identityHashCode(this))
@@ -2638,15 +2665,16 @@ public class PackageParser {
public static class Component<II extends IntentInfo> {
public final Package owner;
public final ArrayList<II> intents;
- public final ComponentName component;
- public final String componentShortName;
+ public final String className;
public Bundle metaData;
+ ComponentName componentName;
+ String componentShortName;
+
public Component(Package _owner) {
owner = _owner;
intents = null;
- component = null;
- componentShortName = null;
+ className = null;
}
public Component(final ParsePackageItemArgs args, final PackageItemInfo outInfo) {
@@ -2654,8 +2682,7 @@ public class PackageParser {
intents = new ArrayList<II>(0);
String name = args.sa.getNonResourceString(args.nameRes);
if (name == null) {
- component = null;
- componentShortName = null;
+ className = null;
args.outError[0] = args.tag + " does not specify android:name";
return;
}
@@ -2663,15 +2690,12 @@ public class PackageParser {
outInfo.name
= buildClassName(owner.applicationInfo.packageName, name, args.outError);
if (outInfo.name == null) {
- component = null;
- componentShortName = null;
+ className = null;
args.outError[0] = args.tag + " does not have valid android:name";
return;
}
- component = new ComponentName(owner.applicationInfo.packageName,
- outInfo.name);
- componentShortName = component.flattenToShortString();
+ className = outInfo.name;
int iconVal = args.sa.getResourceId(args.iconRes, 0);
if (iconVal != 0) {
@@ -2709,9 +2733,36 @@ public class PackageParser {
public Component(Component<II> clone) {
owner = clone.owner;
intents = clone.intents;
- component = clone.component;
+ className = clone.className;
+ componentName = clone.componentName;
componentShortName = clone.componentShortName;
- metaData = clone.metaData;
+ }
+
+ public ComponentName getComponentName() {
+ if (componentName != null) {
+ return componentName;
+ }
+ if (className != null) {
+ componentName = new ComponentName(owner.applicationInfo.packageName,
+ className);
+ }
+ return componentName;
+ }
+
+ public String getComponentShortName() {
+ if (componentShortName != null) {
+ return componentShortName;
+ }
+ ComponentName component = getComponentName();
+ if (component != null) {
+ componentShortName = component.flattenToShortString();
+ }
+ return componentShortName;
+ }
+
+ public void setPackageName(String packageName) {
+ componentName = null;
+ componentShortName = null;
}
}
@@ -2729,6 +2780,11 @@ public class PackageParser {
super(_owner);
info = _info;
}
+
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ info.packageName = packageName;
+ }
public String toString() {
return "Permission{"
@@ -2750,6 +2806,11 @@ public class PackageParser {
info = _info;
}
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ info.packageName = packageName;
+ }
+
public String toString() {
return "PermissionGroup{"
+ Integer.toHexString(System.identityHashCode(this))
@@ -2825,10 +2886,15 @@ public class PackageParser {
info.applicationInfo = args.owner.applicationInfo;
}
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ info.packageName = packageName;
+ }
+
public String toString() {
return "Activity{"
+ Integer.toHexString(System.identityHashCode(this))
- + " " + component.flattenToString() + "}";
+ + " " + getComponentShortName() + "}";
}
}
@@ -2854,10 +2920,15 @@ public class PackageParser {
info.applicationInfo = args.owner.applicationInfo;
}
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ info.packageName = packageName;
+ }
+
public String toString() {
return "Service{"
+ Integer.toHexString(System.identityHashCode(this))
- + " " + component.flattenToString() + "}";
+ + " " + getComponentShortName() + "}";
}
}
@@ -2890,6 +2961,11 @@ public class PackageParser {
this.syncable = existingProvider.syncable;
}
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ info.packageName = packageName;
+ }
+
public String toString() {
return "Provider{"
+ Integer.toHexString(System.identityHashCode(this))
@@ -2923,10 +2999,15 @@ public class PackageParser {
info = _info;
}
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ info.packageName = packageName;
+ }
+
public String toString() {
return "Instrumentation{"
+ Integer.toHexString(System.identityHashCode(this))
- + " " + component.flattenToString() + "}";
+ + " " + getComponentShortName() + "}";
}
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 1cda2ff..4a60445 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -704,7 +704,8 @@ class PackageManagerService extends IPackageManager.Stub {
while (psit.hasNext()) {
PackageSetting ps = psit.next();
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
- && !mPackages.containsKey(ps.name)) {
+ && !mPackages.containsKey(ps.name)
+ && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {
psit.remove();
String msg = "System package " + ps.name
+ " no longer exists; wiping its data";
@@ -2178,47 +2179,56 @@ class PackageManagerService extends IPackageManager.Stub {
* Returns null in case of errors and the error code is stored in mLastScanError
*/
private PackageParser.Package scanPackageLI(File scanFile,
- int parseFlags,
- int scanMode) {
+ int parseFlags, int scanMode) {
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
String scanPath = scanFile.getPath();
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser(scanPath);
pp.setSeparateProcesses(mSeparateProcesses);
final PackageParser.Package pkg = pp.parsePackage(scanFile,
- scanPath,
- mMetrics, parseFlags);
+ scanPath, mMetrics, parseFlags);
if (pkg == null) {
mLastScanError = pp.getParseError();
return null;
}
- PackageSetting ps;
+ PackageSetting ps = null;
PackageSetting updatedPkg;
synchronized (mPackages) {
- ps = mSettings.peekPackageLP(pkg.packageName);
- updatedPkg = mSettings.mDisabledSysPackages.get(pkg.packageName);
- }
- // Verify certificates first
- if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
- Log.i(TAG, "Failed verifying certificates for package:" + pkg.packageName);
- return null;
- }
- if (updatedPkg != null) {
- // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
- parseFlags |= PackageParser.PARSE_IS_SYSTEM;
- }
- if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
- // Check for updated system applications here
- if ((ps != null) && (!ps.codePath.equals(scanFile))) {
+ // Look to see if we already know about this package.
+ String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
+ if (oldName != null && oldName.equals(pkg.mOriginalPackage)) {
+ // This package has been renamed to its original name. Let's
+ // use that.
+ ps = mSettings.peekPackageLP(pkg.mOriginalPackage);
+ }
+ // If there was no original package, see one for the real package name.
+ if (ps == null) {
+ ps = mSettings.peekPackageLP(pkg.packageName);
+ }
+ // Check to see if this package could be hiding/updating a system
+ // package. Must look for it either under the original or real
+ // package name depending on our state.
+ updatedPkg = mSettings.mDisabledSysPackages.get(
+ ps != null ? ps.name : pkg.packageName);
+ }
+ // First check if this is a system package that may involve an update
+ if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
+ if (!ps.codePath.equals(scanFile)) {
+ // The path has changed from what was last scanned... check the
+ // version of the new path against what we have stored to determine
+ // what to do.
if (pkg.mVersionCode < ps.versionCode) {
// The system package has been updated and the code path does not match
- // Ignore entry. Just return
- Log.w(TAG, "Package:" + pkg.packageName +
- " has been updated. Ignoring the one from path:"+scanFile);
+ // Ignore entry. Skip it.
+ Log.i(TAG, "Package " + ps.name + " at " + scanFile
+ + "ignored: updated version " + ps.versionCode
+ + " better than this " + pkg.mVersionCode);
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} else {
- // Delete the older apk pointed to by ps
+ // The current app on the system partion is better than
+ // what we have updated to on the data partition; switch
+ // back to the system partition version.
// At this point, its safely assumed that package installation for
// apps in system partition will go through. If not there won't be a working
// version of the app
@@ -2226,12 +2236,25 @@ class PackageManagerService extends IPackageManager.Stub {
// Just remove the loaded entries from package lists.
mPackages.remove(ps.name);
}
+ Log.w(TAG, "Package " + ps.name + " at " + scanFile
+ + "reverting from " + ps.codePathString
+ + ": new version " + pkg.mVersionCode
+ + " better than installed " + ps.versionCode);
InstallArgs args = new FileInstallArgs(ps.codePathString, ps.resourcePathString);
args.cleanUpResourcesLI();
mSettings.enableSystemPackageLP(ps.name);
}
}
}
+ if (updatedPkg != null) {
+ // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
+ parseFlags |= PackageParser.PARSE_IS_SYSTEM;
+ }
+ // Verify certificates against what was last scanned
+ if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
+ Log.i(TAG, "Failed verifying certificates for package:" + pkg.packageName);
+ return null;
+ }
// The apk is forward locked (not public) if its code and resources
// are kept in different files.
// TODO grab this value from PackageSettings
@@ -2369,8 +2392,8 @@ class PackageManagerService extends IPackageManager.Stub {
return true;
}
- private PackageParser.Package scanPackageLI(
- PackageParser.Package pkg, int parseFlags, int scanMode) {
+ private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
+ int parseFlags, int scanMode) {
File scanFile = new File(pkg.mScanPath);
if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
pkg.applicationInfo.publicSourceDir == null) {
@@ -2385,12 +2408,11 @@ class PackageManagerService extends IPackageManager.Stub {
return null;
}
- final String pkgName = pkg.applicationInfo.packageName;
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
}
- if (pkgName.equals("android")) {
+ if (pkg.packageName.equals("android")) {
synchronized (mPackages) {
if (mAndroidApplication != null) {
Log.w(TAG, "*************************************************");
@@ -2425,10 +2447,11 @@ class PackageManagerService extends IPackageManager.Stub {
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
- TAG, "Scanning package " + pkgName);
- if (mPackages.containsKey(pkgName) || mSharedLibraries.containsKey(pkgName)) {
+ TAG, "Scanning package " + pkg.packageName);
+ if (mPackages.containsKey(pkg.packageName)
+ || mSharedLibraries.containsKey(pkg.packageName)) {
Log.w(TAG, "*************************************************");
- Log.w(TAG, "Application package " + pkgName
+ Log.w(TAG, "Application package " + pkg.packageName
+ " already installed. Skipping duplicate.");
Log.w(TAG, "*************************************************");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
@@ -2444,6 +2467,13 @@ class PackageManagerService extends IPackageManager.Stub {
boolean removeExisting = false;
+ if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
+ // Only system apps can use these features.
+ pkg.mOriginalPackage = null;
+ pkg.mRealPackage = null;
+ pkg.mAdoptPermissions = null;
+ }
+
synchronized (mPackages) {
// Check all shared libraries and map to their actual file path.
if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
@@ -2509,7 +2539,7 @@ class PackageManagerService extends IPackageManager.Stub {
suid = mSettings.getSharedUserLP(pkg.mSharedUserId,
pkg.applicationInfo.flags, true);
if (suid == null) {
- Log.w(TAG, "Creating application package " + pkgName
+ Log.w(TAG, "Creating application package " + pkg.packageName
+ " for shared user failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
@@ -2520,16 +2550,44 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
+ if (false) {
+ if (pkg.mOriginalPackage != null) {
+ Log.w(TAG, "WAITING FOR DEBUGGER");
+ Debug.waitForDebugger();
+ Log.i(TAG, "Package " + pkg.packageName + " from original package"
+ + pkg.mOriginalPackage);
+ }
+ }
+
// Check if we are renaming from an original package name.
PackageSetting origPackage = null;
+ String realName = null;
if (pkg.mOriginalPackage != null) {
- // We will only retrieve the setting for it if it already
- // exists; otherwise we need to make a new one later.
- origPackage = mSettings.peekPackageLP(pkg.mOriginalPackage);
- if (origPackage != null) {
+ // This package may need to be renamed to a previously
+ // installed name. Let's check on that...
+ String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
+ if (pkg.mOriginalPackage.equals(renamed)) {
+ // This package had originally been installed as the
+ // original name, and we have already taken care of
+ // transitioning to the new one. Just update the new
+ // one to continue using the old name.
+ realName = pkg.mRealPackage;
+ if (!pkg.packageName.equals(renamed)) {
+ // Callers into this function may have already taken
+ // care of renaming the package; only do it here if
+ // it is not already done.
+ pkg.setPackageName(renamed);
+ }
+
+ } else if ((origPackage
+ = mSettings.peekPackageLP(pkg.mOriginalPackage)) != null) {
+ // We do have the package already installed under its
+ // original name... should we use it?
if (!verifyPackageUpdate(origPackage, pkg)) {
+ // New package is not compatible with original.
origPackage = null;
} else if (origPackage.sharedUser != null) {
+ // Make sure uid is compatible between packages.
if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
Log.w(TAG, "Unable to migrate data from " + origPackage.name
+ " to " + pkg.packageName + ": old uid "
@@ -2538,8 +2596,8 @@ class PackageManagerService extends IPackageManager.Stub {
origPackage = null;
}
} else {
- if (DEBUG_UPGRADE) Log.v(TAG, "Migrating data from "
- + origPackage.name + " to " + pkg.packageName);
+ if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
+ + pkg.packageName + " to old name " + origPackage.name);
}
}
}
@@ -2551,13 +2609,38 @@ class PackageManagerService extends IPackageManager.Stub {
// Just create the setting, don't add it yet. For already existing packages
// the PkgSetting exists already and doesn't have to be created.
- pkgSetting = mSettings.getPackageLP(pkg, origPackage, suid, destCodeFile,
+ pkgSetting = mSettings.getPackageLP(pkg, origPackage, realName, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.flags, true, false);
if (pkgSetting == null) {
- Log.w(TAG, "Creating application package " + pkgName + " failed");
+ Log.w(TAG, "Creating application package " + pkg.packageName + " failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
+
+ if (pkgSetting.origPackage != null) {
+ // If we are first transitioning from an original package,
+ // fix up the new package's name now. We need to do this after
+ // looking up the package under its new name, so getPackageLP
+ // can take care of fiddling things correctly.
+ pkg.setPackageName(origPackage.name);
+
+ // File a report about this.
+ String msg = "New package " + pkgSetting.realName
+ + " renamed to replace old package " + pkgSetting.name;
+ reportSettingsProblem(Log.WARN, msg);
+
+ // Make a note of it.
+ mTransferedPackages.add(origPackage.name);
+
+ // No longer need to retain this.
+ pkgSetting.origPackage = null;
+ }
+
+ if (realName != null) {
+ // Make a note of it.
+ mTransferedPackages.add(pkg.packageName);
+ }
+
if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
@@ -2565,22 +2648,6 @@ class PackageManagerService extends IPackageManager.Stub {
pkg.applicationInfo.uid = pkgSetting.userId;
pkg.mExtras = pkgSetting;
- if (pkg.mAdoptPermissions != null) {
- // This package wants to adopt ownership of permissions from
- // another package.
- for (int i=pkg.mAdoptPermissions.size()-1; i>=0; i--) {
- String origName = pkg.mAdoptPermissions.get(i);
- PackageSetting orig = mSettings.peekPackageLP(origName);
- if (orig != null) {
- if (verifyPackageUpdate(orig, pkg)) {
- if (DEBUG_UPGRADE) Log.v(TAG, "Adopting permissions from "
- + origName + " to " + pkg.packageName);
- mSettings.transferPermissions(origName, pkg.packageName);
- }
- }
- }
- }
-
if (!verifySignaturesLP(pkgSetting, pkg, parseFlags,
(scanMode&SCAN_UPDATE_SIGNATURE) != 0)) {
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) == 0) {
@@ -2621,8 +2688,8 @@ class PackageManagerService extends IPackageManager.Stub {
Log.w(TAG, "Can't install because provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
") is already used by "
- + ((other != null && other.component != null)
- ? other.component.getPackageName() : "?"));
+ + ((other != null && other.getComponentName() != null)
+ ? other.getComponentName().getPackageName() : "?"));
mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
return null;
}
@@ -2631,6 +2698,8 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
+ final String pkgName = pkg.packageName;
+
if (removeExisting) {
boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
if (mInstaller != null) {
@@ -2648,6 +2717,22 @@ class PackageManagerService extends IPackageManager.Stub {
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
}
+ if (pkg.mAdoptPermissions != null) {
+ // This package wants to adopt ownership of permissions from
+ // another package.
+ for (int i=pkg.mAdoptPermissions.size()-1; i>=0; i--) {
+ String origName = pkg.mAdoptPermissions.get(i);
+ PackageSetting orig = mSettings.peekPackageLP(origName);
+ if (orig != null) {
+ if (verifyPackageUpdate(orig, pkg)) {
+ Log.i(TAG, "Adopting permissions from "
+ + origName + " to " + pkg.packageName);
+ mSettings.transferPermissions(origName, pkg.packageName);
+ }
+ }
+ }
+ }
+
long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
final boolean scanFileNewer = forceDex || scanFileTime != pkgSetting.getTimeStamp();
@@ -2733,29 +2818,6 @@ class PackageManagerService extends IPackageManager.Stub {
} else {
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGV)
Log.v(TAG, "Want this data dir: " + dataPath);
- if (pkgSetting.origPackage != null) {
- synchronized (mPackages) {
- // This package is being update from another; rename the
- // old one's data dir.
- String msg = "Transfering data from old package "
- + pkgSetting.origPackage.name + " to new package "
- + pkgSetting.name;
- reportSettingsProblem(Log.WARN, msg);
- if (mInstaller != null) {
- int ret = mInstaller.rename(pkgSetting.origPackage.name,
- pkgName, useEncryptedFSDir);
- if(ret < 0) {
- msg = "Error transfering data from old package "
- + pkgSetting.origPackage.name + " to new package "
- + pkgSetting.name;
- reportSettingsProblem(Log.WARN, msg);
- }
- // And now uninstall the old package.
- mInstaller.remove(pkgSetting.origPackage.name, useEncryptedFSDir);
- }
- mSettings.removePackageLP(pkgSetting.origPackage.name);
- }
- }
//invoke installer to do the actual installation
if (mInstaller != null) {
int ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
@@ -2785,12 +2847,6 @@ class PackageManagerService extends IPackageManager.Stub {
pkgSetting.uidError = uidError;
}
- // No longer need to retain this.
- if (pkgSetting.origPackage != null) {
- mTransferedPackages.add(pkgSetting.origPackage.name);
- pkgSetting.origPackage = null;
- }
-
// Perform shared library installation and dex validation and
// optimization, if this is not a system app.
if (mInstaller != null) {
@@ -2826,7 +2882,7 @@ class PackageManagerService extends IPackageManager.Stub {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
- if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING ) != 0) {
+ if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
killApplication(pkg.applicationInfo.packageName,
pkg.applicationInfo.uid);
}
@@ -2879,8 +2935,8 @@ class PackageManagerService extends IPackageManager.Stub {
Log.w(TAG, "Skipping provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
"): name already used by "
- + ((other != null && other.component != null)
- ? other.component.getPackageName() : "?"));
+ + ((other != null && other.getComponentName() != null)
+ ? other.getComponentName().getPackageName() : "?"));
}
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
@@ -3059,7 +3115,7 @@ class PackageManagerService extends IPackageManager.Stub {
a.info.sourceDir = pkg.applicationInfo.sourceDir;
a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
a.info.dataDir = pkg.applicationInfo.dataDir;
- mInstrumentation.put(a.component, a);
+ mInstrumentation.put(a.getComponentName(), a);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
@@ -3493,7 +3549,7 @@ class PackageManagerService extends IPackageManager.Stub {
r = null;
for (i=0; i<N; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
- mInstrumentation.remove(a.component);
+ mInstrumentation.remove(a.getComponentName());
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
@@ -3722,7 +3778,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
public final void addActivity(PackageParser.Activity a, String type) {
- mActivities.put(a.component, a);
+ mActivities.put(a.getComponentName(), a);
if (SHOW_INFO || Config.LOGV) Log.v(
TAG, " " + type + " " +
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
@@ -3742,7 +3798,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
public final void removeActivity(PackageParser.Activity a, String type) {
- mActivities.remove(a.component);
+ mActivities.remove(a.getComponentName());
if (SHOW_INFO || Config.LOGV) Log.v(
TAG, " " + type + " " +
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
@@ -3812,7 +3868,7 @@ class PackageManagerService extends IPackageManager.Stub {
out.print(prefix); out.print(
Integer.toHexString(System.identityHashCode(filter.activity)));
out.print(' ');
- out.println(filter.activity.componentShortName);
+ out.println(filter.activity.getComponentShortName());
}
// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
@@ -3868,7 +3924,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
public final void addService(PackageParser.Service s) {
- mServices.put(s.component, s);
+ mServices.put(s.getComponentName(), s);
if (SHOW_INFO || Config.LOGV) Log.v(
TAG, " " + (s.info.nonLocalizedLabel != null
? s.info.nonLocalizedLabel : s.info.name) + ":");
@@ -3890,7 +3946,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
public final void removeService(PackageParser.Service s) {
- mServices.remove(s.component);
+ mServices.remove(s.getComponentName());
if (SHOW_INFO || Config.LOGV) Log.v(
TAG, " " + (s.info.nonLocalizedLabel != null
? s.info.nonLocalizedLabel : s.info.name) + ":");
@@ -3963,7 +4019,7 @@ class PackageManagerService extends IPackageManager.Stub {
out.print(prefix); out.print(
Integer.toHexString(System.identityHashCode(filter.service)));
out.print(' ');
- out.println(filter.service.componentShortName);
+ out.println(filter.service.getComponentShortName());
}
// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
@@ -4799,14 +4855,14 @@ class PackageManagerService extends IPackageManager.Stub {
// First find the old package info and check signatures
synchronized(mPackages) {
oldPackage = mPackages.get(pkgName);
- if(checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures)
+ if (checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
return;
}
}
boolean sysPkg = ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
- if(sysPkg) {
+ if (sysPkg) {
replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
} else {
replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
@@ -4920,7 +4976,7 @@ class PackageManagerService extends IPackageManager.Stub {
oldPkgSetting = mSettings.mPackages.get(packageName);
if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
(oldPkgSetting == null)) {
- Log.w(TAG, "Could'nt find package:"+packageName+" information");
+ Log.w(TAG, "Couldn't find package:"+packageName+" information");
return;
}
}
@@ -5072,9 +5128,22 @@ class PackageManagerService extends IPackageManager.Stub {
boolean systemApp = false;
synchronized (mPackages) {
// Check if installing already existing package
- if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0
- && mPackages.containsKey(pkgName)) {
- replace = true;
+ if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
+ String oldName = mSettings.mRenamedPackages.get(pkgName);
+ if (oldName != null && oldName.equals(pkg.mOriginalPackage)
+ && mPackages.containsKey(oldName)) {
+ // This package is derived from an original package,
+ // and this device has been updating from that original
+ // name. We must continue using the original name, so
+ // rename the new package here.
+ pkg.setPackageName(pkg.mOriginalPackage);
+ pkgName = pkg.packageName;
+ replace = true;
+ } else if (mPackages.containsKey(pkgName)) {
+ // This package, under its official name, already exists
+ // on the device; we should replace it.
+ replace = true;
+ }
}
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
@@ -5098,7 +5167,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
// Set application objects path explicitly after the rename
setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
- if(replace) {
+ if (replace) {
replacePackageLI(pkg, parseFlags, scanMode,
installerPackageName, res);
} else {
@@ -6070,9 +6139,14 @@ class PackageManagerService extends IPackageManager.Stub {
pw.println("Packages:");
{
for (PackageSetting ps : mSettings.mPackages.values()) {
- pw.print(" Package ["); pw.print(ps.name); pw.print("] (");
+ pw.print(" Package [");
+ pw.print(ps.realName != null ? ps.realName : ps.name);
+ pw.print("] (");
pw.print(Integer.toHexString(System.identityHashCode(ps)));
pw.println("):");
+ if (ps.realName != null) {
+ pw.print(" compat name="); pw.println(ps.name);
+ }
pw.print(" userId="); pw.print(ps.userId);
pw.print(" gids="); pw.println(arrayToString(ps.gids));
pw.print(" sharedUser="); pw.println(ps.sharedUser);
@@ -6148,6 +6222,33 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
}
+ if (mSettings.mRenamedPackages.size() > 0) {
+ pw.println(" ");
+ pw.println("Renamed packages:");
+ for (HashMap.Entry<String, String> e
+ : mSettings.mRenamedPackages.entrySet()) {
+ pw.print(" "); pw.print(e.getKey()); pw.print(" -> ");
+ pw.println(e.getValue());
+ }
+ }
+ if (mSettings.mDisabledSysPackages.size() > 0) {
+ pw.println(" ");
+ pw.println("Hidden system packages:");
+ for (PackageSetting ps : mSettings.mDisabledSysPackages.values()) {
+ pw.print(" Package [");
+ pw.print(ps.realName != null ? ps.realName : ps.name);
+ pw.print("] (");
+ pw.print(Integer.toHexString(System.identityHashCode(ps)));
+ pw.println("):");
+ if (ps.realName != null) {
+ pw.print(" compat name="); pw.println(ps.name);
+ }
+ pw.print(" userId="); pw.println(ps.userId);
+ pw.print(" sharedUser="); pw.println(ps.sharedUser);
+ pw.print(" codePath="); pw.println(ps.codePathString);
+ pw.print(" resourcePath="); pw.println(ps.resourcePathString);
+ }
+ }
pw.println(" ");
pw.println("Shared Users:");
{
@@ -6660,6 +6761,7 @@ class PackageManagerService extends IPackageManager.Stub {
*/
static class PackageSettingBase extends GrantedPermissions {
final String name;
+ final String realName;
File codePath;
String codePathString;
File resourcePath;
@@ -6686,10 +6788,11 @@ class PackageManagerService extends IPackageManager.Stub {
/* package name of the app that installed this package */
String installerPackageName;
- PackageSettingBase(String name, File codePath, File resourcePath,
+ PackageSettingBase(String name, String realName, File codePath, File resourcePath,
int pVersionCode, int pkgFlags) {
super(pkgFlags);
this.name = name;
+ this.realName = realName;
init(codePath, resourcePath, pVersionCode);
}
@@ -6786,9 +6889,9 @@ class PackageManagerService extends IPackageManager.Stub {
PackageParser.Package pkg;
SharedUserSetting sharedUser;
- PackageSetting(String name, File codePath, File resourcePath,
+ PackageSetting(String name, String realName, File codePath, File resourcePath,
int pVersionCode, int pkgFlags) {
- super(name, codePath, resourcePath, pVersionCode, pkgFlags);
+ super(name, realName, codePath, resourcePath, pVersionCode, pkgFlags);
}
@Override
@@ -6878,14 +6981,20 @@ class PackageManagerService extends IPackageManager.Stub {
// storage data deleted.
final ArrayList<String> mPackagesToBeCleaned = new ArrayList<String>();
+ // 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<String, String> mRenamedPackages = new HashMap<String, String>();
+
private final StringBuilder mReadMessages = new StringBuilder();
private static final class PendingPackage extends PackageSettingBase {
final int sharedId;
- PendingPackage(String name, File codePath, File resourcePath,
+ PendingPackage(String name, String realName, File codePath, File resourcePath,
int sharedId, int pVersionCode, int pkgFlags) {
- super(name, codePath, resourcePath, pVersionCode, pkgFlags);
+ super(name, realName, codePath, resourcePath, pVersionCode, pkgFlags);
this.sharedId = sharedId;
}
}
@@ -6913,10 +7022,10 @@ class PackageManagerService extends IPackageManager.Stub {
}
PackageSetting getPackageLP(PackageParser.Package pkg, PackageSetting origPackage,
- SharedUserSetting sharedUser, File codePath, File resourcePath,
+ String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
int pkgFlags, boolean create, boolean add) {
final String name = pkg.packageName;
- PackageSetting p = getPackageLP(name, origPackage, sharedUser, codePath,
+ PackageSetting p = getPackageLP(name, origPackage, realName, sharedUser, codePath,
resourcePath, pkg.mVersionCode, pkgFlags, create, add);
return p;
}
@@ -7013,13 +7122,13 @@ class PackageManagerService extends IPackageManager.Stub {
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
- PackageSetting ret = addPackageLP(name, p.codePath,
+ PackageSetting ret = addPackageLP(name, p.realName, p.codePath,
p.resourcePath, p.userId, p.versionCode, p.pkgFlags);
mDisabledSysPackages.remove(name);
return ret;
}
- PackageSetting addPackageLP(String name, File codePath,
+ PackageSetting addPackageLP(String name, String realName, File codePath,
File resourcePath, int uid, int vc, int pkgFlags) {
PackageSetting p = mPackages.get(name);
if (p != null) {
@@ -7030,7 +7139,7 @@ class PackageManagerService extends IPackageManager.Stub {
"Adding duplicate package, keeping first: " + name);
return null;
}
- p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags);
+ p = new PackageSetting(name, realName, codePath, resourcePath, vc, pkgFlags);
p.userId = uid;
if (addUserIdLP(uid, p, name)) {
mPackages.put(name, p);
@@ -7083,7 +7192,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
private PackageSetting getPackageLP(String name, PackageSetting origPackage,
- SharedUserSetting sharedUser, File codePath, File resourcePath,
+ String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
int vc, int pkgFlags, boolean create, boolean add) {
PackageSetting p = mPackages.get(name);
if (p != null) {
@@ -7125,19 +7234,22 @@ class PackageManagerService extends IPackageManager.Stub {
if (!create) {
return null;
}
- p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags);
if (origPackage != null) {
// We are consuming the data from an existing package.
+ p = new PackageSetting(origPackage.name, name, codePath,
+ resourcePath, vc, pkgFlags);
if (DEBUG_UPGRADE) Log.v(TAG, "Package " + name
+ " is adopting original package " + origPackage.name);
p.copyFrom(origPackage);
p.sharedUser = origPackage.sharedUser;
p.userId = origPackage.userId;
p.origPackage = origPackage;
- transferPermissions(origPackage.name, name);
+ mRenamedPackages.put(name, origPackage.name);
+ name = origPackage.name;
// Update new package state.
p.setTimeStamp(codePath.lastModified());
} else {
+ p = new PackageSetting(name, realName, codePath, resourcePath, vc, pkgFlags);
p.setTimeStamp(codePath.lastModified());
p.sharedUser = sharedUser;
if (sharedUser != null) {
@@ -7449,7 +7561,16 @@ class PackageManagerService extends IPackageManager.Stub {
serializer.endTag(null, "cleaning-package");
}
}
-
+
+ if (mRenamedPackages.size() > 0) {
+ for (HashMap.Entry<String, String> 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");
serializer.endDocument();
@@ -7540,6 +7661,9 @@ class PackageManagerService extends IPackageManager.Stub {
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, "ts", pkg.getTimeStampStr());
serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
@@ -7578,6 +7702,9 @@ class PackageManagerService extends IPackageManager.Stub {
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);
@@ -7770,6 +7897,12 @@ class PackageManagerService extends IPackageManager.Stub {
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 {
Log.w(TAG, "Unknown element under <packages>: "
+ parser.getName());
@@ -7794,7 +7927,7 @@ class PackageManagerService extends IPackageManager.Stub {
final PendingPackage pp = mPendingPackages.get(i);
Object idObj = getUserIdLP(pp.sharedId);
if (idObj != null && idObj instanceof SharedUserSetting) {
- PackageSetting p = getPackageLP(pp.name, null,
+ PackageSetting p = getPackageLP(pp.name, null, pp.realName,
(SharedUserSetting)idObj, pp.codePath, pp.resourcePath,
pp.versionCode, pp.pkgFlags, true, true);
if (p == null) {
@@ -7897,9 +8030,10 @@ class PackageManagerService extends IPackageManager.Stub {
private void readDisabledSysPackageLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = parser.getAttributeValue(null, "name");
+ String realName = parser.getAttributeValue(null, "realName");
String codePathStr = parser.getAttributeValue(null, "codePath");
String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
- if(resourcePathStr == null) {
+ if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
String version = parser.getAttributeValue(null, "version");
@@ -7913,7 +8047,7 @@ class PackageManagerService extends IPackageManager.Stub {
int pkgFlags = 0;
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
- PackageSetting ps = new PackageSetting(name,
+ PackageSetting ps = new PackageSetting(name, realName,
new File(codePathStr),
new File(resourcePathStr), versionCode, pkgFlags);
String timeStampStr = parser.getAttributeValue(null, "ts");
@@ -7957,6 +8091,7 @@ class PackageManagerService extends IPackageManager.Stub {
private void readPackageLP(XmlPullParser parser)
throws XmlPullParserException, IOException {
String name = null;
+ String realName = null;
String idStr = null;
String sharedIdStr = null;
String codePathStr = null;
@@ -7972,6 +8107,7 @@ class PackageManagerService extends IPackageManager.Stub {
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");
@@ -8016,6 +8152,9 @@ class PackageManagerService extends IPackageManager.Stub {
if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
+ if (realName != null) {
+ realName = realName.intern();
+ }
if (name == null) {
reportSettingsProblem(Log.WARN,
"Error in package manager settings: <package> has no name at "
@@ -8025,8 +8164,9 @@ class PackageManagerService extends IPackageManager.Stub {
"Error in package manager settings: <package> has no codePath at "
+ parser.getPositionDescription());
} else if (userId > 0) {
- packageSetting = addPackageLP(name.intern(), new File(codePathStr),
- new File(resourcePathStr), userId, versionCode, pkgFlags);
+ packageSetting = addPackageLP(name.intern(), realName,
+ new File(codePathStr), new File(resourcePathStr),
+ userId, versionCode, pkgFlags);
if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
+ ": userId=" + userId + " pkg=" + packageSetting);
if (packageSetting == null) {
@@ -8041,8 +8181,9 @@ class PackageManagerService extends IPackageManager.Stub {
userId = sharedIdStr != null
? Integer.parseInt(sharedIdStr) : 0;
if (userId > 0) {
- packageSetting = new PendingPackage(name.intern(), new File(codePathStr),
- new File(resourcePathStr), userId, versionCode, pkgFlags);
+ packageSetting = new PendingPackage(name.intern(), realName,
+ new File(codePathStr), new File(resourcePathStr),
+ userId, versionCode, pkgFlags);
packageSetting.setTimeStamp(timeStamp, timeStampStr);
mPendingPackages.add((PendingPackage) packageSetting);
if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
@@ -8357,6 +8498,13 @@ class PackageManagerService extends IPackageManager.Stub {
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 ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0)
|| ((componentInfo.enabled
&& ((packageSettings.enabled == COMPONENT_ENABLED_STATE_ENABLED)