Fixes for a11y selection

- TextView should request focus before performing selection on
  non-editable text, since selection requires focus. On the a11y
  service side, input focus should not matter when selecting
  non-editable text.
- Remove clickable and long-clickable states, since these are present
  due to TextView#setTextIsSelectable.
- Make UI controller changes consistent between SET_SiELECTION and
  SET_TEXT. Using SET_SELECTION means the action mode menu won't pop up
  and the left/right selection handles won't appear. Interactions
  between multiple EditTexts were previously inconsistent

- Delete some obsolete javadoc

Bug: 218357385
Test: builds and install: highlighting is consistent between SET
actions. highlighting works when selecting text in TalkBack, without
the service needing to purposely put input focus,
atest AccessibilityTextTraverssalText

Change-Id: I67986020aa112d45bd670f77b2b415617226c094
This commit is contained in:
Sally
2022-03-15 17:33:40 +00:00
parent fe5ac369f9
commit 55022a5880
2 changed files with 39 additions and 10 deletions

View File

@@ -14649,6 +14649,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int selectionStart;
int selectionEnd;
if (extendSelection && isAccessibilitySelectionExtendable()) {
prepareForExtendedAccessibilitySelection();
selectionStart = getAccessibilitySelectionStart();
if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
selectionStart = forward ? segmentStart : segmentEnd;
@@ -14687,6 +14688,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return false;
}
/**
* Prepare for extended selection.
* @hide
*/
public void prepareForExtendedAccessibilitySelection() {
return;
}
/**
* @hide
*/

View File

@@ -12363,9 +12363,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// A view should not be exposed as clickable/long-clickable to a service because of a
// LinkMovementMethod.
// LinkMovementMethod or because it has selectable and non-editable text.
if ((info.isClickable() || info.isLongClickable())
&& mMovement instanceof LinkMovementMethod) {
&& (mMovement instanceof LinkMovementMethod
|| (isTextSelectable() && !isTextEditable()))) {
if (!hasOnClickListeners()) {
info.setClickable(false);
info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
@@ -12597,11 +12598,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return true;
}
if (start >= 0 && start <= end && end <= text.length()) {
requestFocusOnNonEditableSelectableText();
Selection.setSelection((Spannable) text, start, end);
// Make sure selection mode is engaged.
if (mEditor != null) {
mEditor.startSelectionActionModeAsync(false);
}
hideAccessibilitySelectionControllers();
return true;
}
}
@@ -12695,6 +12694,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return handled;
}
private void requestFocusOnNonEditableSelectableText() {
if (!isTextEditable() && isTextSelectable()) {
if (!isEnabled()) {
return;
}
if (isFocusable() && !isFocused()) {
requestFocus();
}
}
}
private boolean hasSpannableText() {
return mText != null && mText instanceof Spannable;
}
@@ -12723,9 +12734,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* Returns the text that should be exposed to accessibility services.
* <p>
* This approximates what is displayed visually. If the user has specified
* that accessibility services should speak passwords, this method will
* bypass any password transformation method and return unobscured text.
* This approximates what is displayed visually.
*
* @return the text that should be exposed to accessibility services, may
* be {@code null} if no text is set
@@ -13703,6 +13712,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return true;
}
/**
* @hide
*/
public void prepareForExtendedAccessibilitySelection() {
requestFocusOnNonEditableSelectableText();
}
/**
* @hide
*/
@@ -13727,8 +13743,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Selection.removeSelection((Spannable) text);
}
// Hide all selection controllers used for adjusting selection
// since we are doing so explicitlty by other means and these
// since we are doing so explicitly by other means and these
// controllers interact with how selection behaves.
hideAccessibilitySelectionControllers();
}
private void hideAccessibilitySelectionControllers() {
if (mEditor != null) {
mEditor.hideCursorAndSpanControllers();
mEditor.stopTextActionMode();