Change reserved cache space as sum of cache quotas of all uids
Bug: 203650406 Test: atest frameworks/base/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest atest cts/tests/tests/os/src/android/os/storage/cts/StorageManagerTest#testComputeStorageCacheBytes Change-Id: I72710c89961ecc16b27ebb0647798f28e2e810ca
This commit is contained in:
@@ -341,6 +341,7 @@ package android.os {
|
||||
package android.os.storage {
|
||||
|
||||
public class StorageManager {
|
||||
method public long computeStorageCacheBytes(@NonNull java.io.File);
|
||||
method public void notifyAppIoBlocked(@NonNull java.util.UUID, int, int, int);
|
||||
method public void notifyAppIoResumed(@NonNull java.util.UUID, int, int, int);
|
||||
field public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 1; // 0x1
|
||||
|
||||
@@ -1976,6 +1976,7 @@ package android.os.storage {
|
||||
}
|
||||
|
||||
public class StorageManager {
|
||||
method public long computeStorageCacheBytes(@NonNull java.io.File);
|
||||
method @NonNull public static java.util.UUID convert(@NonNull String);
|
||||
method @NonNull public static String convert(@NonNull java.util.UUID);
|
||||
method public boolean isAppIoBlocked(@NonNull java.util.UUID, int, int, int);
|
||||
|
||||
@@ -1434,11 +1434,36 @@ public class StorageManager {
|
||||
throw new IllegalStateException("Missing primary storage");
|
||||
}
|
||||
|
||||
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 5;
|
||||
private static final long DEFAULT_THRESHOLD_MAX_BYTES = DataUnit.MEBIBYTES.toBytes(500);
|
||||
/**
|
||||
* Devices having above STORAGE_THRESHOLD_PERCENT_HIGH of total space free are considered to be
|
||||
* in high free space category.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int STORAGE_THRESHOLD_PERCENT_HIGH = 20;
|
||||
/**
|
||||
* Devices having below STORAGE_THRESHOLD_PERCENT_LOW of total space free are considered to be
|
||||
* in low free space category.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int STORAGE_THRESHOLD_PERCENT_LOW = 5;
|
||||
/**
|
||||
* For devices in high free space category, CACHE_RESERVE_PERCENT_HIGH percent of total space is
|
||||
* allocated for cache.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int CACHE_RESERVE_PERCENT_HIGH = 10;
|
||||
/**
|
||||
* For devices in low free space category, CACHE_RESERVE_PERCENT_LOW percent of total space is
|
||||
* allocated for cache.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int CACHE_RESERVE_PERCENT_LOW = 2;
|
||||
|
||||
private static final int DEFAULT_CACHE_PERCENTAGE = 10;
|
||||
private static final long DEFAULT_CACHE_MAX_BYTES = DataUnit.GIBIBYTES.toBytes(5);
|
||||
private static final long DEFAULT_THRESHOLD_MAX_BYTES = DataUnit.MEBIBYTES.toBytes(500);
|
||||
|
||||
private static final long DEFAULT_FULL_THRESHOLD_BYTES = DataUnit.MEBIBYTES.toBytes(1);
|
||||
|
||||
@@ -1462,7 +1487,7 @@ public class StorageManager {
|
||||
@UnsupportedAppUsage
|
||||
public long getStorageLowBytes(File path) {
|
||||
final long lowPercent = Settings.Global.getInt(mResolver,
|
||||
Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE, DEFAULT_THRESHOLD_PERCENTAGE);
|
||||
Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE, STORAGE_THRESHOLD_PERCENT_LOW);
|
||||
final long lowBytes = (path.getTotalSpace() * lowPercent) / 100;
|
||||
|
||||
final long maxLowBytes = Settings.Global.getLong(mResolver,
|
||||
@@ -1471,29 +1496,55 @@ public class StorageManager {
|
||||
return Math.min(lowBytes, maxLowBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the minimum number of bytes of storage on the device that could
|
||||
* be reserved for cached data depending on the device state which is then passed on
|
||||
* to getStorageCacheBytes.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@TestApi
|
||||
@SuppressLint("StreamFiles")
|
||||
public long computeStorageCacheBytes(@NonNull File path) {
|
||||
final long totalBytes = path.getTotalSpace();
|
||||
final long usableBytes = path.getUsableSpace();
|
||||
final long storageThresholdHighBytes = totalBytes * STORAGE_THRESHOLD_PERCENT_HIGH / 100;
|
||||
final long storageThresholdLowBytes = getStorageLowBytes(path);
|
||||
long result;
|
||||
if (usableBytes > storageThresholdHighBytes) {
|
||||
// If free space is >STORAGE_THRESHOLD_PERCENT_HIGH of total space,
|
||||
// reserve CACHE_RESERVE_PERCENT_HIGH of total space
|
||||
result = totalBytes * CACHE_RESERVE_PERCENT_HIGH / 100;
|
||||
} else if (usableBytes < storageThresholdLowBytes) {
|
||||
// If free space is <min(STORAGE_THRESHOLD_PERCENT_LOW of total space, 500MB),
|
||||
// reserve CACHE_RESERVE_PERCENT_LOW of total space
|
||||
result = totalBytes * CACHE_RESERVE_PERCENT_LOW / 100;
|
||||
} else {
|
||||
// Else, linearly interpolate the amount of space to reserve
|
||||
result = ((CACHE_RESERVE_PERCENT_HIGH - CACHE_RESERVE_PERCENT_LOW)
|
||||
* (usableBytes - storageThresholdHighBytes) + CACHE_RESERVE_PERCENT_HIGH
|
||||
* (storageThresholdHighBytes - storageThresholdLowBytes)) * totalBytes
|
||||
/ (100 * (storageThresholdHighBytes - storageThresholdLowBytes));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum number of bytes of storage on the device that should
|
||||
* be reserved for cached data.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public long getStorageCacheBytes(File path, @AllocateFlags int flags) {
|
||||
final long cachePercent = Settings.Global.getInt(mResolver,
|
||||
Settings.Global.SYS_STORAGE_CACHE_PERCENTAGE, DEFAULT_CACHE_PERCENTAGE);
|
||||
final long cacheBytes = (path.getTotalSpace() * cachePercent) / 100;
|
||||
|
||||
final long maxCacheBytes = Settings.Global.getLong(mResolver,
|
||||
Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES, DEFAULT_CACHE_MAX_BYTES);
|
||||
|
||||
final long result = Math.min(cacheBytes, maxCacheBytes);
|
||||
public long getStorageCacheBytes(@NonNull File path, @AllocateFlags int flags) {
|
||||
if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
|
||||
return 0;
|
||||
} else if ((flags & StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED) != 0) {
|
||||
return 0;
|
||||
} else if ((flags & StorageManager.FLAG_ALLOCATE_DEFY_HALF_RESERVED) != 0) {
|
||||
return result / 2;
|
||||
return computeStorageCacheBytes(path) / 2;
|
||||
} else {
|
||||
return result;
|
||||
return computeStorageCacheBytes(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package android.os.storage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.test.InstrumentationTestCase;
|
||||
@@ -23,6 +27,10 @@ import android.util.Log;
|
||||
|
||||
import libcore.io.Streams;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
@@ -39,6 +47,7 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
||||
|
||||
protected Context mContext = null;
|
||||
protected StorageManager mSm = null;
|
||||
@Mock private File mFile;
|
||||
private static String LOG_TAG = "StorageManagerBaseTest";
|
||||
protected static final long MAX_WAIT_TIME = 120*1000;
|
||||
protected static final long WAIT_TIME_INCR = 5*1000;
|
||||
@@ -121,11 +130,49 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
||||
*/
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = getInstrumentation().getContext();
|
||||
mSm = (StorageManager)mContext.getSystemService(android.content.Context.STORAGE_SERVICE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the space reserved for cache when system has high free space i.e. more than
|
||||
* StorageManager.STORAGE_THRESHOLD_PERCENT_HIGH of total space.
|
||||
*/
|
||||
@Test
|
||||
public void testGetStorageCacheBytesUnderHighStorage() throws Exception {
|
||||
when(mFile.getUsableSpace()).thenReturn(10000L);
|
||||
when(mFile.getTotalSpace()).thenReturn(15000L);
|
||||
long result = mSm.getStorageCacheBytes(mFile, 0);
|
||||
assertThat(result).isEqualTo(1500L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the space reserved for cache when system has low free space i.e. less than
|
||||
* StorageManager.STORAGE_THRESHOLD_PERCENT_LOW of total space.
|
||||
*/
|
||||
@Test
|
||||
public void testGetStorageCacheBytesUnderLowStorage() throws Exception {
|
||||
when(mFile.getUsableSpace()).thenReturn(10000L);
|
||||
when(mFile.getTotalSpace()).thenReturn(250000L);
|
||||
long result = mSm.getStorageCacheBytes(mFile, 0);
|
||||
assertThat(result).isEqualTo(5000L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the space reserved for cache when system has moderate free space i.e.more than
|
||||
* StorageManager.STORAGE_THRESHOLD_PERCENT_LOW of total space but less than
|
||||
* StorageManager.STORAGE_THRESHOLD_PERCENT_HIGH of total space.
|
||||
*/
|
||||
@Test
|
||||
public void testGetStorageCacheBytesUnderModerateStorage() throws Exception {
|
||||
when(mFile.getUsableSpace()).thenReturn(10000L);
|
||||
when(mFile.getTotalSpace()).thenReturn(100000L);
|
||||
long result = mSm.getStorageCacheBytes(mFile, 0);
|
||||
assertThat(result).isEqualTo(4666L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an OBB file (with the given name), into the app's standard files directory
|
||||
*
|
||||
@@ -526,4 +573,4 @@ public class StorageManagerBaseTest extends InstrumentationTestCase {
|
||||
doValidateIntContents(path + File.separator + "subdir2" + File.separator + "subdir2a"
|
||||
+ File.separator + "subdir2a1", "OneToOneThousandInts", 0, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user