From b521feaed410b6862baca9b42d5fd7c398e07b2f Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 15 Jun 2015 21:09:10 -0700 Subject: [PATCH] Update file size formatting. Per UX, default strings should have space between value and units resulting in "12.3 GB". Add a formatting variant that returns the various components for callers who want to build their own strings. For now there is only one mounted emulated volume at a time, and it's always the primary storage, so give it the default rootId to keep old Uris working. Change-Id: Ifcc72a91a6b397ee65dc92642153286186eb64ac --- core/java/android/net/TrafficStats.java | 2 + core/java/android/text/format/Formatter.java | 64 ++++++++++++++++------ core/res/res/values/strings.xml | 2 +- .../externalstorage/ExternalStorageProvider.java | 21 ++++--- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index ff3de2b6b4ab..bb08be2e3b25 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -53,6 +53,8 @@ public class TrafficStats { public static final long GB_IN_BYTES = MB_IN_BYTES * 1024; /** @hide */ public static final long TB_IN_BYTES = GB_IN_BYTES * 1024; + /** @hide */ + public static final long PB_IN_BYTES = TB_IN_BYTES * 1024; /** * Special UID value used when collecting {@link NetworkStatsHistory} for diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java index b467f5a8c67a..13a959e6fcdd 100644 --- a/core/java/android/text/format/Formatter.java +++ b/core/java/android/text/format/Formatter.java @@ -17,7 +17,9 @@ package android.text.format; import android.content.Context; +import android.content.res.Resources; import android.net.NetworkUtils; +import android.net.TrafficStats; /** * Utility class to aid in formatting common values that are not covered @@ -25,63 +27,88 @@ import android.net.NetworkUtils; */ public final class Formatter { + /** {@hide} */ + public static final int FLAG_SHORTER = 1 << 0; + /** {@hide} */ + public static final int FLAG_CALCULATE_ROUNDED = 1 << 1; + + /** {@hide} */ + public static class BytesResult { + public final String value; + public final String units; + public final long roundedBytes; + + public BytesResult(String value, String units, long roundedBytes) { + this.value = value; + this.units = units; + this.roundedBytes = roundedBytes; + } + } + /** * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc * * @param context Context to use to load the localized units - * @param number size value to be formatted + * @param sizeBytes size value to be formatted, in bytes * @return formatted string with the number */ - public static String formatFileSize(Context context, long number) { - return formatFileSize(context, number, false); + public static String formatFileSize(Context context, long sizeBytes) { + final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0); + return context.getString(com.android.internal.R.string.fileSizeSuffix, + res.value, res.units); } /** * Like {@link #formatFileSize}, but trying to generate shorter numbers * (showing fewer digits of precision). */ - public static String formatShortFileSize(Context context, long number) { - return formatFileSize(context, number, true); + public static String formatShortFileSize(Context context, long sizeBytes) { + final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER); + return context.getString(com.android.internal.R.string.fileSizeSuffix, + res.value, res.units); } - private static String formatFileSize(Context context, long number, boolean shorter) { - if (context == null) { - return ""; - } - - float result = number; + /** {@hide} */ + public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) { + float result = sizeBytes; int suffix = com.android.internal.R.string.byteShort; + long mult = 1; if (result > 900) { suffix = com.android.internal.R.string.kilobyteShort; + mult = TrafficStats.KB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = com.android.internal.R.string.megabyteShort; + mult = TrafficStats.MB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = com.android.internal.R.string.gigabyteShort; + mult = TrafficStats.GB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = com.android.internal.R.string.terabyteShort; + mult = TrafficStats.TB_IN_BYTES; result = result / 1024; } if (result > 900) { suffix = com.android.internal.R.string.petabyteShort; + mult = TrafficStats.PB_IN_BYTES; result = result / 1024; } String value; if (result < 1) { value = String.format("%.2f", result); } else if (result < 10) { - if (shorter) { + if ((flags & FLAG_SHORTER) != 0) { value = String.format("%.1f", result); } else { value = String.format("%.2f", result); } } else if (result < 100) { - if (shorter) { + if ((flags & FLAG_SHORTER) != 0) { value = String.format("%.0f", result); } else { value = String.format("%.2f", result); @@ -89,9 +116,14 @@ public final class Formatter { } else { value = String.format("%.0f", result); } - return context.getResources(). - getString(com.android.internal.R.string.fileSizeSuffix, - value, context.getString(suffix)); + final String units = res.getString(suffix); + final long roundedBytes; + if ((flags & FLAG_CALCULATE_ROUNDED) != 0) { + roundedBytes = (long) (Double.parseDouble(value) * mult); + } else { + roundedBytes = 0; + } + return new BytesResult(value, units, roundedBytes); } /** diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 2908cc5e7b0e..fb0455dcd354 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -34,7 +34,7 @@ to display a size in kilobytes, megabytes, or other size units. Some languages (like French) will want to add a space between the placeholders. --> - %1$s%2$s + %1$s %2$s %1$d days diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 73a723d0858e..4143e154e3ac 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -120,13 +120,20 @@ public class ExternalStorageProvider extends DocumentsProvider { if (!volume.isMountedReadable()) continue; final String rootId; - if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) { + final String title; + if (volume.getType() == VolumeInfo.TYPE_EMULATED) { + // We currently only support a single emulated volume mounted at + // a time, and it's always considered the primary rootId = ROOT_ID_PRIMARY_EMULATED; - } else if (volume.getType() == VolumeInfo.TYPE_EMULATED) { - final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume); - rootId = privateVol.getFsUuid(); + if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) { + title = getContext().getString(R.string.root_internal_storage); + } else { + final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume); + title = mStorageManager.getBestVolumeDescription(privateVol); + } } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC) { rootId = volume.getFsUuid(); + title = mStorageManager.getBestVolumeDescription(volume); } else { // Unsupported volume; ignore continue; @@ -148,11 +155,7 @@ public class ExternalStorageProvider extends DocumentsProvider { root.rootId = rootId; root.flags = Root.FLAG_SUPPORTS_CREATE | Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD; - if (ROOT_ID_PRIMARY_EMULATED.equals(rootId)) { - root.title = getContext().getString(R.string.root_internal_storage); - } else { - root.title = mStorageManager.getBestVolumeDescription(volume); - } + root.title = title; if (volume.getType() == VolumeInfo.TYPE_PUBLIC) { root.flags |= Root.FLAG_HAS_SETTINGS; } -- 2.11.0