Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec8c01d7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Switch formatElapsedTime to use ICU's MeasureFormat"

parents 21be0d85 2ee90754
Loading
Loading
Loading
Loading
+31 −29
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.icu.text.MeasureFormat;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.net.NetworkUtils;
import android.text.BidiFormatter;
import android.text.TextUtils;
@@ -51,9 +54,13 @@ public final class Formatter {
        }
    }

    private static Locale localeFromContext(@NonNull Context context) {
        return context.getResources().getConfiguration().getLocales().get(0);
    }

    /* Wraps the source string in bidi formatting characters in RTL locales */
    private static String bidiWrap(@NonNull Context context, String source) {
        final Locale locale = context.getResources().getConfiguration().locale;
        final Locale locale = localeFromContext(context);
        if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) {
            return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source);
        } else {
@@ -197,7 +204,7 @@ public final class Formatter {

    /**
     * Returns elapsed time for the given millis, in the following format:
     * 1 day 5 hrs; will include at most two units, can go down to seconds precision.
     * 1 day, 5 hr; will include at most two units, can go down to seconds precision.
     * @param context the application context
     * @param millis the elapsed time in milli seconds
     * @return the formatted elapsed time
@@ -221,44 +228,38 @@ public final class Formatter {
        }
        int seconds = (int)secondsLong;

        final Locale locale = localeFromContext(context);
        final MeasureFormat measureFormat = MeasureFormat.getInstance(
                locale, MeasureFormat.FormatWidth.SHORT);
        if (days >= 2) {
            days += (hours+12)/24;
            return context.getString(com.android.internal.R.string.durationDays, days);
            return measureFormat.format(new Measure(days, MeasureUnit.DAY));
        } else if (days > 0) {
            if (hours == 1) {
                return context.getString(com.android.internal.R.string.durationDayHour, days, hours);
            }
            return context.getString(com.android.internal.R.string.durationDayHours, days, hours);
            return measureFormat.formatMeasures(
                    new Measure(days, MeasureUnit.DAY),
                    new Measure(hours, MeasureUnit.HOUR));
        } else if (hours >= 2) {
            hours += (minutes+30)/60;
            return context.getString(com.android.internal.R.string.durationHours, hours);
            return measureFormat.format(new Measure(hours, MeasureUnit.HOUR));
        } else if (hours > 0) {
            if (minutes == 1) {
                return context.getString(com.android.internal.R.string.durationHourMinute, hours,
                        minutes);
            }
            return context.getString(com.android.internal.R.string.durationHourMinutes, hours,
                    minutes);
            return measureFormat.formatMeasures(
                    new Measure(hours, MeasureUnit.HOUR),
                    new Measure(minutes, MeasureUnit.MINUTE));
        } else if (minutes >= 2) {
            minutes += (seconds+30)/60;
            return context.getString(com.android.internal.R.string.durationMinutes, minutes);
            return measureFormat.format(new Measure(minutes, MeasureUnit.MINUTE));
        } else if (minutes > 0) {
            if (seconds == 1) {
                return context.getString(com.android.internal.R.string.durationMinuteSecond, minutes,
                        seconds);
            }
            return context.getString(com.android.internal.R.string.durationMinuteSeconds, minutes,
                    seconds);
        } else if (seconds == 1) {
            return context.getString(com.android.internal.R.string.durationSecond, seconds);
            return measureFormat.formatMeasures(
                    new Measure(minutes, MeasureUnit.MINUTE),
                    new Measure(seconds, MeasureUnit.SECOND));
        } else {
            return context.getString(com.android.internal.R.string.durationSeconds, seconds);
            return measureFormat.format(new Measure(seconds, MeasureUnit.SECOND));
        }
    }

    /**
     * Returns elapsed time for the given millis, in the following format:
     * 1 day 5 hrs; will include at most two units, can go down to minutes precision.
     * 1 day, 5 hr; will include at most two units, can go down to minutes precision.
     * @param context the application context
     * @param millis the elapsed time in milli seconds
     * @return the formatted elapsed time
@@ -267,10 +268,11 @@ public final class Formatter {
    public static String formatShortElapsedTimeRoundingUpToMinutes(Context context, long millis) {
        long minutesRoundedUp = (millis + MILLIS_PER_MINUTE - 1) / MILLIS_PER_MINUTE;

        if (minutesRoundedUp == 0) {
            return context.getString(com.android.internal.R.string.durationMinutes, 0);
        } else if (minutesRoundedUp == 1) {
            return context.getString(com.android.internal.R.string.durationMinute, 1);
        if (minutesRoundedUp == 0 || minutesRoundedUp == 1) {
            final Locale locale = localeFromContext(context);
            final MeasureFormat measureFormat = MeasureFormat.getInstance(
                    locale, MeasureFormat.FormatWidth.SHORT);
            return measureFormat.format(new Measure(minutesRoundedUp, MeasureUnit.MINUTE));
        }

        return formatShortElapsedTime(context, minutesRoundedUp * MILLIS_PER_MINUTE);
+0 −42
Original line number Diff line number Diff line
@@ -38,48 +38,6 @@
         the placeholders. -->
    <string name="fileSizeSuffix"><xliff:g id="number" example="123">%1$s</xliff:g> <xliff:g id="unit" example="MB">%2$s</xliff:g></string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in days -->
    <string name="durationDays"><xliff:g id="days">%1$d</xliff:g> days</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one day with hours -->
    <string name="durationDayHours"><xliff:g id="days">%1$d</xliff:g> day
            <xliff:g id="hours">%2$d</xliff:g> hrs</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one day with one hours -->
    <string name="durationDayHour"><xliff:g id="days">%1$d</xliff:g> day
            <xliff:g id="hours">%2$d</xliff:g> hr</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in hours -->
    <string name="durationHours"><xliff:g id="hours">%1$d</xliff:g> hrs</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one hour with minutes -->
    <string name="durationHourMinutes"><xliff:g id="hours">%1$d</xliff:g> hr
            <xliff:g id="minutes">%2$d</xliff:g> mins</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one hour with one minute -->
    <string name="durationHourMinute"><xliff:g id="hours">%1$d</xliff:g> hr
            <xliff:g id="minutes">%2$d</xliff:g> min</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in minutes -->
    <string name="durationMinutes"><xliff:g id="minutes">%1$d</xliff:g> mins</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one minute -->
    <string name="durationMinute"><xliff:g id="minutes">%1$d</xliff:g> min</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one minute with seconds -->
    <string name="durationMinuteSeconds"><xliff:g id="minutes">%1$d</xliff:g> min
            <xliff:g id="seconds">%2$d</xliff:g> secs</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one minute with one second -->
    <string name="durationMinuteSecond"><xliff:g id="minutes">%1$d</xliff:g> min
            <xliff:g id="seconds">%2$d</xliff:g> sec</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration in seconds -->
    <string name="durationSeconds"><xliff:g id="seconds">%1$d</xliff:g> secs</string>

    <!-- [CHAR_LIMIT=10] Suffix added to signify duration of one second -->
    <string name="durationSecond"><xliff:g id="seconds">%1$d</xliff:g> sec</string>

    <!-- Used in Contacts for a field that has no label and in Note Pad
         for a note with no name. -->
    <string name="untitled">&lt;Untitled&gt;</string>
+0 −12
Original line number Diff line number Diff line
@@ -656,18 +656,6 @@
  <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
  <java-symbol type="string" name="display_manager_overlay_display_title" />
  <java-symbol type="string" name="double_tap_toast" />
  <java-symbol type="string" name="durationDays" />
  <java-symbol type="string" name="durationDayHours" />
  <java-symbol type="string" name="durationDayHour" />
  <java-symbol type="string" name="durationHours" />
  <java-symbol type="string" name="durationHourMinutes" />
  <java-symbol type="string" name="durationHourMinute" />
  <java-symbol type="string" name="durationMinutes" />
  <java-symbol type="string" name="durationMinute" />
  <java-symbol type="string" name="durationMinuteSeconds" />
  <java-symbol type="string" name="durationMinuteSecond" />
  <java-symbol type="string" name="durationSeconds" />
  <java-symbol type="string" name="durationSecond" />
  <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
  <java-symbol type="string" name="elapsed_time_short_format_mm_ss" />
  <java-symbol type="string" name="emailTypeCustom" />
+92 −2
Original line number Diff line number Diff line
@@ -26,12 +26,13 @@ import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.text.format.Formatter.BytesResult;

import java.util.Locale;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Locale;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class FormatterTest {
@@ -54,7 +55,7 @@ public class FormatterTest {

    @Test
    public void testFormatBytes() {
        setLocale(Locale.ENGLISH);
        setLocale(Locale.US);

        checkFormatBytes(0, true, "0", 0);
        checkFormatBytes(0, false, "0", 0);
@@ -99,6 +100,95 @@ public class FormatterTest {
        checkFormatBytes(9123000, false, "9,12", 9120000);
    }

    private static final long SECOND = 1000;
    private static final long MINUTE = 60 * SECOND;
    private static final long HOUR = 60 * MINUTE;
    private static final long DAY = 24 * HOUR;

    @Test
    public void testFormatShortElapsedTime() {
        setLocale(Locale.US);
        assertEquals("3 days", Formatter.formatShortElapsedTime(mContext, 2 * DAY + 12 * HOUR));
        assertEquals("2 days", Formatter.formatShortElapsedTime(mContext, 2 * DAY + 11 * HOUR));
        assertEquals("2 days", Formatter.formatShortElapsedTime(mContext, 2 * DAY));
        assertEquals("1 day, 23 hr",
                Formatter.formatShortElapsedTime(mContext, 1 * DAY + 23 * HOUR + 59 * MINUTE));
        assertEquals("1 day, 0 hr",
                Formatter.formatShortElapsedTime(mContext, 1 * DAY + 59 * MINUTE));
        assertEquals("1 day, 0 hr", Formatter.formatShortElapsedTime(mContext, 1 * DAY));
        assertEquals("24 hr", Formatter.formatShortElapsedTime(mContext, 23 * HOUR + 30 * MINUTE));
        assertEquals("3 hr", Formatter.formatShortElapsedTime(mContext, 2 * HOUR + 30 * MINUTE));
        assertEquals("2 hr", Formatter.formatShortElapsedTime(mContext, 2 * HOUR));
        assertEquals("1 hr, 0 min", Formatter.formatShortElapsedTime(mContext, 1 * HOUR));
        assertEquals("60 min",
                Formatter.formatShortElapsedTime(mContext, 59 * MINUTE + 30 * SECOND));
        assertEquals("59 min",
                Formatter.formatShortElapsedTime(mContext, 59 * MINUTE));
        assertEquals("3 min", Formatter.formatShortElapsedTime(mContext, 2 * MINUTE + 30 * SECOND));
        assertEquals("2 min", Formatter.formatShortElapsedTime(mContext, 2 * MINUTE));
        assertEquals("1 min, 59 sec",
                Formatter.formatShortElapsedTime(mContext, 1 * MINUTE + 59 * SECOND + 999));
        assertEquals("1 min, 0 sec", Formatter.formatShortElapsedTime(mContext, 1 * MINUTE));
        assertEquals("59 sec", Formatter.formatShortElapsedTime(mContext, 59 * SECOND + 999));
        assertEquals("1 sec", Formatter.formatShortElapsedTime(mContext, 1 * SECOND));
        assertEquals("0 sec", Formatter.formatShortElapsedTime(mContext, 1));
        assertEquals("0 sec", Formatter.formatShortElapsedTime(mContext, 0));

        // Make sure it works on different locales.
        setLocale(Locale.FRANCE);
        assertEquals("2 j", Formatter.formatShortElapsedTime(mContext, 2 * DAY));
    }

    @Test
    public void testFormatShortElapsedTimeRoundingUpToMinutes() {
        setLocale(Locale.US);
        assertEquals("3 days", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * DAY + 12 * HOUR));
        assertEquals("2 days", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * DAY + 11 * HOUR));
        assertEquals("2 days", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * DAY));
        assertEquals("1 day, 23 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * DAY + 23 * HOUR + 59 * MINUTE));
        assertEquals("1 day, 0 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * DAY + 59 * MINUTE));
        assertEquals("1 day, 0 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * DAY));
        assertEquals("24 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 23 * HOUR + 30 * MINUTE));
        assertEquals("3 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * HOUR + 30 * MINUTE));
        assertEquals("2 hr", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * HOUR));
        assertEquals("1 hr, 0 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * HOUR));
        assertEquals("1 hr, 0 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 59 * MINUTE + 30 * SECOND));
        assertEquals("59 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 59 * MINUTE));
        assertEquals("3 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * MINUTE + 30 * SECOND));
        assertEquals("2 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 2 * MINUTE));
        assertEquals("2 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * MINUTE + 59 * SECOND + 999));
        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * MINUTE));
        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 59 * SECOND + 999));
        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * SECOND));
        assertEquals("1 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1));
        assertEquals("0 min", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 0));

        // Make sure it works on different locales.
        setLocale(new Locale("ru", "RU"));
        assertEquals("1 мин", Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                mContext, 1 * SECOND));
    }

    private void checkFormatBytes(long bytes, boolean useShort,
            String expectedString, long expectedRounded) {
        BytesResult r = Formatter.formatBytes(mContext.getResources(), bytes,