Merge "Revert "Don't use framework strings for formatting file sizes""
diff --git a/res/layout/data_usage_bytes_editor.xml b/res/layout/data_usage_bytes_editor.xml
index af2d59b..2878c3e 100644
--- a/res/layout/data_usage_bytes_editor.xml
+++ b/res/layout/data_usage_bytes_editor.xml
@@ -37,6 +37,7 @@
         android:id="@+id/size_spinner"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical" />
+        android:layout_gravity="center_vertical"
+        android:entries="@array/bytes_picker_sizes" />
 
 </LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a809c78..3dc342b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8505,6 +8505,11 @@
     <!-- Text for the setting on whether you can type text into notifications without unlocking the device. -->
     <string name="lockscreen_remote_input">If device is locked, prevent typing replies or other text in notifications</string>
 
+    <string-array name="bytes_picker_sizes" translatable="false">
+        <item>@*android:string/megabyteShort</item>
+        <item>@*android:string/gigabyteShort</item>
+    </string-array>
+
     <!-- [CHAR LIMIT=30] Label for setting to control the default spell checker -->
     <string name="default_spell_checker">Default spell checker</string>
 
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index d0114e3..3dcf935 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.icu.util.MeasureUnit;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.util.AttributeSet;
@@ -52,7 +51,7 @@
                 FileSizeFormatter.formatFileSize(
                         getContext(),
                         size,
-                        MeasureUnit.GIGABYTE,
+                        getGigabyteSuffix(getContext().getResources()),
                         FileSizeFormatter.GIGABYTE_IN_BYTES));
         if (total == 0) {
             mProgressPercent = 0;
@@ -76,4 +75,8 @@
         updateProgressBar();
         super.onBindViewHolder(view);
     }
+
+    private static int getGigabyteSuffix(Resources res) {
+        return res.getIdentifier("gigabyteShort", "string", "android");
+    }
 }
diff --git a/src/com/android/settings/utils/FileSizeFormatter.java b/src/com/android/settings/utils/FileSizeFormatter.java
index c0d360f..e56388a 100644
--- a/src/com/android/settings/utils/FileSizeFormatter.java
+++ b/src/com/android/settings/utils/FileSizeFormatter.java
@@ -16,22 +16,11 @@
 
 package com.android.settings.utils;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Resources;
-import android.icu.text.DecimalFormat;
-import android.icu.text.MeasureFormat;
-import android.icu.text.NumberFormat;
-import android.icu.util.Measure;
-import android.icu.util.MeasureUnit;
 import android.text.BidiFormatter;
-import android.text.TextUtils;
 import android.text.format.Formatter;
-import android.view.View;
-
-import java.math.BigDecimal;
-import java.util.Locale;
 
 /**
  * Utility class to aid in formatting file sizes always with the same unit. This is modified from
@@ -42,61 +31,6 @@
     public static final long MEGABYTE_IN_BYTES = KILOBYTE_IN_BYTES * 1000;
     public static final long GIGABYTE_IN_BYTES = MEGABYTE_IN_BYTES * 1000;
 
-    private static class RoundedBytesResult {
-        public final float value;
-        public final MeasureUnit units;
-        public final int fractionDigits;
-        public final long roundedBytes;
-
-        public RoundedBytesResult(
-                float value, MeasureUnit units, int fractionDigits, long roundedBytes) {
-            this.value = value;
-            this.units = units;
-            this.fractionDigits = fractionDigits;
-            this.roundedBytes = roundedBytes;
-        }
-    }
-
-    private static Locale localeFromContext(@NonNull Context context) {
-        return context.getResources().getConfiguration().locale;
-    }
-
-    private static String bidiWrap(@NonNull Context context, String source) {
-        final Locale locale = localeFromContext(context);
-        if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) {
-            return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source);
-        } else {
-            return source;
-        }
-    }
-
-    private static NumberFormat getNumberFormatter(Locale locale, int fractionDigits) {
-        final NumberFormat numberFormatter = NumberFormat.getInstance(locale);
-        numberFormatter.setMinimumFractionDigits(fractionDigits);
-        numberFormatter.setMaximumFractionDigits(fractionDigits);
-        numberFormatter.setGroupingUsed(false);
-        if (numberFormatter instanceof DecimalFormat) {
-            // We do this only for DecimalFormat, since in the general NumberFormat case, calling
-            // setRoundingMode may throw an exception.
-            numberFormatter.setRoundingMode(BigDecimal.ROUND_HALF_UP);
-        }
-        return numberFormatter;
-    }
-
-    private static String formatMeasureShort(Locale locale, NumberFormat numberFormatter,
-            float value, MeasureUnit units) {
-        final MeasureFormat measureFormatter = MeasureFormat.getInstance(
-                locale, MeasureFormat.FormatWidth.SHORT, numberFormatter);
-        return measureFormatter.format(new Measure(value, units));
-    }
-
-    private static String formatRoundedBytesResult(
-            @NonNull Context context, @NonNull RoundedBytesResult input) {
-        final Locale locale = localeFromContext(context);
-        final NumberFormat numberFormatter = getNumberFormatter(locale, input.fractionDigits);
-        return formatMeasureShort(locale, numberFormatter, input.value, input.units);
-    }
-
     /**
      * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc.
      *
@@ -113,17 +47,23 @@
      *
      * @param context Context to use to load the localized units
      * @param sizeBytes size value to be formatted, in bytes
-     * @param unit The unit used for formatting.
-     * @param mult Amount of bytes in the unit.
-     * @return formatted string with the number
+     * @param suffix String id for the unit suffix.
+     * @param mult Amount of bytes in the unit. * @return formatted string with the number
      */
     public static String formatFileSize(
-            @Nullable Context context, long sizeBytes, MeasureUnit unit, long mult) {
+            @Nullable Context context, long sizeBytes, int suffix, long mult) {
         if (context == null) {
             return "";
         }
-        final RoundedBytesResult res = formatBytes(sizeBytes, unit, mult);
-        return bidiWrap(context, formatRoundedBytesResult(context, res));
+        final Formatter.BytesResult res =
+                formatBytes(context.getResources(), sizeBytes, suffix, mult);
+        return BidiFormatter.getInstance()
+                .unicodeWrap(context.getString(getFileSizeSuffix(context), res.value, res.units));
+    }
+
+    private static int getFileSizeSuffix(Context context) {
+        final Resources res = context.getResources();
+        return res.getIdentifier("fileSizeSuffix", "string", "android");
     }
 
     /**
@@ -136,8 +76,8 @@
      * @param suffix String id for the unit suffix.
      * @param mult Amount of bytes in the unit.
      */
-    private static RoundedBytesResult formatBytes(
-            long sizeBytes, MeasureUnit unit, long mult) {
+    private static Formatter.BytesResult formatBytes(
+            Resources res, long sizeBytes, int suffix, long mult) {
         final boolean isNegative = (sizeBytes < 0);
         float result = isNegative ? -sizeBytes : sizeBytes;
         result = result / mult;
@@ -145,29 +85,32 @@
         // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
         // floating point errors.
         final int roundFactor;
-        final int roundDigits;
+        final String roundFormat;
         if (mult == 1) {
             roundFactor = 1;
-            roundDigits = 0;
+            roundFormat = "%.0f";
         } else if (result < 1) {
             roundFactor = 100;
-            roundDigits = 2;
+            roundFormat = "%.2f";
         } else if (result < 10) {
             roundFactor = 10;
-            roundDigits = 1;
+            roundFormat = "%.1f";
         } else { // 10 <= result < 100
             roundFactor = 1;
-            roundDigits = 0;
+            roundFormat = "%.0f";
         }
 
         if (isNegative) {
             result = -result;
         }
+        final String roundedString = String.format(roundFormat, result);
 
         // Note this might overflow if abs(result) >= Long.MAX_VALUE / 100, but that's like 80PB so
         // it's okay (for now)...
         final long roundedBytes = (((long) Math.round(result * roundFactor)) * mult / roundFactor);
 
-        return new RoundedBytesResult(result, unit, roundDigits, roundedBytes);
+        final String units = res.getString(suffix);
+
+        return new Formatter.BytesResult(roundedString, units, roundedBytes);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index b20823b..1a3139d 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -92,6 +92,8 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        SettingsShadowResources.overrideResource("android:string/fileSizeSuffix", "%1$s %2$s");
+        SettingsShadowResources.overrideResource("android:string/gigabyteShort", "GB");
         when(mFragment.getActivity()).thenReturn(mActivity);
         when(mFragment.getFragmentManager()).thenReturn(mFragmentManager);
         when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
diff --git a/tests/unit/README b/tests/unit/README
index 2544ea5..5184b07 100644
--- a/tests/unit/README
+++ b/tests/unit/README
@@ -1,8 +1,8 @@
 To build the tests you can use the following command at the root of your android source tree
-$ make -j SettingsUnitTests
+$ make SettingsUnitTests
 
 The test apk then needs to be installed onto your test device via for example
-$ adb install -r ${ANDROID_PRODUCT_OUT}/data/app/SettingsUnitTests/SettingsUnitTests.apk
+$ adb install -r out/target/product/shamu/data/app/SettingsUnitTests/SettingsUnitTests.apk
 
 To run all tests:
 $ adb shell am instrument -w com.android.settings.tests.unit/android.support.test.runner.AndroidJUnitRunner
diff --git a/tests/unit/src/com/android/settings/utils/FileSizeFormatterTest.java b/tests/unit/src/com/android/settings/utils/FileSizeFormatterTest.java
index 41b236c..c5b050a 100644
--- a/tests/unit/src/com/android/settings/utils/FileSizeFormatterTest.java
+++ b/tests/unit/src/com/android/settings/utils/FileSizeFormatterTest.java
@@ -22,7 +22,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
-import android.icu.util.MeasureUnit;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -47,7 +46,7 @@
                         FileSizeFormatter.formatFileSize(
                                 mContext,
                                 0 /* size */,
-                                MeasureUnit.GIGABYTE,
+                                com.android.internal.R.string.gigabyteShort,
                                 GIGABYTE_IN_BYTES))
                 .isEqualTo("0.00 GB");
     }
@@ -58,7 +57,7 @@
                         FileSizeFormatter.formatFileSize(
                                 mContext,
                                 MEGABYTE_IN_BYTES * 11 /* size */,
-                                MeasureUnit.GIGABYTE,
+                                com.android.internal.R.string.gigabyteShort,
                                 GIGABYTE_IN_BYTES))
                 .isEqualTo("0.01 GB");
     }
@@ -69,7 +68,7 @@
                         FileSizeFormatter.formatFileSize(
                                 mContext,
                                 MEGABYTE_IN_BYTES * 155 /* size */,
-                                MeasureUnit.GIGABYTE,
+                                com.android.internal.R.string.gigabyteShort,
                                 GIGABYTE_IN_BYTES))
                 .isEqualTo("0.16 GB");
     }
@@ -80,7 +79,7 @@
                         FileSizeFormatter.formatFileSize(
                                 mContext,
                                 MEGABYTE_IN_BYTES * 1551 /* size */,
-                                MeasureUnit.GIGABYTE,
+                                com.android.internal.R.string.gigabyteShort,
                                 GIGABYTE_IN_BYTES))
                 .isEqualTo("1.6 GB");
     }
@@ -92,7 +91,7 @@
                         FileSizeFormatter.formatFileSize(
                                 mContext,
                                 GIGABYTE_IN_BYTES * 15 + MEGABYTE_IN_BYTES * 50 /* size */,
-                                MeasureUnit.GIGABYTE,
+                                com.android.internal.R.string.gigabyteShort,
                                 GIGABYTE_IN_BYTES))
                 .isEqualTo("15 GB");
     }
@@ -103,7 +102,7 @@
                         FileSizeFormatter.formatFileSize(
                                 mContext,
                                 MEGABYTE_IN_BYTES * -155 /* size */,
-                                MeasureUnit.GIGABYTE,
+                                com.android.internal.R.string.gigabyteShort,
                                 GIGABYTE_IN_BYTES))
                 .isEqualTo("-0.16 GB");
     }