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

Commit 628bb61c authored by David Ogutu's avatar David Ogutu
Browse files

Fix TimePicker separator l10n issue.

This was surfacing in the android clock with certain locales e.g. fr_CA.
Fixed for all unqiue locale patterns.

Bug: 71572309
Test: manual - changed locale to Fr_CA and made sure clock seperator WAI
Test: atest CtsWidgetTestCases:TextViewTest CtsWidgetTestCases:EditTextTest CtsWidgetTestCases:TextViewFadingEdgeTest FrameworksCoreTests:TextViewFallbackLineSpacingTest FrameworksCoreTests:TextViewTest

Change-Id: Ie43bf9428e8c5ef2fe2e9545cb5a6dada25d6e52
parent 86356ec7
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -431,7 +431,7 @@ public class DateFormat {
            int c = s.charAt(i);

            if (c == QUOTE) {
                count = appendQuotedText(s, i, len);
                count = appendQuotedText(s, i);
                len = s.length();
                continue;
            }
@@ -574,36 +574,48 @@ public class DateFormat {
                            : String.format(Locale.getDefault(), "%d", year);
    }

    private static int appendQuotedText(SpannableStringBuilder s, int i, int len) {
        if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
            s.delete(i, i + 1);

    /**
     * Strips quotation marks from the {@code formatString} and appends the result back to the
     * {@code formatString}.
     *
     * @param formatString the format string, as described in
     *                     {@link android.text.format.DateFormat}, to be modified
     * @param index        index of the first quote
     * @return the length of the quoted text that was appended.
     * @hide
     */
    public static int appendQuotedText(SpannableStringBuilder formatString, int index) {
        int length = formatString.length();
        if (index + 1 < length && formatString.charAt(index + 1) == QUOTE) {
            formatString.delete(index, index + 1);
            return 1;
        }

        int count = 0;

        // delete leading quote
        s.delete(i, i + 1);
        len--;
        formatString.delete(index, index + 1);
        length--;

        while (i < len) {
            char c = s.charAt(i);
        while (index < length) {
            char c = formatString.charAt(index);

            if (c == QUOTE) {
                //  QUOTEQUOTE -> QUOTE
                if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
                if (index + 1 < length && formatString.charAt(index + 1) == QUOTE) {

                    s.delete(i, i + 1);
                    len--;
                    formatString.delete(index, index + 1);
                    length--;
                    count++;
                    i++;
                    index++;
                } else {
                    //  Closing QUOTE ends quoted text copying
                    s.delete(i, i + 1);
                    formatString.delete(index, index + 1);
                    break;
                }
            } else {
                i++;
                index++;
                count++;
            }
        }
+47 −10
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import com.android.internal.R;
import com.android.internal.widget.NumericTextView;
import com.android.internal.widget.NumericTextView.OnValueChangedListener;


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Calendar;
@@ -804,20 +805,56 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate {
    private void updateHeaderSeparator() {
        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
                (mIs24Hour) ? "Hm" : "hm");
        final String separatorText;
        // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats
        final char[] hourFormats = {'H', 'h', 'K', 'k'};
        int hIndex = lastIndexOfAny(bestDateTimePattern, hourFormats);
        if (hIndex == -1) {
            // Default case
            separatorText = ":";
        } else {
            separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1));
        }
        final String separatorText = getHourMinSeparatorFromPattern(bestDateTimePattern);
        mSeparatorView.setText(separatorText);
        mTextInputPickerView.updateSeparator(separatorText);
    }

    /**
     * This helper method extracts the time separator from the {@code datetimePattern}.
     *
     * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":".
     *
     * See http://unicode.org/cldr/trac/browser/trunk/common/main
     *
     * @return Separator string. This is the character or set of quoted characters just after the
     * hour marker in {@code dateTimePattern}. Returns a colon (:) if it can't locate the
     * separator.
     *
     * @hide
     */
    private static String getHourMinSeparatorFromPattern(String dateTimePattern) {
        final String defaultSeparator = ":";
        boolean foundHourPattern = false;
        for (int i = 0; i < dateTimePattern.length(); i++) {
            switch (dateTimePattern.charAt(i)) {
                // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats.
                case 'H':
                case 'h':
                case 'K':
                case 'k':
                    foundHourPattern = true;
                    continue;
                case ' ': // skip spaces
                    continue;
                case '\'':
                    if (!foundHourPattern) {
                        continue;
                    }
                    SpannableStringBuilder quotedSubstring = new SpannableStringBuilder(
                            dateTimePattern.substring(i));
                    int quotedTextLength = DateFormat.appendQuotedText(quotedSubstring, 0);
                    return quotedSubstring.subSequence(0, quotedTextLength).toString();
                default:
                    if (!foundHourPattern) {
                        continue;
                    }
                    return Character.toString(dateTimePattern.charAt(i));
            }
        }
        return defaultSeparator;
    }

    static private int lastIndexOfAny(String str, char[] any) {
        final int lengthAny = any.length;
        if (lengthAny > 0) {