From cf6eaeaae9e6745dd6e07540812c79821d7043c2 Mon Sep 17 00:00:00 2001 From: Suchi Amalapurapu Date: Tue, 23 Feb 2010 19:37:45 -0800 Subject: [PATCH] Some framework fixes for apps on sd change hard coded path in installd fix tests Work around for renaming containers. Do forced unmount when destroying containers. Force a gc in default container service to release handle to parsed package and thus avoid getting killed by vold Some cosmetic changes to PackageManager api. Unit tests for renaming container for MountService Remove internal size limit on app to be installed. --- cmds/installd/installd.h | 2 +- core/java/android/content/pm/IPackageManager.aidl | 2 +- .../android/internal/content/PackageHelper.java | 11 +- .../defcontainer/DefaultContainerService.java | 8 +- .../com/android/server/PackageManagerService.java | 128 ++++++++++------ .../src/com/android/unit_tests/AsecTests.java | 29 ++++ .../android/unit_tests/PackageManagerTests.java | 168 +++++++++++++++------ 7 files changed, 246 insertions(+), 102 deletions(-) diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 92ae310d1a3f..66f3676f2b23 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -68,7 +68,7 @@ /* other handy constants */ #define PROTECTED_DIR_PREFIX "/data/app-private/" -#define SDCARD_DIR_PREFIX "/asec/" +#define SDCARD_DIR_PREFIX "/mnt/asec/" #define DALVIK_CACHE_PREFIX "/data/dalvik-cache/" #define DALVIK_CACHE_POSTFIX "/classes.dex" diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index f793a00f397a..399a87dde3a6 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -309,7 +309,7 @@ interface IPackageManager { * MountService uses this to call into the package manager to update * status of sdcard. */ - void updateExternalMediaStatus(boolean mounted); + boolean updateExternalMediaStatus(boolean mounted); String nextPackageToClean(String lastPackage); diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index bc7dbf4e7b21..c5db83fba62a 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -36,7 +36,7 @@ public class PackageHelper { public static final int RECOMMEND_INSTALL_EXTERNAL = 2; public static final int RECOMMEND_FAILED_INSUFFICIENT_STORAGE = -1; public static final int RECOMMEND_FAILED_INVALID_APK = -2; - private static final boolean DEBUG_SD_INSTALL = true; + private static final boolean localLOGV = true; private static final String TAG = "PackageHelper"; public static IMountService getMountService() { @@ -58,7 +58,7 @@ public class PackageHelper { if ((len - (mbLen * 1024 * 1024)) > 0) { mbLen++; } - if (DEBUG_SD_INSTALL) Log.i(TAG, "Size of resource " + mbLen); + if (localLOGV) Log.i(TAG, "Size of resource " + mbLen); try { int rc = mountService.createSecureContainer( @@ -68,7 +68,7 @@ public class PackageHelper { return null; } String cachePath = mountService.getSecureContainerPath(cid); - if (DEBUG_SD_INSTALL) Log.i(TAG, "Created secure container " + cid + + if (localLOGV) Log.i(TAG, "Created secure container " + cid + " at " + cachePath); return cachePath; } catch (RemoteException e) { @@ -93,7 +93,7 @@ public class PackageHelper { public static boolean unMountSdDir(String cid) { try { - int rc = getMountService().unmountSecureContainer(cid, false); + int rc = getMountService().unmountSecureContainer(cid, true); if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc); return false; @@ -148,7 +148,8 @@ public class PackageHelper { public static boolean destroySdDir(String cid) { try { - int rc = getMountService().destroySecureContainer(cid, false); + if (localLOGV) Log.i(TAG, "Forcibly destroying container " + cid); + int rc = getMountService().destroySecureContainer(cid, true); if (rc != StorageResultCode.OperationSucceeded) { Log.i(TAG, "Failed to destroy container " + cid); return false; diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 95ab684e2347..a79f0cdb1f5a 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -39,7 +39,7 @@ import android.provider.Settings; */ public class DefaultContainerService extends IntentService { private static final String TAG = "DefContainer"; - private static final boolean localLOGV = false; + private static final boolean localLOGV = true; private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() { /* @@ -211,6 +211,8 @@ public class DefaultContainerService extends IntentService { if (PackageHelper.isContainerMounted(newCid)) { if (localLOGV) Log.i(TAG, "Unmounting " + newCid + " at path " + newCachePath + " after " + errMsg); + // Force a gc to avoid being killed. + Runtime.getRuntime().gc(); PackageHelper.unMountSdDir(newCid); } else { if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted"); @@ -328,8 +330,8 @@ public class DefaultContainerService extends IntentService { boolean auto = true; // To make final copy long reqInstallSize = pkgLen; - // For dex files - long reqInternalSize = 1 * pkgLen; + // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now. + long reqInternalSize = 0; boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD); boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize); boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk && diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 4a7fc9c0570b..9e0d6239216c 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -4858,42 +4858,67 @@ class PackageManagerService extends IPackageManager.Stub { String oldCodePath) { String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME); String newCachePath = null; - final int RENAME_FAILED = 1; - final int MOUNT_FAILED = 2; - final int PASS = 4; - int errCode = RENAME_FAILED; - String errMsg = "RENAME_FAILED"; - boolean mounted = PackageHelper.isContainerMounted(cid); - if (mounted) { - // Unmount the container - if (!PackageHelper.unMountSdDir(cid)) { - Log.i(TAG, "Failed to unmount " + cid + " before renaming"); + boolean enableRename = false; + if (enableRename) { + if (PackageHelper.isContainerMounted(cid)) { + // Unmount the container + if (!PackageHelper.unMountSdDir(cid)) { + Log.i(TAG, "Failed to unmount " + cid + " before renaming"); + return false; + } + } + if (!PackageHelper.renameSdDir(cid, newCacheId)) { + Log.e(TAG, "Failed to rename " + cid + " to " + newCacheId); return false; } - mounted = false; - } - if (PackageHelper.renameSdDir(cid, newCacheId)) { - errCode = MOUNT_FAILED; - errMsg = "MOUNT_FAILED"; - if ((newCachePath = PackageHelper.mountSdDir(newCacheId, - getEncryptKey(), Process.SYSTEM_UID)) != null) { - errCode = PASS; - errMsg = "PASS"; + if (!PackageHelper.isContainerMounted(newCacheId)) { + Log.w(TAG, "Mounting container " + newCacheId); + newCachePath = PackageHelper.mountSdDir(newCacheId, + getEncryptKey(), Process.SYSTEM_UID); + } else { + newCachePath = PackageHelper.getSdDir(newCacheId); + } + if (newCachePath == null) { + Log.w(TAG, "Failed to get cache path for " + newCacheId); + return false; } - } - if (errCode != PASS) { - Log.i(TAG, "Failed to rename " + cid + " to " + newCacheId + - " at path: " + cachePath + " to new path: " + newCachePath + - "err = " + errMsg); // Mount old container? - return false; + Log.i(TAG, "Succesfully renamed " + cid + + " at path: " + cachePath + " to " + newCacheId + + " at new path: " + newCachePath); + cid = newCacheId; + cachePath = newCachePath; + return true; } else { - Log.i(TAG, "Succesfully renamed " + cid + " to " + newCacheId + - " at path: " + cachePath + " to new path: " + newCachePath); + // STOPSHIP work around for rename + Log.i(TAG, "Copying instead of renaming"); + File srcFile = new File(getCodePath()); + // Create new container + newCachePath = PackageHelper.createSdDir(srcFile, newCacheId, + getEncryptKey(), Process.SYSTEM_UID); + Log.i(TAG, "Created rename container " + newCacheId); + File destFile = new File(newCachePath + "/" + RES_FILE_NAME); + if (!FileUtils.copyFile(srcFile, destFile)) { + Log.e(TAG, "Failed to copy " + srcFile + " to " + destFile); + return false; + } + Log.i(TAG, "Successfully copied resource to " + newCachePath); + if (!PackageHelper.finalizeSdDir(newCacheId)) { + Log.e(TAG, "Failed to finalize " + newCacheId); + PackageHelper.destroySdDir(newCacheId); + return false; + } + Log.i(TAG, "Finalized " + newCacheId); + Runtime.getRuntime().gc(); + // Unmount first + PackageHelper.unMountSdDir(cid); + // Delete old container + PackageHelper.destroySdDir(cid); + // Dont have to mount. Already mounted. + cid = newCacheId; + cachePath = newCachePath; + return true; } - cid = newCacheId; - cachePath = newCachePath; - return true; } int doPostInstall(int status) { @@ -5403,6 +5428,7 @@ class PackageManagerService extends IPackageManager.Stub { res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; return; } + if (!args.doRename(res.returnCode, pkgName, oldCodePath)) { res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; return; @@ -8809,7 +8835,7 @@ class PackageManagerService extends IPackageManager.Stub { } static String getTempContainerId() { - String prefix = "smdl1tmp"; + String prefix = "smdl2tmp"; int tmpIdx = 1; String list[] = PackageHelper.getSecureContainerList(); if (list != null) { @@ -8851,30 +8877,45 @@ class PackageManagerService extends IPackageManager.Stub { return prefix + tmpIdx; } - public void updateExternalMediaStatus(final boolean mediaStatus) { + public boolean updateExternalMediaStatus(final boolean mediaStatus) { synchronized (mPackages) { if (DEBUG_SD_INSTALL) Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus+", mMediaMounted=" + mMediaMounted); if (mediaStatus == mMediaMounted) { - return; + return false; } mMediaMounted = mediaStatus; + final HashMap processCids = + new HashMap(); + final int[] uidArr = getExternalMediaPackages(mediaStatus, processCids); + if (processCids.size() == 0) { + return false; + } // Queue up an async operation since the package installation may take a little while. mHandler.post(new Runnable() { public void run() { mHandler.removeCallbacks(this); - updateExternalMediaStatusInner(mediaStatus); + if (mediaStatus) { + if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages"); + loadMediaPackages(processCids, uidArr); + startCleaningPackages(); + } else { + if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading packages"); + unloadMediaPackages(processCids, uidArr); + } } }); + return true; } } - void updateExternalMediaStatusInner(boolean mediaStatus) { + private int[] getExternalMediaPackages(boolean mediaStatus, + Map processCids) { final String list[] = PackageHelper.getSecureContainerList(); if (list == null || list.length == 0) { - return; + return null; } - HashMap processCids = new HashMap(); + int uidList[] = new int[list.length]; int num = 0; synchronized (mPackages) { @@ -8916,14 +8957,7 @@ class PackageManagerService extends IPackageManager.Stub { } } } - if (mediaStatus) { - if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages"); - loadMediaPackages(processCids, uidArr); - startCleaningPackages(); - } else { - if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading packages"); - unloadMediaPackages(processCids, uidArr); - } + return uidArr; } private void sendResourcesChangedBroadcast(boolean mediaStatus, @@ -8943,7 +8977,7 @@ class PackageManagerService extends IPackageManager.Stub { } } - void loadMediaPackages(HashMap processCids, int uidArr[]) { + private void loadMediaPackages(HashMap processCids, int uidArr[]) { ArrayList pkgList = new ArrayList(); Set keys = processCids.keySet(); for (SdInstallArgs args : keys) { @@ -8993,7 +9027,7 @@ class PackageManagerService extends IPackageManager.Stub { } } - void unloadMediaPackages(HashMap processCids, int uidArr[]) { + private void unloadMediaPackages(HashMap processCids, int uidArr[]) { if (DEBUG_SD_INSTALL) Log.i(TAG, "unloading media packages"); ArrayList pkgList = new ArrayList(); ArrayList failedList = new ArrayList(); diff --git a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java index d5d23266d70a..e85254d60b44 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java @@ -132,6 +132,14 @@ public class AsecTests extends AndroidTestCase { return ms.destroySecureContainer(fullId, force); } + private boolean isContainerMounted(String localId) throws RemoteException { + Assert.assertTrue(isMediaMounted()); + String fullId = "com.android.unittests.AsecTests." + localId; + + IMountService ms = getMs(); + return ms.isSecureContainerMounted(fullId); + } + private IMountService getMs() { IBinder service = ServiceManager.getService("mount"); if (service != null) { @@ -329,4 +337,25 @@ public class AsecTests extends AndroidTestCase { failStr(e); } } + + public void testIsContainerMountedAfterRename() { + try { + Assert.assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none")); + + Assert.assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testRenameContainer.1", false)); + + Assert.assertEquals(StorageResultCode.OperationSucceeded, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); + + Assert.assertEquals(false, containerExists("testRenameContainer.1")); + Assert.assertEquals(true, containerExists("testRenameContainer.2")); + // Check if isContainerMounted returns valid value + Assert.assertEquals(true, isContainerMounted("testRenameContainer.2")); + } catch (Exception e) { + failStr(e); + } + } + } diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java index 9c5c44d32faa..d161a8838581 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java @@ -57,17 +57,25 @@ import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.storage.IMountService; +import android.os.storage.IMountServiceListener; +import android.os.storage.StorageEventListener; +import android.os.storage.StorageManager; import android.os.storage.StorageResultCode; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; public class PackageManagerTests extends AndroidTestCase { private static final boolean localLOGV = true; public static final String TAG="PackageManagerTests"; public final long MAX_WAIT_TIME=120*1000; public final long WAIT_TIME_INCR=20*1000; + private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec"; + private static final int APP_INSTALL_AUTO = 0; + private static final int APP_INSTALL_DEVICE = 1; + private static final int APP_INSTALL_SDCARD = 2; void failStr(String errMsg) { Log.w(TAG, "errMsg="+errMsg); @@ -244,9 +252,46 @@ public class PackageManagerTests extends AndroidTestCase { packageParser = null; return pkg; } - - private void assertInstall(String pkgName, int flags) { + private boolean getInstallLoc(int flags, int expInstallLocation) { + // Flags explicitly over ride everything else. + if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) { + return false; + } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) { + return true; + } + // Manifest option takes precedence next + if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { + return true; + } + // TODO Out of memory checks here. + boolean checkSd = false; + int setLoc = 0; + try { + setLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION); + } catch (SettingNotFoundException e) { + failStr(e); + } + if (setLoc == 1) { + int userPref = APP_INSTALL_AUTO; + try { + userPref = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION); + } catch (SettingNotFoundException e) { + failStr(e); + } + if (userPref == APP_INSTALL_DEVICE) { + checkSd = false; + } else if (userPref == APP_INSTALL_SDCARD) { + checkSd = true; + } else if (userPref == APP_INSTALL_AUTO) { + // Might be determined dynamically. TODO fix this + checkSd = false; + } + } + return checkSd; + } + private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) { try { + String pkgName = pkg.packageName; ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0); assertNotNull(info); assertEquals(pkgName, info.packageName); @@ -264,15 +309,14 @@ public class PackageManagerTests extends AndroidTestCase { assertEquals(publicSrcPath, appInstallPath); } else { assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); - if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { - assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0); - // Hardcoded for now - assertTrue(srcPath.startsWith("/asec")); - assertTrue(publicSrcPath.startsWith("/asec")); - } else { + if (!getInstallLoc(flags, expInstallLocation)) { assertEquals(srcPath, appInstallPath); assertEquals(publicSrcPath, appInstallPath); assertFalse((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0); + } else { + assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0); + assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX)); + assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX)); } } } catch (NameNotFoundException e) { @@ -300,7 +344,7 @@ public class PackageManagerTests extends AndroidTestCase { private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) { return installFromRawResource("install.apk", R.raw.install, flags, cleanUp, - false, -1); + false, -1, PackageInfo.INSTALL_LOCATION_AUTO); } public void clearSecureContainersForPkg(String pkgName) { @@ -327,7 +371,8 @@ public class PackageManagerTests extends AndroidTestCase { * PackageManager api to install it. */ private InstallParams installFromRawResource(String outFileName, - int rawResId, int flags, boolean cleanUp, boolean fail, int result) { + int rawResId, int flags, boolean cleanUp, boolean fail, int result, + int expInstallLocation) { File filesDir = mContext.getFilesDir(); File outFile = new File(filesDir, outFileName); Uri packageURI = getInstallablePackage(rawResId, outFile); @@ -337,9 +382,7 @@ public class PackageManagerTests extends AndroidTestCase { // Make sure the package doesn't exist getPm().deletePackage(pkg.packageName, null, 0); // Clean up the containers as well - if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { - clearSecureContainersForPkg(pkg.packageName); - } + clearSecureContainersForPkg(pkg.packageName); try { try { if (fail) { @@ -351,7 +394,7 @@ public class PackageManagerTests extends AndroidTestCase { assertTrue(invokeInstallPackage(packageURI, flags, pkg.packageName, receiver)); // Verify installed information - assertInstall(pkg.packageName, flags); + assertInstall(pkg, flags, expInstallLocation); ip = new InstallParams(pkg, outFileName, packageURI); } } catch (Exception e) { @@ -443,6 +486,7 @@ public class PackageManagerTests extends AndroidTestCase { public void replaceFromRawResource(int flags) { InstallParams ip = sampleInstallFromRawResource(flags, false); boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0); + Log.i(TAG, "replace=" + replace); GenericReceiver receiver; if (replace) { receiver = new ReplaceReceiver(ip.pkg.packageName); @@ -455,7 +499,7 @@ public class PackageManagerTests extends AndroidTestCase { assertEquals(invokeInstallPackage(ip.packageURI, flags, ip.pkg.packageName, receiver), replace); if (replace) { - assertInstall(ip.pkg.packageName, flags); + assertInstall(ip.pkg, flags, ip.pkg.installLocation); } } catch (Exception e) { failStr("Failed with exception : " + e); @@ -738,51 +782,73 @@ public class PackageManagerTests extends AndroidTestCase { } } + class StorageListener extends StorageEventListener { + String oldState; + String newState; + String path; + private boolean doneFlag = false; + @Override + public void onStorageStateChanged(String path, String oldState, String newState) { + if (localLOGV) Log.i(TAG, "Storage state changed from " + oldState + " to " + newState); + synchronized (this) { + this.oldState = oldState; + this.newState = newState; + this.path = path; + doneFlag = true; + notifyAll(); + } + } + + public boolean isDone() { + return doneFlag; + } + } + private boolean unmountMedia() { if (!getMediaState()) { return true; } + String path = Environment.getExternalStorageDirectory().toString(); + StorageListener observer = new StorageListener(); + StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); + sm.registerListener(observer); try { - String mPath = Environment.getExternalStorageDirectory().toString(); - int ret = getMs().unmountVolume(mPath, false); - return ret == StorageResultCode.OperationSucceeded; - } catch (RemoteException e) { - return true; + // Wait on observer + synchronized(observer) { + getMs().unmountVolume(path, false); + long waitTime = 0; + while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!observer.isDone()) { + throw new Exception("Timed out waiting for packageInstalled callback"); + } + return true; + } + } catch (Exception e) { + return false; + } finally { + sm.unregisterListener(observer); } } - /* - * Install package on sdcard. Unmount and then mount the media. - * (Use PackageManagerService private api for now) - * Make sure the installed package is available. - * STOPSHIP will uncomment when MountService api's to mount/unmount - * are made asynchronous. - */ - public void xxxtestMountSdNormalInternal() { - assertTrue(mountFromRawResource()); - } - private boolean mountFromRawResource() { // Install pkg on sdcard - InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL | - PackageManager.INSTALL_REPLACE_EXISTING, false); + InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false); if (localLOGV) Log.i(TAG, "Installed pkg on sdcard"); boolean origState = getMediaState(); + boolean registeredReceiver = false; SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName}); try { if (localLOGV) Log.i(TAG, "Unmounting media"); // Unmount media assertTrue(unmountMedia()); if (localLOGV) Log.i(TAG, "Unmounted media"); - try { - if (localLOGV) Log.i(TAG, "Sleeping for 10 second"); - Thread.sleep(10*1000); - } catch (InterruptedException e) { - failStr(e); - } // Register receiver here PackageManager pm = getPm(); mContext.registerReceiver(receiver, receiver.filter); + registeredReceiver = true; // Wait on receiver synchronized (receiver) { @@ -807,7 +873,7 @@ public class PackageManagerTests extends AndroidTestCase { failStr(e); return false; } finally { - mContext.unregisterReceiver(receiver); + if (registeredReceiver) mContext.unregisterReceiver(receiver); // Restore original media state if (origState) { mountMedia(); @@ -819,6 +885,17 @@ public class PackageManagerTests extends AndroidTestCase { } } + /* + * Install package on sdcard. Unmount and then mount the media. + * (Use PackageManagerService private api for now) + * Make sure the installed package is available. + * STOPSHIP will uncomment when MountService api's to mount/unmount + * are made asynchronous. + */ + public void xxxtestMountSdNormalInternal() { + assertTrue(mountFromRawResource()); + } + void cleanUpInstall(InstallParams ip) { if (ip == null) { return; @@ -834,28 +911,29 @@ public class PackageManagerTests extends AndroidTestCase { public void testManifestInstallLocationInternal() { installFromRawResource("install.apk", R.raw.install_loc_internal, - 0, true, false, -1); + 0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); } public void testManifestInstallLocationSdcard() { installFromRawResource("install.apk", R.raw.install_loc_sdcard, - 0, true, false, -1); + 0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); } public void testManifestInstallLocationAuto() { installFromRawResource("install.apk", R.raw.install_loc_auto, - 0, true, false, -1); + 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO); } public void testManifestInstallLocationUnspecified() { installFromRawResource("install.apk", R.raw.install_loc_unspecified, - 0, true, false, -1); + 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO); } public void testManifestInstallLocationFwdLockedSdcard() { installFromRawResource("install.apk", R.raw.install_loc_sdcard, PackageManager.INSTALL_FORWARD_LOCK, true, true, - PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION); + PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, + PackageInfo.INSTALL_LOCATION_AUTO); } public void xxxtestClearAllSecureContainers() { -- 2.11.0