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

Commit 35ea7b7d authored by Roozbeh Pournader's avatar Roozbeh Pournader Committed by android-build-merger
Browse files

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

am: 94b6b532

Change-Id: I38faf86ec475154d437cc7dc7a363d58fd5962da
parents a110bdd0 94b6b532
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