From 9f2dc0527e755743c3b13fb27f68e5c425276106 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sun, 7 Jan 2018 16:47:31 -0700 Subject: Add DataUnit to clarify SI-vs-IEC units. Mirrors the design of TimeUnit and ChronoUnit which many developers are already familiar with, making it easy to pick up and use. Yes, this is an enum. Bug: 70915728 Test: bit FrameworksCoreTests:android.util.DataUnitTest Change-Id: Id0cfdac5c81ed89c3c9ece23c964acba4a4f8471 --- core/java/android/net/TrafficStats.java | 16 ++++++--- core/java/android/os/storage/StorageManager.java | 10 +++--- core/java/android/provider/DocumentsContract.java | 4 +-- core/java/android/util/DataUnit.java | 41 ++++++++++++++++++++++ .../coretests/src/android/util/DataUnitTest.java | 36 +++++++++++++++++++ .../com/android/server/StorageManagerService.java | 5 +-- .../storage/DeviceStorageMonitorService.java | 5 +-- .../android/server/usage/StorageStatsService.java | 3 +- 8 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 core/java/android/util/DataUnit.java create mode 100644 core/tests/coretests/src/android/util/DataUnitTest.java diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 196a3bc9c8d7..bda720bb6fdd 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -27,6 +27,7 @@ import android.content.Context; import android.media.MediaPlayer; import android.os.RemoteException; import android.os.ServiceManager; +import android.util.DataUnit; import com.android.server.NetworkManagementSocketTagger; @@ -56,15 +57,20 @@ public class TrafficStats { */ public final static int UNSUPPORTED = -1; - /** @hide */ + /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */ + @Deprecated public static final long KB_IN_BYTES = 1024; - /** @hide */ + /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */ + @Deprecated public static final long MB_IN_BYTES = KB_IN_BYTES * 1024; - /** @hide */ + /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */ + @Deprecated public static final long GB_IN_BYTES = MB_IN_BYTES * 1024; - /** @hide */ + /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */ + @Deprecated public static final long TB_IN_BYTES = GB_IN_BYTES * 1024; - /** @hide */ + /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */ + @Deprecated public static final long PB_IN_BYTES = TB_IN_BYTES * 1024; /** diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 68c242d9cd66..9de1223515f7 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -16,9 +16,6 @@ package android.os.storage; -import static android.net.TrafficStats.GB_IN_BYTES; -import static android.net.TrafficStats.MB_IN_BYTES; - import android.annotation.BytesLong; import android.annotation.IntDef; import android.annotation.NonNull; @@ -59,6 +56,7 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.text.TextUtils; +import android.util.DataUnit; import android.util.Log; import android.util.Pair; import android.util.Slog; @@ -1197,12 +1195,12 @@ public class StorageManager { } private static final int DEFAULT_THRESHOLD_PERCENTAGE = 5; - private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES; + private static final long DEFAULT_THRESHOLD_MAX_BYTES = DataUnit.MEBIBYTES.toBytes(500); private static final int DEFAULT_CACHE_PERCENTAGE = 10; - private static final long DEFAULT_CACHE_MAX_BYTES = 5 * GB_IN_BYTES; + private static final long DEFAULT_CACHE_MAX_BYTES = DataUnit.GIBIBYTES.toBytes(5); - private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES; + private static final long DEFAULT_FULL_THRESHOLD_BYTES = DataUnit.MEBIBYTES.toBytes(1); /** * Return the number of available bytes until the given path is considered diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 99fcdad4fc94..e7fd59e45fd0 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -16,7 +16,6 @@ package android.provider; -import static android.net.TrafficStats.KB_IN_BYTES; import static android.system.OsConstants.SEEK_SET; import static com.android.internal.util.Preconditions.checkArgument; @@ -51,6 +50,7 @@ import android.os.RemoteException; import android.os.storage.StorageVolume; import android.system.ErrnoException; import android.system.Os; +import android.util.DataUnit; import android.util.Log; import libcore.io.IoUtils; @@ -173,7 +173,7 @@ public final class DocumentsContract { /** * Buffer is large enough to rewind past any EXIF headers. */ - private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES); + private static final int THUMBNAIL_BUFFER_SIZE = (int) DataUnit.KIBIBYTES.toBytes(128); /** {@hide} */ public static final String EXTERNAL_STORAGE_PROVIDER_AUTHORITY = diff --git a/core/java/android/util/DataUnit.java b/core/java/android/util/DataUnit.java new file mode 100644 index 000000000000..3cc1bd899eeb --- /dev/null +++ b/core/java/android/util/DataUnit.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; + +/** + * Constants for common byte-related units. Note that both SI and IEC units are + * supported, and you'll need to pick the correct one for your use-case. + *

+ * This design is mirrored after {@link TimeUnit} and {@link ChronoUnit}. + * + * @hide + */ +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; } }, + 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; } }; + + public long toBytes(long v) { + throw new AbstractMethodError(); + } +} diff --git a/core/tests/coretests/src/android/util/DataUnitTest.java b/core/tests/coretests/src/android/util/DataUnitTest.java new file mode 100644 index 000000000000..4eae8b45e94b --- /dev/null +++ b/core/tests/coretests/src/android/util/DataUnitTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import android.support.test.filters.SmallTest; + +import junit.framework.TestCase; + +@SmallTest +public class DataUnitTest extends TestCase { + public void testSi() throws Exception { + assertEquals(12_000L, DataUnit.KILOBYTES.toBytes(12)); + assertEquals(12_000_000L, DataUnit.MEGABYTES.toBytes(12)); + assertEquals(12_000_000_000L, DataUnit.GIGABYTES.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)); + } +} diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 90822d1aaef1..8b13aa052da0 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -96,6 +96,7 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.AtomicFile; +import android.util.DataUnit; import android.util.Log; import android.util.Pair; import android.util.Slog; @@ -3508,8 +3509,8 @@ class StorageManagerService extends IStorageManager.Stub pw.print(") total size: "); pw.print(pair.second); pw.print(" ("); - pw.print((float) pair.second / TrafficStats.GB_IN_BYTES); - pw.println(" GB)"); + pw.print(DataUnit.MEBIBYTES.toBytes(pair.second)); + pw.println(" MiB)"); } pw.println("Force adoptable: " + mForceAdoptable); pw.println(); diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java index a35383f385f2..f7cc4432f9bc 100644 --- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java @@ -40,6 +40,7 @@ import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.text.format.DateUtils; import android.util.ArrayMap; +import android.util.DataUnit; import android.util.Slog; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; @@ -80,13 +81,13 @@ public class DeviceStorageMonitorService extends SystemService { private static final int MSG_CHECK = 1; - private static final long DEFAULT_LOG_DELTA_BYTES = 64 * TrafficStats.MB_IN_BYTES; + private static final long DEFAULT_LOG_DELTA_BYTES = DataUnit.MEBIBYTES.toBytes(64); private static final long DEFAULT_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS; // com.android.internal.R.string.low_internal_storage_view_text_no_boot // hard codes 250MB in the message as the storage space required for the // boot image. - private static final long BOOT_IMAGE_STORAGE_REQUIREMENT = 250 * TrafficStats.MB_IN_BYTES; + private static final long BOOT_IMAGE_STORAGE_REQUIREMENT = DataUnit.MEBIBYTES.toBytes(250); private NotificationManager mNotifManager; diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java index 82f800128beb..d598649926ad 100644 --- a/services/usage/java/com/android/server/usage/StorageStatsService.java +++ b/services/usage/java/com/android/server/usage/StorageStatsService.java @@ -49,6 +49,7 @@ import android.os.storage.VolumeInfo; import android.provider.Settings; import android.text.format.DateUtils; import android.util.ArrayMap; +import android.util.DataUnit; import android.util.Slog; import android.util.SparseLongArray; @@ -73,7 +74,7 @@ public class StorageStatsService extends IStorageStatsManager.Stub { private static final String PROP_VERIFY_STORAGE = "fw.verify_storage"; private static final long DELAY_IN_MILLIS = 30 * DateUtils.SECOND_IN_MILLIS; - private static final long DEFAULT_QUOTA = 64 * TrafficStats.MB_IN_BYTES; + private static final long DEFAULT_QUOTA = DataUnit.MEBIBYTES.toBytes(64); public static class Lifecycle extends SystemService { private StorageStatsService mService; -- cgit v1.2.3-59-g8ed1b