summaryrefslogtreecommitdiff
path: root/core/java/android/widget/TextView.java
diff options
context:
space:
mode:
authoryingleiw <yingleiw@google.com>2021-11-02 18:31:40 -0700
committeryingleiw <yingleiw@google.com>2021-11-17 20:01:30 -0800
commit63ab661d5a8c83ed9f02924f17f79116865275ea (patch)
treed40e85fd4298262629154e61118054eead6b10e7 /core/java/android/widget/TextView.java
parente551c20dc8a295ebf3b7b729a321210c37e430dd (diff)
Send TYPE_VIEW_TEXT_CHANGED a11y event when SuggestionSpan is added
When user types space after a word, we receive a text change event, but the suggestion span is not added to the text yet. The spell checker adds the span after the text change event is sent. Previously we send the event in onSpanAdded in TextView, but we don't do anything or update the before text for span removed. This is a bit confusing and error prone. This change moves the send event logic into spell checker. Bug: b/143378480 Test: tested with talkback. Change-Id: Ibd45843494304602b177df8da520a51058989f10
Diffstat (limited to 'core/java/android/widget/TextView.java')
-rw-r--r--core/java/android/widget/TextView.java68
1 files changed, 17 insertions, 51 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8fba58364c94..496fa67498eb 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12501,6 +12501,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return TextUtils.trimToParcelableSize(mTransformed);
}
+ boolean isVisibleToAccessibility() {
+ return AccessibilityManager.getInstance(mContext).isEnabled()
+ && (isFocused() || (isSelected() && isShown()));
+ }
+
void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText,
int fromIndex, int removedCount, int addedCount) {
AccessibilityEvent event =
@@ -12512,6 +12517,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
sendAccessibilityEventUnchecked(event);
}
+ void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText,
+ int fromIndex, int toIndex) {
+ AccessibilityEvent event =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+ event.setFromIndex(fromIndex);
+ event.setToIndex(toIndex);
+ event.setBeforeText(beforeText);
+ sendAccessibilityEventUnchecked(event);
+ }
+
private InputMethodManager getInputMethodManager() {
return getContext().getSystemService(InputMethodManager.class);
}
@@ -13826,10 +13841,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
TextView.this.handleTextChanged(buffer, start, before, after);
- if (AccessibilityManager.getInstance(mContext).isEnabled()
- && (isFocused() || (isSelected() && isShown()))) {
+ if (isVisibleToAccessibility()) {
sendAccessibilityEventTypeViewTextChanged(mBeforeText, start, before, after);
- mBeforeText = TextUtils.stringOrSpannedString(mTransformed);
+ mBeforeText = null;
}
}
@@ -13857,54 +13871,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Log.v(LOG_TAG, "onSpanAdded s=" + s + " e=" + e + " what=" + what + ": " + buf);
}
TextView.this.spanChange(buf, what, -1, s, -1, e);
- // Note we don't update mBeforeText here. We look for SuggestionSpans added after the
- // text content changes.
- if (AccessibilityManager.getInstance(mContext).isEnabled()
- && (isFocused() || (isSelected() && isShown()))
- && (what instanceof SuggestionSpan)) {
- // When the user types a new word, and SuggestionSpans on the existing words will be
- // removed and added again. We don't need to send out events for existing
- // SuggestionSpans. Multiple spans can be placed on the range.
- if (mBeforeText instanceof SpannedString) {
- final SpannedString beforeSpannedString = (SpannedString) mBeforeText;
- if ((beforeSpannedString.getSpanStart(what) == s)
- && (beforeSpannedString.getSpanEnd(what) == e)) {
- // Exactly same span is found.
- return;
- }
- // Suggestion span couldn't be found. Try to find a suggestion span that has the
- // same contents.
- SuggestionSpan[] suggestionSpans = beforeSpannedString.getSpans(s, e,
- SuggestionSpan.class);
- for (final SuggestionSpan suggestionSpan : suggestionSpans) {
- final int start = beforeSpannedString.getSpanStart(suggestionSpan);
- if (start != s) {
- continue;
- }
- final int end = beforeSpannedString.getSpanEnd(suggestionSpan);
- if (end != e) {
- continue;
- }
- if (equalSuggestionSpan(suggestionSpan, (SuggestionSpan) what)) {
- return;
- }
- }
- }
- AccessibilityEvent event =
- AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
- event.setFromIndex(s);
- event.setToIndex(e);
- event.setBeforeText(mBeforeText);
- sendAccessibilityEventUnchecked(event);
- }
- }
-
- private boolean equalSuggestionSpan(SuggestionSpan span1, SuggestionSpan span2) {
- // We compare flags because flags will determine the underline color.
- return Arrays.equals(span1.getSuggestions(), span2.getSuggestions())
- && Objects.equals(span1.getLocaleObject(), span2.getLocaleObject())
- && span1.getLocale().equals(span2.getLocale())
- && (span1.getFlags() == span2.getFlags());
}
public void onSpanRemoved(Spannable buf, Object what, int s, int e) {