From 7a5cbaf752181713cc5fc081cd180b94c73fcc63 Mon Sep 17 00:00:00 2001 From: alukin Date: Mon, 6 Mar 2023 21:15:18 +0000 Subject: [PATCH] Fix the storage size display values for GiB measurements Some devices are still using GiB measurements over GB. Fixing the incorrect storage size round for them which could show more memory than it should. Bug: 268571529 Test: atest FileUtilsTest Change-Id: I6bdea4e028c2755a6979c3e5a563495aba32e785 Merged-In: I6bdea4e028c2755a6979c3e5a563495aba32e785 (cherry picked from commit bd0d590325a4282330440a2da1a5df8686c58ba9) --- core/java/android/os/FileUtils.java | 20 ++++-- core/java/android/util/DataUnit.java | 4 +- .../src/android/os/FileUtilsTest.java | 61 ++++++++++++------- .../src/android/util/DataUnitTest.java | 2 + 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index b478a37984e03..af09a06627955 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -1295,19 +1295,31 @@ public final class FileUtils { * value, such as 256MB or 32GB. This avoids showing weird values like * "29.5GB" in UI. * + * Some storage devices are still using GiB (powers of 1024) over + * GB (powers of 1000) measurements and this method takes it into account. + * + * Round ranges: + * ... + * [256 GiB + 1; 512 GiB] -> 512 GB + * [512 GiB + 1; 1 TiB] -> 1 TB + * [1 TiB + 1; 2 TiB] -> 2 TB + * etc + * * @hide */ public static long roundStorageSize(long size) { long val = 1; - long pow = 1; - while ((val * pow) < size) { + long kiloPow = 1; + long kibiPow = 1; + while ((val * kibiPow) < size) { val <<= 1; if (val > 512) { val = 1; - pow *= 1000; + kibiPow *= 1024; + kiloPow *= 1000; } } - return val * pow; + return val * kiloPow; } private static long toBytes(long value, String unit) { diff --git a/core/java/android/util/DataUnit.java b/core/java/android/util/DataUnit.java index cf045b8aec065..cc33af32ba934 100644 --- a/core/java/android/util/DataUnit.java +++ b/core/java/android/util/DataUnit.java @@ -36,9 +36,11 @@ public enum DataUnit { KILOBYTES { @Override public long toBytes(long v) { return v * 1_000; } }, MEGABYTES { @Override public long toBytes(long v) { return v * 1_000_000; } }, GIGABYTES { @Override public long toBytes(long v) { return v * 1_000_000_000; } }, + TERABYTES { @Override public long toBytes(long v) { return v * 1_000_000_000_000L; } }, KIBIBYTES { @Override public long toBytes(long v) { return v * 1_024; } }, MEBIBYTES { @Override public long toBytes(long v) { return v * 1_048_576; } }, - GIBIBYTES { @Override public long toBytes(long v) { return v * 1_073_741_824; } }; + GIBIBYTES { @Override public long toBytes(long v) { return v * 1_073_741_824; } }, + TEBIBYTES { @Override public long toBytes(long v) { return v * 1_099_511_627_776L; } }; public long toBytes(long v) { throw new AbstractMethodError(); diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java index 91fbe00341337..394ff0ae9a2e4 100644 --- a/core/tests/coretests/src/android/os/FileUtilsTest.java +++ b/core/tests/coretests/src/android/os/FileUtilsTest.java @@ -54,6 +54,7 @@ import static org.junit.Assert.fail; import android.content.Context; import android.os.FileUtils.MemoryPipe; import android.provider.DocumentsContract.Document; +import android.util.DataUnit; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -504,31 +505,45 @@ public class FileUtilsTest { @Test public void testRoundStorageSize() throws Exception { - final long M128 = 128000000L; - final long M256 = 256000000L; - final long M512 = 512000000L; - final long G1 = 1000000000L; - final long G2 = 2000000000L; - final long G16 = 16000000000L; - final long G32 = 32000000000L; - final long G64 = 64000000000L; + final long GB1 = DataUnit.GIGABYTES.toBytes(1); + final long GiB1 = DataUnit.GIBIBYTES.toBytes(1); + final long GB2 = DataUnit.GIGABYTES.toBytes(2); + final long GiB2 = DataUnit.GIBIBYTES.toBytes(2); + final long GiB128 = DataUnit.GIBIBYTES.toBytes(128); + final long GB256 = DataUnit.GIGABYTES.toBytes(256); + final long GiB256 = DataUnit.GIBIBYTES.toBytes(256); + final long GB512 = DataUnit.GIGABYTES.toBytes(512); + final long GiB512 = DataUnit.GIBIBYTES.toBytes(512); + final long TB1 = DataUnit.TERABYTES.toBytes(1); + final long TiB1 = DataUnit.TEBIBYTES.toBytes(1); + final long TB2 = DataUnit.TERABYTES.toBytes(2); + final long TiB2 = DataUnit.TEBIBYTES.toBytes(2); + final long TB4 = DataUnit.TERABYTES.toBytes(4); + final long TiB4 = DataUnit.TEBIBYTES.toBytes(4); + final long TB8 = DataUnit.TERABYTES.toBytes(8); + final long TiB8 = DataUnit.TEBIBYTES.toBytes(8); - assertEquals(M128, roundStorageSize(M128)); - assertEquals(M256, roundStorageSize(M128 + 1)); - assertEquals(M256, roundStorageSize(M256 - 1)); - assertEquals(M256, roundStorageSize(M256)); - assertEquals(M512, roundStorageSize(M256 + 1)); - assertEquals(M512, roundStorageSize(M512 - 1)); - assertEquals(M512, roundStorageSize(M512)); - assertEquals(G1, roundStorageSize(M512 + 1)); - assertEquals(G1, roundStorageSize(G1)); - assertEquals(G2, roundStorageSize(G1 + 1)); + assertEquals(GB1, roundStorageSize(GB1 - 1)); + assertEquals(GB1, roundStorageSize(GB1)); + assertEquals(GB1, roundStorageSize(GB1 + 1)); + assertEquals(GB1, roundStorageSize(GiB1 - 1)); + assertEquals(GB1, roundStorageSize(GiB1)); + assertEquals(GB2, roundStorageSize(GiB1 + 1)); + assertEquals(GB2, roundStorageSize(GiB2)); - assertEquals(G16, roundStorageSize(G16)); - assertEquals(G32, roundStorageSize(G16 + 1)); - assertEquals(G32, roundStorageSize(G32 - 1)); - assertEquals(G32, roundStorageSize(G32)); - assertEquals(G64, roundStorageSize(G32 + 1)); + assertEquals(GB256, roundStorageSize(GiB128 + 1)); + assertEquals(GB256, roundStorageSize(GiB256)); + assertEquals(GB512, roundStorageSize(GiB256 + 1)); + assertEquals(GB512, roundStorageSize(GiB512)); + assertEquals(TB1, roundStorageSize(GiB512 + 1)); + assertEquals(TB1, roundStorageSize(TiB1)); + assertEquals(TB2, roundStorageSize(TiB1 + 1)); + assertEquals(TB2, roundStorageSize(TiB2)); + assertEquals(TB4, roundStorageSize(TiB2 + 1)); + assertEquals(TB4, roundStorageSize(TiB4)); + assertEquals(TB8, roundStorageSize(TiB4 + 1)); + assertEquals(TB8, roundStorageSize(TiB8)); + assertEquals(TB1, roundStorageSize(1013077688320L)); // b/268571529 } @Test diff --git a/core/tests/coretests/src/android/util/DataUnitTest.java b/core/tests/coretests/src/android/util/DataUnitTest.java index ec296b76c3740..034cbddc0144b 100644 --- a/core/tests/coretests/src/android/util/DataUnitTest.java +++ b/core/tests/coretests/src/android/util/DataUnitTest.java @@ -26,11 +26,13 @@ public class DataUnitTest extends TestCase { assertEquals(12_000L, DataUnit.KILOBYTES.toBytes(12)); assertEquals(12_000_000L, DataUnit.MEGABYTES.toBytes(12)); assertEquals(12_000_000_000L, DataUnit.GIGABYTES.toBytes(12)); + assertEquals(12_000_000_000_000L, DataUnit.TERABYTES.toBytes(12)); } public void testIec() throws Exception { assertEquals(12_288L, DataUnit.KIBIBYTES.toBytes(12)); assertEquals(12_582_912L, DataUnit.MEBIBYTES.toBytes(12)); assertEquals(12_884_901_888L, DataUnit.GIBIBYTES.toBytes(12)); + assertEquals(13_194_139_533_312L, DataUnit.TEBIBYTES.toBytes(12)); } }