From c7537ee7b6a7d7c857a02170fa9f41461e5d075b Mon Sep 17 00:00:00 2001 From: Suchi Amalapurapu Date: Wed, 24 Mar 2010 09:27:19 -0700 Subject: [PATCH] Clean up stale containers if needed at install time. This is needed when restoring applications installed on sdcard via Market after a data wipe. The stale containers need to be cleaned up before reinstalling again. Add a test case for installing when a stale container exists. Change-Id: I20c30b3003e85fb31531dd3cf9cb59962fe8fe5f --- .../android/server/PackageManagerService.java | 15 ++++- .../unit_tests/PackageManagerTests.java | 63 +++++++++++++------ 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 4d7b393d1a98d..b3705c3f8feda 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -5214,8 +5214,19 @@ class PackageManagerService extends IPackageManager.Stub { } } if (!PackageHelper.renameSdDir(cid, newCacheId)) { - Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId); - return false; + Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + + " which might be stale. Will try to clean up."); + // Clean up the stale container and proceed to recreate. + if (!PackageHelper.destroySdDir(newCacheId)) { + Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); + return false; + } + // Successfully cleaned up stale container. Try to rename again. + if (!PackageHelper.renameSdDir(cid, newCacheId)) { + Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + + " inspite of cleaning it up."); + return false; + } } if (!PackageHelper.isContainerMounted(newCacheId)) { Slog.w(TAG, "Mounting container " + newCacheId); diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java index 6975c706cd433..449661c944597 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java @@ -520,24 +520,6 @@ public class PackageManagerTests extends AndroidTestCase { } } } - - public void clearSecureContainersForPkg(String pkgName) { - IMountService ms = getMs(); - try { - String list[] = ms.getSecureContainerList(); - if (list != null) { - for (String cid : list) { - boolean delete = false; - // STOPSHIP issues with rename should be fixed. - if (cid.contains(pkgName) || - cid.contains("smdltmp")) { - Log.i(TAG, "Destroying container " + cid); - ms.destroySecureContainer(cid, true); - } - } - } - } catch (RemoteException e) {} - } /* * Utility function that reads a apk bundled as a raw resource @@ -792,7 +774,7 @@ public class PackageManagerTests extends AndroidTestCase { waitTime += WAIT_TIME_INCR; } if(!receiver.isDone()) { - throw new Exception("Timed out waiting for PACKAGE_ADDED notification"); + throw new Exception("Timed out waiting for PACKAGE_REMOVED notification"); } return receiver.received; } @@ -2186,6 +2168,49 @@ public class PackageManagerTests extends AndroidTestCase { } } } + + /* This test creates a stale container via MountService and then installs + * a package and verifies that the stale container is cleaned up and install + * is successful. + * Please note that this test is very closely tied to the framework's + * naming convention for secure containers. + */ + public void testInstallSdcardStaleContainer() { + boolean origMediaState = getMediaState(); + try { + String outFileName = "install.apk"; + int rawResId = R.raw.install; + PackageManager pm = mContext.getPackageManager(); + File filesDir = mContext.getFilesDir(); + File outFile = new File(filesDir, outFileName); + Uri packageURI = getInstallablePackage(rawResId, outFile); + PackageParser.Package pkg = parsePackage(packageURI); + assertNotNull(pkg); + // Install an app on sdcard. + installFromRawResource(outFileName, rawResId, + PackageManager.INSTALL_EXTERNAL, false, + false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); + // Unmount sdcard + unmountMedia(); + // Delete the app on sdcard to leave a stale container on sdcard. + GenericReceiver receiver = new DeleteReceiver(pkg.packageName); + assertTrue(invokeDeletePackage(packageURI, 0, pkg.packageName, receiver)); + mountMedia(); + // Reinstall the app and make sure it gets installed. + installFromRawResource(outFileName, rawResId, + PackageManager.INSTALL_EXTERNAL, true, + false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); + } catch (Exception e) { + failStr(e.getMessage()); + } finally { + if (origMediaState) { + mountMedia(); + } else { + unmountMedia(); + } + + } + } /*---------- Recommended install location tests ----*/ /* * TODO's