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.
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 4a7fc9c..9e0d623 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4858,42 +4858,67 @@
                 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 (errCode != PASS) {
-                Log.i(TAG, "Failed to rename " + cid + " to " + newCacheId +
-                        " at path: " + cachePath + " to new path: " + newCachePath +
-                        "err = " + errMsg);
+                if (newCachePath == null) {
+                    Log.w(TAG, "Failed to get cache path for  " + newCacheId);
+                    return false;
+                }
                 // 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 @@
             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 @@
     }
 
    static String getTempContainerId() {
-       String prefix = "smdl1tmp";
+       String prefix = "smdl2tmp";
        int tmpIdx = 1;
        String list[] = PackageHelper.getSecureContainerList();
        if (list != null) {
@@ -8851,30 +8877,45 @@
        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<SdInstallArgs, String> processCids =
+                   new HashMap<SdInstallArgs, String>();
+           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<SdInstallArgs, String> processCids) {
        final String list[] = PackageHelper.getSecureContainerList();
        if (list == null || list.length == 0) {
-           return;
+           return null;
        }
-       HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>();
+
        int uidList[] = new int[list.length];
        int num = 0;
        synchronized (mPackages) {
@@ -8916,14 +8957,7 @@
                }
            }
        }
-       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 @@
        }
    }
 
-   void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
+   private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
        ArrayList<String> pkgList = new ArrayList<String>();
        Set<SdInstallArgs> keys = processCids.keySet();
        for (SdInstallArgs args : keys) {
@@ -8993,7 +9027,7 @@
        }
    }
 
-   void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
+   private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
        if (DEBUG_SD_INSTALL) Log.i(TAG, "unloading media packages");
        ArrayList<String> pkgList = new ArrayList<String>();
        ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>();