Loading core/java/android/os/FileUtils.java +16 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading core/java/android/util/DataUnit.java +3 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading core/tests/coretests/src/android/os/FileUtilsTest.java +40 −25 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; 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(G16, roundStorageSize(G16)); assertEquals(G32, roundStorageSize(G16 + 1)); assertEquals(G32, roundStorageSize(G32 - 1)); assertEquals(G32, roundStorageSize(G32)); assertEquals(G64, roundStorageSize(G32 + 1)); 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(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(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 Loading core/tests/coretests/src/android/util/DataUnitTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -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)); } } Loading
core/java/android/os/FileUtils.java +16 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading
core/java/android/util/DataUnit.java +3 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading
core/tests/coretests/src/android/os/FileUtilsTest.java +40 −25 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; 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(G16, roundStorageSize(G16)); assertEquals(G32, roundStorageSize(G16 + 1)); assertEquals(G32, roundStorageSize(G32 - 1)); assertEquals(G32, roundStorageSize(G32)); assertEquals(G64, roundStorageSize(G32 + 1)); 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(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(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 Loading
core/tests/coretests/src/android/util/DataUnitTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -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)); } }