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

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

Merge "Use text input for various internationalized listeners" into oc-dev

parents 6343bd8f 889c6503
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.text.InputType;
import android.view.KeyEvent;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -37,8 +38,11 @@ import java.util.Locale;
public class DateKeyListener extends NumberKeyListener
{
    public int getInputType() {
        return InputType.TYPE_CLASS_DATETIME
                | InputType.TYPE_DATETIME_VARIATION_DATE;
        if (mNeedsAdvancedInput) {
            return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
        } else {
            return InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_DATE;
        }
    }

    @Override
@@ -65,7 +69,13 @@ public class DateKeyListener extends NumberKeyListener
        final boolean success = NumberKeyListener.addDigits(chars, locale)
                                && NumberKeyListener.addFormatCharsFromSkeletons(
                                        chars, locale, SKELETONS, SYMBOLS_TO_IGNORE);
        mCharacters = success ? NumberKeyListener.collectionToArray(chars) : CHARACTERS;
        if (success) {
            mCharacters = NumberKeyListener.collectionToArray(chars);
            mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
        } else {
            mCharacters = CHARACTERS;
            mNeedsAdvancedInput = false;
        }
    }

    /**
@@ -110,6 +120,7 @@ public class DateKeyListener extends NumberKeyListener
        };

    private final char[] mCharacters;
    private final boolean mNeedsAdvancedInput;

    private static final Object sLock = new Object();
    @GuardedBy("sLock")
+15 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.text.InputType;
import android.view.KeyEvent;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -37,8 +38,11 @@ import java.util.Locale;
public class DateTimeKeyListener extends NumberKeyListener
{
    public int getInputType() {
        return InputType.TYPE_CLASS_DATETIME
                | InputType.TYPE_DATETIME_VARIATION_NORMAL;
        if (mNeedsAdvancedInput) {
            return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
        } else {
            return InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_NORMAL;
        }
    }

    @Override
@@ -70,7 +74,13 @@ public class DateTimeKeyListener extends NumberKeyListener
                              chars, locale, SKELETON_12HOUR, SYMBOLS_TO_IGNORE)
                          && NumberKeyListener.addFormatCharsFromSkeleton(
                              chars, locale, SKELETON_24HOUR, SYMBOLS_TO_IGNORE);
        mCharacters = success ? NumberKeyListener.collectionToArray(chars) : CHARACTERS;
        if (success) {
            mCharacters = NumberKeyListener.collectionToArray(chars);
            mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
        } else {
            mCharacters = CHARACTERS;
            mNeedsAdvancedInput = false;
        }
    }

    /**
@@ -114,6 +124,7 @@ public class DateTimeKeyListener extends NumberKeyListener
        };

    private final char[] mCharacters;
    private final boolean mNeedsAdvancedInput;

    private static final Object sLock = new Object();
    @GuardedBy("sLock")
+56 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.text.Spanned;
import android.view.KeyEvent;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -42,8 +43,12 @@ import java.util.Locale;
public class DigitsKeyListener extends NumberKeyListener
{
    private char[] mAccepted;
    private boolean mNeedsAdvancedInput;
    private final boolean mSign;
    private final boolean mDecimal;
    private final boolean mStringMode;
    @Nullable
    private final Locale mLocale;

    private static final String DEFAULT_DECIMAL_POINT_CHARS = ".";
    private static final String DEFAULT_SIGN_CHARS = "-+";
@@ -112,11 +117,17 @@ public class DigitsKeyListener extends NumberKeyListener
        this(locale, false, false);
    }

    private void setToCompat(boolean sign, boolean decimal) {
    private void setToCompat() {
        mDecimalPointChars = DEFAULT_DECIMAL_POINT_CHARS;
        mSignChars = DEFAULT_SIGN_CHARS;
        final int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);
        final int kind = (mSign ? SIGN : 0) | (mDecimal ? DECIMAL : 0);
        mAccepted = COMPATIBILITY_CHARACTERS[kind];
        mNeedsAdvancedInput = false;
    }

    private void calculateNeedForAdvancedInput() {
        final int kind = (mSign ? SIGN : 0) | (mDecimal ? DECIMAL : 0);
        mNeedsAdvancedInput = !ArrayUtils.containsAll(COMPATIBILITY_CHARACTERS[kind], mAccepted);
    }

    // Takes a sign string and strips off its bidi controls, if any.
@@ -144,14 +155,16 @@ public class DigitsKeyListener extends NumberKeyListener
    public DigitsKeyListener(@Nullable Locale locale, boolean sign, boolean decimal) {
        mSign = sign;
        mDecimal = decimal;
        mStringMode = false;
        mLocale = locale;
        if (locale == null) {
            setToCompat(sign, decimal);
            setToCompat();
            return;
        }
        LinkedHashSet<Character> chars = new LinkedHashSet<>();
        final boolean success = NumberKeyListener.addDigits(chars, locale);
        if (!success) {
            setToCompat(sign, decimal);
            setToCompat();
            return;
        }
        if (sign || decimal) {
@@ -161,7 +174,7 @@ public class DigitsKeyListener extends NumberKeyListener
                final String plusString = stripBidiControls(symbols.getPlusSignString());
                if (minusString.length() > 1 || plusString.length() > 1) {
                    // non-BMP and multi-character signs are not supported.
                    setToCompat(sign, decimal);
                    setToCompat();
                    return;
                }
                final char minus = minusString.charAt(0);
@@ -181,7 +194,7 @@ public class DigitsKeyListener extends NumberKeyListener
                final String separatorString = symbols.getDecimalSeparatorString();
                if (separatorString.length() > 1) {
                    // non-BMP and multi-character decimal separators are not supported.
                    setToCompat(sign, decimal);
                    setToCompat();
                    return;
                }
                final Character separatorChar = Character.valueOf(separatorString.charAt(0));
@@ -190,13 +203,19 @@ public class DigitsKeyListener extends NumberKeyListener
            }
        }
        mAccepted = NumberKeyListener.collectionToArray(chars);
        calculateNeedForAdvancedInput();
    }

    private DigitsKeyListener(@NonNull final String accepted) {
        mSign = false;
        mDecimal = false;
        mStringMode = true;
        mLocale = null;
        mAccepted = new char[accepted.length()];
        accepted.getChars(0, accepted.length(), mAccepted, 0);
        // Theoretically we may need advanced input, but for backward compatibility, we don't change
        // the input type.
        mNeedsAdvancedInput = false;
    }

    /**
@@ -280,14 +299,39 @@ public class DigitsKeyListener extends NumberKeyListener
        return result;
    }

    /**
     * Returns a DigitsKeyListener based on an the settings of a existing DigitsKeyListener, with
     * the locale modified.
     *
     * @hide
     */
    @NonNull
    public static DigitsKeyListener getInstance(
            @Nullable Locale locale,
            @NonNull DigitsKeyListener listener) {
        if (listener.mStringMode) {
            return listener; // string-mode DigitsKeyListeners have no locale.
        } else {
            return getInstance(locale, listener.mSign, listener.mDecimal);
        }
    }

    /**
     * Returns the input type for the listener.
     */
    public int getInputType() {
        int contentType = InputType.TYPE_CLASS_NUMBER;
        int contentType;
        if (mNeedsAdvancedInput) {
            contentType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
        } else {
            contentType = InputType.TYPE_CLASS_NUMBER;
            if (mSign) {
                contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED;
            }
            if (mDecimal) {
                contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL;
            }
        }
        return contentType;
    }

+14 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.text.InputType;
import android.view.KeyEvent;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -37,8 +38,11 @@ import java.util.Locale;
public class TimeKeyListener extends NumberKeyListener
{
    public int getInputType() {
        return InputType.TYPE_CLASS_DATETIME
        | InputType.TYPE_DATETIME_VARIATION_TIME;
        if (mNeedsAdvancedInput) {
            return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
        } else {
            return InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_TIME;
        }
    }

    @Override
@@ -70,7 +74,13 @@ public class TimeKeyListener extends NumberKeyListener
                              chars, locale, SKELETON_12HOUR, SYMBOLS_TO_IGNORE)
                          && NumberKeyListener.addFormatCharsFromSkeleton(
                              chars, locale, SKELETON_24HOUR, SYMBOLS_TO_IGNORE);
        mCharacters = success ? NumberKeyListener.collectionToArray(chars) : CHARACTERS;
        if (success) {
            mCharacters = NumberKeyListener.collectionToArray(chars);
            mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
        } else {
            mCharacters = CHARACTERS;
            mNeedsAdvancedInput = false;
        }
    }

    /**
@@ -114,6 +124,7 @@ public class TimeKeyListener extends NumberKeyListener
        };

    private final char[] mCharacters;
    private final boolean mNeedsAdvancedInput;

    private static final Object sLock = new Object();
    @GuardedBy("sLock")
+66 −21
Original line number Diff line number Diff line
@@ -598,6 +598,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    private Layout mLayout;
    private boolean mLocalesChanged = false;

    // True if setKeyListener() has been explicitly called
    private boolean mListenerChanged = false;
    // True if internationalized input should be used for numbers and date and time.
    private final boolean mUseInternationalizedInput;

    @ViewDebug.ExportedProperty(category = "text")
    private int mGravity = Gravity.TOP | Gravity.START;
    private boolean mHorizontallyScrolling;
@@ -1356,6 +1361,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        final boolean numberPasswordInputType = variation
                == (EditorInfo.TYPE_CLASS_NUMBER | EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD);

        mUseInternationalizedInput =
                context.getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O;

        if (inputMethod != null) {
            Class<?> c;

@@ -1398,15 +1406,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            mEditor.mInputType = inputType = EditorInfo.TYPE_CLASS_PHONE;
        } else if (numeric != 0) {
            createEditorIfNeeded();
            mEditor.mKeyListener = DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
            mEditor.mKeyListener = DigitsKeyListener.getInstance(
                    mUseInternationalizedInput ? getTextLocale() : null,
                    (numeric & SIGNED) != 0,
                    (numeric & DECIMAL) != 0);
            inputType = EditorInfo.TYPE_CLASS_NUMBER;
            if ((numeric & SIGNED) != 0) {
                inputType |= EditorInfo.TYPE_NUMBER_FLAG_SIGNED;
            }
            if ((numeric & DECIMAL) != 0) {
                inputType |= EditorInfo.TYPE_NUMBER_FLAG_DECIMAL;
            }
            inputType = mEditor.mKeyListener.getInputType();
            mEditor.mInputType = inputType;
        } else if (autotext || autocap != -1) {
            TextKeyListener.Capitalize cap;
@@ -2308,11 +2312,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     * @attr ref android.R.styleable#TextView_autoText
     */
    public void setKeyListener(KeyListener input) {
        mListenerChanged = true;
        setKeyListenerOnly(input);
        fixFocusableAndClickableSettings();

        if (input != null) {
            createEditorIfNeeded();
            setInputTypeFromEditor();
        } else {
            if (mEditor != null) mEditor.mInputType = EditorInfo.TYPE_NULL;
        }

        InputMethodManager imm = InputMethodManager.peekInstance();
        if (imm != null) imm.restartInput(this);
    }

    private void setInputTypeFromEditor() {
        try {
            mEditor.mInputType = mEditor.mKeyListener.getInputType();
        } catch (IncompatibleClassChangeError e) {
@@ -2321,12 +2336,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        // Change inputType, without affecting transformation.
        // No need to applySingleLine since mSingleLine is unchanged.
        setInputTypeSingleLine(mSingleLine);
        } else {
            if (mEditor != null) mEditor.mInputType = EditorInfo.TYPE_NULL;
        }

        InputMethodManager imm = InputMethodManager.peekInstance();
        if (imm != null) imm.restartInput(this);
    }

    private void setKeyListenerOnly(KeyListener input) {
@@ -3390,6 +3399,29 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return mTextPaint.getTextLocales();
    }

    private void changeListenerLocaleTo(@NonNull Locale locale) {
        if (mListenerChanged) {
            // If a listener has been explicitly set, don't change it. We may break something.
            return;
        }
        if (mEditor != null) {
            KeyListener listener = mEditor.mKeyListener;
            if (listener instanceof DigitsKeyListener) {
                listener = DigitsKeyListener.getInstance(locale, (DigitsKeyListener) listener);
            } else if (listener instanceof DateKeyListener) {
                listener = DateKeyListener.getInstance(locale);
            } else if (listener instanceof TimeKeyListener) {
                listener = TimeKeyListener.getInstance(locale);
            } else if (listener instanceof DateTimeKeyListener) {
                listener = DateTimeKeyListener.getInstance(locale);
            } else {
                return;
            }
            setKeyListenerOnly(listener);
            setInputTypeFromEditor();
        }
    }

    /**
     * Set the default {@link LocaleList} of the text in this TextView to a one-member list
     * containing just the given value.
@@ -3401,6 +3433,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    public void setTextLocale(@NonNull Locale locale) {
        mLocalesChanged = true;
        mTextPaint.setTextLocale(locale);
        changeListenerLocaleTo(locale);
        if (mLayout != null) {
            nullLayouts();
            requestLayout();
@@ -3422,6 +3455,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    public void setTextLocales(@NonNull @Size(min = 1) LocaleList locales) {
        mLocalesChanged = true;
        mTextPaint.setTextLocales(locales);
        changeListenerLocaleTo(locales.get(0));
        if (mLayout != null) {
            nullLayouts();
            requestLayout();
@@ -3433,7 +3467,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (!mLocalesChanged) {
            mTextPaint.setTextLocales(LocaleList.getDefault());
            final LocaleList locales = LocaleList.getDefault();
            mTextPaint.setTextLocales(locales);
            changeListenerLocaleTo(locales.get(0));
            if (mLayout != null) {
                nullLayouts();
                requestLayout();
@@ -5567,26 +5603,35 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            input = TextKeyListener.getInstance(autotext, cap);
        } else if (cls == EditorInfo.TYPE_CLASS_NUMBER) {
            input = DigitsKeyListener.getInstance(
                    mUseInternationalizedInput ? getTextLocale() : null,
                    (type & EditorInfo.TYPE_NUMBER_FLAG_SIGNED) != 0,
                    (type & EditorInfo.TYPE_NUMBER_FLAG_DECIMAL) != 0);
            if (mUseInternationalizedInput) {
                type = input.getInputType(); // Override type, if necessary for i18n.
            }
        } else if (cls == EditorInfo.TYPE_CLASS_DATETIME) {
            final Locale locale = mUseInternationalizedInput ? getTextLocale() : null;
            switch (type & EditorInfo.TYPE_MASK_VARIATION) {
                case EditorInfo.TYPE_DATETIME_VARIATION_DATE:
                    input = DateKeyListener.getInstance();
                    input = DateKeyListener.getInstance(locale);
                    break;
                case EditorInfo.TYPE_DATETIME_VARIATION_TIME:
                    input = TimeKeyListener.getInstance();
                    input = TimeKeyListener.getInstance(locale);
                    break;
                default:
                    input = DateTimeKeyListener.getInstance();
                    input = DateTimeKeyListener.getInstance(locale);
                    break;
            }
            if (mUseInternationalizedInput) {
                type = input.getInputType(); // Override type, if necessary for i18n.
            }
        } else if (cls == EditorInfo.TYPE_CLASS_PHONE) {
            input = DialerKeyListener.getInstance();
        } else {
            input = TextKeyListener.getInstance();
        }
        setRawInputType(type);
        mListenerChanged = false;
        if (direct) {
            createEditorIfNeeded();
            mEditor.mKeyListener = input;
Loading