Loading core/java/android/os/storage/StorageManager.java +20 −0 Original line number Diff line number Diff line Loading @@ -1987,11 +1987,31 @@ public class StorageManager { */ public static final int FLAG_ALLOCATE_DEFY_HALF_RESERVED = 1 << 2; /** * Flag indicating that a disk space check should not take into account * freeable cached space when determining allocatable space. * * Intended for use with {@link #getAllocatableBytes()}. * @hide */ public static final int FLAG_ALLOCATE_NON_CACHE_ONLY = 1 << 3; /** * Flag indicating that a disk space check should only return freeable * cached space when determining allocatable space. * * Intended for use with {@link #getAllocatableBytes()}. * @hide */ public static final int FLAG_ALLOCATE_CACHE_ONLY = 1 << 4; /** @hide */ @IntDef(flag = true, prefix = { "FLAG_ALLOCATE_" }, value = { FLAG_ALLOCATE_AGGRESSIVE, FLAG_ALLOCATE_DEFY_ALL_RESERVED, FLAG_ALLOCATE_DEFY_HALF_RESERVED, FLAG_ALLOCATE_NON_CACHE_ONLY, FLAG_ALLOCATE_CACHE_ONLY, }) @Retention(RetentionPolicy.SOURCE) public @interface AllocateFlags {} Loading core/java/com/android/internal/content/PackageHelper.java +15 −2 Original line number Diff line number Diff line Loading @@ -261,8 +261,21 @@ public class PackageHelper { public static boolean fitsOnInternal(Context context, SessionParams params) throws IOException { final StorageManager storage = context.getSystemService(StorageManager.class); final UUID target = storage.getUuidForPath(Environment.getDataDirectory()); return (params.sizeBytes <= storage.getAllocatableBytes(target, translateAllocateFlags(params.installFlags))); final int flags = translateAllocateFlags(params.installFlags); final long allocateableBytes = storage.getAllocatableBytes(target, flags | StorageManager.FLAG_ALLOCATE_NON_CACHE_ONLY); // If we fit on internal storage without including freeable cache space, don't bother // checking to determine how much space is taken up by the cache. if (params.sizeBytes <= allocateableBytes) { return true; } final long cacheClearable = storage.getAllocatableBytes(target, flags | StorageManager.FLAG_ALLOCATE_CACHE_ONLY); return params.sizeBytes <= allocateableBytes + cacheClearable; } public static boolean fitsOnExternal(Context context, SessionParams params) { Loading services/core/java/com/android/server/StorageManagerService.java +27 −20 Original line number Diff line number Diff line Loading @@ -3208,29 +3208,29 @@ class StorageManagerService extends IStorageManager.Stub // should be kept in sync with getFreeBytes(). final File path = storage.findPathForUuid(volumeUuid); final long usable = path.getUsableSpace(); final long lowReserved = storage.getStorageLowBytes(path); final long fullReserved = storage.getStorageFullBytes(path); long usable = 0; long lowReserved = 0; long fullReserved = 0; long cacheClearable = 0; if (stats.isQuotaSupported(volumeUuid)) { if ((flags & StorageManager.FLAG_ALLOCATE_CACHE_ONLY) == 0) { usable = path.getUsableSpace(); lowReserved = storage.getStorageLowBytes(path); fullReserved = storage.getStorageFullBytes(path); } if ((flags & StorageManager.FLAG_ALLOCATE_NON_CACHE_ONLY) == 0 && stats.isQuotaSupported(volumeUuid)) { final long cacheTotal = stats.getCacheBytes(volumeUuid); final long cacheReserved = storage.getStorageCacheBytes(path, flags); final long cacheClearable = Math.max(0, cacheTotal - cacheReserved); cacheClearable = Math.max(0, cacheTotal - cacheReserved); } if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) { return Math.max(0, (usable + cacheClearable) - fullReserved); } else { return Math.max(0, (usable + cacheClearable) - lowReserved); } } else { // When we don't have fast quota information, we ignore cached // data and only consider unused bytes. if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) { return Math.max(0, usable - fullReserved); } else { return Math.max(0, usable - lowReserved); } } } catch (IOException e) { throw new ParcelableException(e); } finally { Loading @@ -3242,10 +3242,17 @@ class StorageManagerService extends IStorageManager.Stub public void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) { flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage); final long allocatableBytes = getAllocatableBytes(volumeUuid, flags, callingPackage); final long allocatableBytes = getAllocatableBytes(volumeUuid, flags | StorageManager.FLAG_ALLOCATE_NON_CACHE_ONLY, callingPackage); if (bytes > allocatableBytes) { // If we don't have room without taking cache into account, check to see if we'd have // room if we included freeable cache space. final long cacheClearable = getAllocatableBytes(volumeUuid, flags | StorageManager.FLAG_ALLOCATE_CACHE_ONLY, callingPackage); if (bytes > allocatableBytes + cacheClearable) { throw new ParcelableException(new IOException("Failed to allocate " + bytes + " because only " + allocatableBytes + " allocatable")); + " because only " + (allocatableBytes + cacheClearable) + " allocatable")); } } final StorageManager storage = mContext.getSystemService(StorageManager.class); Loading Loading
core/java/android/os/storage/StorageManager.java +20 −0 Original line number Diff line number Diff line Loading @@ -1987,11 +1987,31 @@ public class StorageManager { */ public static final int FLAG_ALLOCATE_DEFY_HALF_RESERVED = 1 << 2; /** * Flag indicating that a disk space check should not take into account * freeable cached space when determining allocatable space. * * Intended for use with {@link #getAllocatableBytes()}. * @hide */ public static final int FLAG_ALLOCATE_NON_CACHE_ONLY = 1 << 3; /** * Flag indicating that a disk space check should only return freeable * cached space when determining allocatable space. * * Intended for use with {@link #getAllocatableBytes()}. * @hide */ public static final int FLAG_ALLOCATE_CACHE_ONLY = 1 << 4; /** @hide */ @IntDef(flag = true, prefix = { "FLAG_ALLOCATE_" }, value = { FLAG_ALLOCATE_AGGRESSIVE, FLAG_ALLOCATE_DEFY_ALL_RESERVED, FLAG_ALLOCATE_DEFY_HALF_RESERVED, FLAG_ALLOCATE_NON_CACHE_ONLY, FLAG_ALLOCATE_CACHE_ONLY, }) @Retention(RetentionPolicy.SOURCE) public @interface AllocateFlags {} Loading
core/java/com/android/internal/content/PackageHelper.java +15 −2 Original line number Diff line number Diff line Loading @@ -261,8 +261,21 @@ public class PackageHelper { public static boolean fitsOnInternal(Context context, SessionParams params) throws IOException { final StorageManager storage = context.getSystemService(StorageManager.class); final UUID target = storage.getUuidForPath(Environment.getDataDirectory()); return (params.sizeBytes <= storage.getAllocatableBytes(target, translateAllocateFlags(params.installFlags))); final int flags = translateAllocateFlags(params.installFlags); final long allocateableBytes = storage.getAllocatableBytes(target, flags | StorageManager.FLAG_ALLOCATE_NON_CACHE_ONLY); // If we fit on internal storage without including freeable cache space, don't bother // checking to determine how much space is taken up by the cache. if (params.sizeBytes <= allocateableBytes) { return true; } final long cacheClearable = storage.getAllocatableBytes(target, flags | StorageManager.FLAG_ALLOCATE_CACHE_ONLY); return params.sizeBytes <= allocateableBytes + cacheClearable; } public static boolean fitsOnExternal(Context context, SessionParams params) { Loading
services/core/java/com/android/server/StorageManagerService.java +27 −20 Original line number Diff line number Diff line Loading @@ -3208,29 +3208,29 @@ class StorageManagerService extends IStorageManager.Stub // should be kept in sync with getFreeBytes(). final File path = storage.findPathForUuid(volumeUuid); final long usable = path.getUsableSpace(); final long lowReserved = storage.getStorageLowBytes(path); final long fullReserved = storage.getStorageFullBytes(path); long usable = 0; long lowReserved = 0; long fullReserved = 0; long cacheClearable = 0; if (stats.isQuotaSupported(volumeUuid)) { if ((flags & StorageManager.FLAG_ALLOCATE_CACHE_ONLY) == 0) { usable = path.getUsableSpace(); lowReserved = storage.getStorageLowBytes(path); fullReserved = storage.getStorageFullBytes(path); } if ((flags & StorageManager.FLAG_ALLOCATE_NON_CACHE_ONLY) == 0 && stats.isQuotaSupported(volumeUuid)) { final long cacheTotal = stats.getCacheBytes(volumeUuid); final long cacheReserved = storage.getStorageCacheBytes(path, flags); final long cacheClearable = Math.max(0, cacheTotal - cacheReserved); cacheClearable = Math.max(0, cacheTotal - cacheReserved); } if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) { return Math.max(0, (usable + cacheClearable) - fullReserved); } else { return Math.max(0, (usable + cacheClearable) - lowReserved); } } else { // When we don't have fast quota information, we ignore cached // data and only consider unused bytes. if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) { return Math.max(0, usable - fullReserved); } else { return Math.max(0, usable - lowReserved); } } } catch (IOException e) { throw new ParcelableException(e); } finally { Loading @@ -3242,10 +3242,17 @@ class StorageManagerService extends IStorageManager.Stub public void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) { flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage); final long allocatableBytes = getAllocatableBytes(volumeUuid, flags, callingPackage); final long allocatableBytes = getAllocatableBytes(volumeUuid, flags | StorageManager.FLAG_ALLOCATE_NON_CACHE_ONLY, callingPackage); if (bytes > allocatableBytes) { // If we don't have room without taking cache into account, check to see if we'd have // room if we included freeable cache space. final long cacheClearable = getAllocatableBytes(volumeUuid, flags | StorageManager.FLAG_ALLOCATE_CACHE_ONLY, callingPackage); if (bytes > allocatableBytes + cacheClearable) { throw new ParcelableException(new IOException("Failed to allocate " + bytes + " because only " + allocatableBytes + " allocatable")); + " because only " + (allocatableBytes + cacheClearable) + " allocatable")); } } final StorageManager storage = mContext.getSystemService(StorageManager.class); Loading