Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf6eaeaa authored by Suchi Amalapurapu's avatar Suchi Amalapurapu Committed by Jean-Baptiste Queru
Browse files

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.
parent 2a399f06
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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"
+1 −1
Original line number Diff line number Diff line
@@ -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);

+6 −5
Original line number Diff line number Diff line
@@ -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;
+5 −3
Original line number Diff line number Diff line
@@ -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 &&
+81 −47
Original line number Diff line number Diff line
@@ -4858,43 +4858,68 @@ 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) {
            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;
                    }
                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.renameSdDir(cid, newCacheId)) {
                    Log.e(TAG, "Failed to rename " + cid + " to " + newCacheId);
                    return false;
                }
                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);
                // Mount old container?
                if (newCachePath == null) {
                    Log.w(TAG, "Failed to get cache path for  " + newCacheId);
                    return false;
                }
                // Mount old container?
                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;
            }
        }

        int doPostInstall(int status) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
@@ -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<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 @@ 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<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 @@ class PackageManagerService extends IPackageManager.Stub {
       }
   }

   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>();
Loading