am 2a66eee3: Merge change 25157 into eclair

Merge commit '2a66eee3ef88bdc7167e5e5d0471c1e8b2e68fc6' into eclair-plus-aosp

* commit '2a66eee3ef88bdc7167e5e5d0471c1e8b2e68fc6':
  Remove deadlock in PackageManager when installing or upgrading packages.
This commit is contained in:
Suchi Amalapurapu
2009-09-16 09:43:52 -07:00
committed by Android Git Automerger

View File

@@ -3611,9 +3611,18 @@ class PackageManagerService extends IPackageManager.Stub {
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
public void run() { public void run() {
mHandler.removeCallbacks(this); mHandler.removeCallbacks(this);
PackageInstalledInfo res; // Result object to be returned
synchronized (mInstallLock) { PackageInstalledInfo res = new PackageInstalledInfo();
res = installPackageLI(packageURI, flags, true, installerPackageName); res.returnCode = PackageManager.INSTALL_SUCCEEDED;
res.uid = -1;
res.pkg = null;
res.removedInfo = new PackageRemovedInfo();
// Make a temporary copy of file from given packageURI
File tmpPackageFile = copyTempInstallFile(packageURI, res);
if (tmpPackageFile != null) {
synchronized (mInstallLock) {
installPackageLI(packageURI, flags, true, installerPackageName, tmpPackageFile, res);
}
} }
if (observer != null) { if (observer != null) {
try { try {
@@ -3828,11 +3837,30 @@ class PackageManagerService extends IPackageManager.Stub {
// Since we failed to install the new package we need to restore the old // Since we failed to install the new package we need to restore the old
// package that we deleted. // package that we deleted.
if(deletedPkg) { if(deletedPkg) {
File restoreFile = new File(deletedPackage.mPath);
if (restoreFile == null) {
Log.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
return;
}
File restoreTmpFile = createTempPackageFile();
if (restoreTmpFile == null) {
Log.e(TAG, "Failed creating temp file when restoring pkg : " + pkgName);
return;
}
if (!FileUtils.copyFile(restoreFile, restoreTmpFile)) {
Log.e(TAG, "Failed copying temp file when restoring pkg : " + pkgName);
return;
}
PackageInstalledInfo restoreRes = new PackageInstalledInfo();
restoreRes.removedInfo = new PackageRemovedInfo();
installPackageLI( installPackageLI(
Uri.fromFile(new File(deletedPackage.mPath)), Uri.fromFile(restoreFile),
isForwardLocked(deletedPackage) isForwardLocked(deletedPackage)
? PackageManager.INSTALL_FORWARD_LOCK ? PackageManager.INSTALL_FORWARD_LOCK
: 0, false, oldInstallerPackageName); : 0, false, oldInstallerPackageName, restoreTmpFile, restoreRes);
if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) {
Log.e(TAG, "Failed restoring pkg : " + pkgName + " after failed upgrade");
}
} }
} }
} }
@@ -3995,50 +4023,36 @@ class PackageManagerService extends IPackageManager.Stub {
return new File(mAppInstallDir, publicZipFileName); return new File(mAppInstallDir, publicZipFileName);
} }
private PackageInstalledInfo installPackageLI(Uri pPackageURI, private File copyTempInstallFile(Uri pPackageURI,
int pFlags, boolean newInstall, String installerPackageName) { PackageInstalledInfo res) {
File tmpPackageFile = null; File tmpPackageFile = createTempPackageFile();
String pkgName = null; int retCode = PackageManager.INSTALL_SUCCEEDED;
boolean forwardLocked = false; if (tmpPackageFile == null) {
boolean replacingExistingPackage = false; res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
// Result object to be returned return null;
PackageInstalledInfo res = new PackageInstalledInfo(); }
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
res.uid = -1;
res.pkg = null;
res.removedInfo = new PackageRemovedInfo();
main_flow: try { if (pPackageURI.getScheme().equals("file")) {
tmpPackageFile = createTempPackageFile(); final File srcPackageFile = new File(pPackageURI.getPath());
if (tmpPackageFile == null) { // We copy the source package file to a temp file and then rename it to the
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; // destination file in order to eliminate a window where the package directory
break main_flow; // scanner notices the new package file but it's not completely copied yet.
if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
Log.e(TAG, "Couldn't copy package file to temp file.");
retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
} }
tmpPackageFile.deleteOnExit(); // paranoia } else if (pPackageURI.getScheme().equals("content")) {
if (pPackageURI.getScheme().equals("file")) { ParcelFileDescriptor fd = null;
final File srcPackageFile = new File(pPackageURI.getPath()); try {
// We copy the source package file to a temp file and then rename it to the fd = mContext.getContentResolver().openFileDescriptor(pPackageURI, "r");
// destination file in order to eliminate a window where the package directory } catch (FileNotFoundException e) {
// scanner notices the new package file but it's not completely copied yet. Log.e(TAG, "Couldn't open file descriptor from download service. Failed with exception " + e);
if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) { retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
Log.e(TAG, "Couldn't copy package file to temp file."); }
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; if (fd == null) {
break main_flow; Log.e(TAG, "Couldn't open file descriptor from download service (null).");
} retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
} else if (pPackageURI.getScheme().equals("content")) { } else {
ParcelFileDescriptor fd;
try {
fd = mContext.getContentResolver().openFileDescriptor(pPackageURI, "r");
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't open file descriptor from download service.");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
if (fd == null) {
Log.e(TAG, "Couldn't open file descriptor from download service (null).");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
if (Config.LOGV) { if (Config.LOGV) {
Log.v(TAG, "Opened file descriptor from download service."); Log.v(TAG, "Opened file descriptor from download service.");
} }
@@ -4049,14 +4063,34 @@ class PackageManagerService extends IPackageManager.Stub {
// scanner notices the new package file but it's not completely copied yet. // scanner notices the new package file but it's not completely copied yet.
if (!FileUtils.copyToFile(dlStream, tmpPackageFile)) { if (!FileUtils.copyToFile(dlStream, tmpPackageFile)) {
Log.e(TAG, "Couldn't copy package stream to temp file."); Log.e(TAG, "Couldn't copy package stream to temp file.");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
} }
} else {
Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
res.returnCode = PackageManager.INSTALL_FAILED_INVALID_URI;
break main_flow;
} }
} else {
Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
}
res.returnCode = retCode;
if (retCode != PackageManager.INSTALL_SUCCEEDED) {
if (tmpPackageFile != null && tmpPackageFile.exists()) {
tmpPackageFile.delete();
}
return null;
}
return tmpPackageFile;
}
private void installPackageLI(Uri pPackageURI,
int pFlags, boolean newInstall, String installerPackageName,
File tmpPackageFile, PackageInstalledInfo res) {
String pkgName = null;
boolean forwardLocked = false;
boolean replacingExistingPackage = false;
// Result object to be returned
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
main_flow: try {
pkgName = PackageParser.parsePackageName( pkgName = PackageParser.parsePackageName(
tmpPackageFile.getAbsolutePath(), 0); tmpPackageFile.getAbsolutePath(), 0);
if (pkgName == null) { if (pkgName == null) {
@@ -4128,7 +4162,6 @@ class PackageManagerService extends IPackageManager.Stub {
tmpPackageFile.delete(); tmpPackageFile.delete();
} }
} }
return res;
} }
private int setPermissionsLI(String pkgName, private int setPermissionsLI(String pkgName,