From 2d3709246ed7933d456397ead7d782eb9c126d88 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 10 May 2016 17:01:49 -0600 Subject: [PATCH] Fail upgrades that change storage devices. Now that we live in an FBE world, we need the user to be involved with every package move to ensure that CE storage is unlocked. This means that a package upgrade session that would require moving an app between storage devices cannot be satisfied. Bug: 27147501 Change-Id: I274d85cbed727d9185178b77bfc6cef196df17f5 --- .../internal/content/PackageHelper.java | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index 8219c61daf7fd..4e3c3fc94a434 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -37,7 +37,6 @@ import android.os.storage.VolumeInfo; import android.provider.Settings; import android.util.ArraySet; import android.util.Log; -import android.util.Slog; import libcore.io.IoUtils; @@ -46,6 +45,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; +import java.util.Objects; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @@ -383,23 +383,31 @@ public class PackageHelper { installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY; } - // If app expresses strong desire for internal space, honor it + // If app expresses strong desire for internal storage, honor it if (!forceAllowOnExternal && installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { + if (existingInfo != null && !Objects.equals(existingInfo.volumeUuid, + StorageManager.UUID_PRIVATE_INTERNAL)) { + throw new IOException("Cannot automatically move " + packageName + " from " + + existingInfo.volumeUuid + " to internal storage"); + } if (fitsOnInternal) { - return null; + return StorageManager.UUID_PRIVATE_INTERNAL; } else { throw new IOException("Requested internal only, but not enough space"); } } - // If app already exists somewhere, prefer to stay on that volume + // If app already exists somewhere, we must stay on that volume if (existingInfo != null) { - if (existingInfo.volumeUuid == null && fitsOnInternal) { - return null; - } - if (allCandidates.contains(existingInfo.volumeUuid)) { + if (Objects.equals(existingInfo.volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL) + && fitsOnInternal) { + return StorageManager.UUID_PRIVATE_INTERNAL; + } else if (allCandidates.contains(existingInfo.volumeUuid)) { return existingInfo.volumeUuid; + } else { + throw new IOException("Not enough space on existing volume " + + existingInfo.volumeUuid + " for " + packageName + " upgrade"); } } @@ -408,7 +416,7 @@ public class PackageHelper { if (bestCandidate != null) { return bestCandidate.fsUuid; } else if (fitsOnInternal) { - return null; + return StorageManager.UUID_PRIVATE_INTERNAL; } else { throw new IOException("No special requests, but no room anywhere"); }