Status Update
Comments
al...@google.com <al...@google.com>
se...@google.com <se...@google.com> #2
Taking a look, thanks!
se...@google.com <se...@google.com> #3
Details for future reference (copied from internal debugging doc)
se...@google.com <se...@google.com> #4
Overview
Exploring the behavior of TextView.setKeyListener
in O+ which strips input type when wrapping a platform KeyListener
. In addition to stripping input type, calling setKeyListener
disables TextView
locale setting updates to locale on the KeyListener
.
This surfaced when integrating emoji2 into appcompat, but impacts all KeyListener
usage in EditText
.
Problem
setKeyListener
attempts to update the input type for the new key listener, which is behavior that was added in O
In addition, hardcoded class names for internationalization impacts i18n keyListener configuration when the developer has wrapped a KeyListener
.
Flow for dropping variations
InputType
supports multiple variations (e.g. TYPE_TEXT_VARIATION_URI
) that impact the keyboard behavior. These variations that are stored directly on the Editor as a primary source of truth to share with imm, that source of truth is overwritten by partial information from KeyListener
.
The full flow to removing variations for text looks like:
- TextView ctor - read inputType correctly from XML and apply it to the TextView
- Assigns inputType to editor (this is source of truth)
- Text variation flow runs through several branches, leading to here which stores the xml inputType directly
- Assign appropriate KeyListener, depending on inputType (here)
- KeyListener also has knowledge of inputType, but it's not the same as the one on editor (note missing parameter here)
- TextView.setKeyListener - reset the inputType to KeyListener.getInputType() (line)
- KeyListener.getInputType() is not dependent on the full variation specified in XML, and attempts to reconstruct an input type only from it's internal state
- TextKeyListener.getInputType - delegates to BaseKeyListener.makeTextContentType which only depends on caps and autoText.
- BaseKeyListener.makeTextContentType - constructs a new input type, stripping variations such as TYPE_TEXT_VARIANT_URI.
Flow for disabling locale updates on KeyListener
Another issue is that setting a KeyListener
, even to a platform type, disables locale setting to types that support setting locale. This has the effect of not correctly allowing punctuation on dates, for example.
The flow for this is similar:
- TextView ctor - initialize editor with a KeyListener that correctly supports locale changes
- TextView.setKeyListener - set a flag to disable locale updates
- mListenerChanged = true;
- This is always set, even if the listener is able to support locale changes
- There is no interface or supertype that a non-platform KeyListener may implement that allows it to receive locale changes.
- TextView.setImeHintLocales - Called by developer to attempt to update locales for ime
- TextView.changeLocaleListenerTo - private method, that attempts to update locale on KeyListener, exits early if setKeyListener has been called (even if the KeyListener could support locale).
Solution to implement
Reset variations after setKeyListener
Basically, reset the inputType
after calling setKeyListener
only to add EmojiKeyListener
. When the KeyListener
is actually changed by app delegate to existing platform behavior.
se...@google.com <se...@google.com> #5
Easy enough fix for appcompat, landing shortly.
se...@google.com <se...@google.com> #6
For IME, the recommendation is to manually handle that in your KeyListener
implementation and call it directly (not through EditText
).
se...@google.com <se...@google.com> #7
For locale updates on a custom KeyListener - recommendation is to implement your own KeyListener
that handles locale and call it directly (skipping the EditText
path).
ap...@google.com <ap...@google.com> #8
Branch: androidx-main
commit 72e50a813e3af970adfaecc8eff3ce22c6d5b827
Author: Sean McQuillan <seanmcq@google.com>
Date: Wed Jun 16 15:51:17 2021
Bugfix: Don't reset inputType in AppCompatEditText
Calling setKeyListener in the AppCompatEditText constructor reset the
input type specified in XML. Instead, only on the constructor call
restore the input type after setting the EmojiCompat key listener.
The platfrom behavior is retained for AppCompatEditText.setKeyListener,
which will cause the inputType to be reset in setKeyListener on O+.
Bug:
Test: New unit test
Relnote: "Fix bug in AppCompatEditText that will reset the inputType
specified in XML to remove variations. This bug was introduced in
AppCompat 1.4.0-alpha01."
Change-Id: I9df3655f05312806c46875e9d5603fe48154dd8e
M appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatEditTextEmojiTest.java
M appcompat/appcompat/src/androidTest/res/layout/appcompat_edittext_emoji_activity.xml
M appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatEmojiEditTextHelper.java
al...@google.com <al...@google.com> #9
Just a note for process's sake -- we don't need to cherry-pick this in a bugfix since 1.4.0 hasn't gone stable yet.
se...@google.com <se...@google.com>
bo...@googlemail.com <bo...@googlemail.com> #10
Just a note for process's sake -- we don't need to cherry-pick this in a bugfix since 1.4.0 hasn't gone stable yet.
Do I understand correctly that you don't want to put this bug in the release notes? Is it because, it's a little embarrassing :D (just kidding) that this bug has survived two alpha versions or because it was security related? I mean all others reported bugs are always listed in the release notes.
But hey I'm just a small developer and respect the decisions of google people. Just wanted to make myself important :D
al...@google.com <al...@google.com> #11
high priority bug, but that it wasn't a bug affecting the previously
released stable version such that it would require an extra release.
On Fri, Jun 18, 2021, 4:52 AM <buganizer-system@google.com> wrote:
dm...@gmail.com <dm...@gmail.com> #12
I use code below to display EditText in which user can type IP-address
<com.google.android.material.textfield.TextInputEditText
...
android:inputType="numberDecimal"
android:digits="0123456789."
...
/>
For all previous releases (including 1.4.0-alpha02) I got numeric keyboard, which allowed me to enter several dots while entering IP.
In release 1.4.0-alpha03 I can only input first dot and the next dot cannot be placed.
Maybe this is wrong issue for this, but I didnt find any better match.
al...@google.com <al...@google.com> #13
Please file the regression as a new issue.
Description
Component used: EditText Version used: Version 1.4.0-alpha02 Devices/Android versions reproduced on: Pixel 3a/4a/5
It seems that set the inputType over xml doesn't work anymore. I have attached a demo project where you can reproduce this issue. With Version 1.3.0 everything working fine.
Just simple things like:
are not working anymore. When you set it programmatically everything is working fine:
Also more critical things like 'textPassword' are not working correctly. The password doesn't show but the keyboard (in this sample gboard) is showing auto suggestions!. When you set the InputType programmatically auto suggestions got hidden.
I think it is a high priority thing because it is not immediately recognizable.