Add AccessibilityNodeInfo.isTextSelectable

ACTION_SET_SELECTION is needed on all TextView nodes to reset the
cursor. But some non-edit texts are selectable and need to be
identified by a11y services. ACTION_SET_SELECTION has been on these
nodes for years so to avoid the complexity of breaking this, add a
node property.

Services should use ACTION_SET_SELECTION for nodes where
property=true

Bug: 62058901
Test: atest  AccessibilityTextTraversalTest, TextViewTest cts and
core (TextViewTest#testCutShouldNotThrowException keeps failing but
it's unrelated to this change)

Change-Id: Ia825dd806824e663e7fa7d274f51c6bf44f0c2c4
This commit is contained in:
sallyyuen
2022-01-26 09:32:51 -08:00
parent e39055a2d7
commit bd0e5becea
4 changed files with 44 additions and 2 deletions

View File

@@ -52266,6 +52266,7 @@ package android.view.accessibility {
method public boolean isSelected();
method public boolean isShowingHintText();
method public boolean isTextEntryKey();
method public boolean isTextSelectable();
method public boolean isVisibleToUser();
method @Deprecated public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View);
method @Deprecated public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View, int);
@@ -52329,6 +52330,7 @@ package android.view.accessibility {
method public void setStateDescription(@Nullable CharSequence);
method public void setText(CharSequence);
method public void setTextEntryKey(boolean);
method public void setTextSelectable(boolean);
method public void setTextSelection(int, int);
method public void setTooltipText(@Nullable CharSequence);
method public void setTouchDelegateInfo(@NonNull android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo);

View File

@@ -710,6 +710,8 @@ public class AccessibilityNodeInfo implements Parcelable {
private static final int BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY = 0x0400000;
private static final int BOOLEAN_PROPERTY_IS_TEXT_SELECTABLE = 0x0800000;
/**
* Bits that provide the id of a virtual descendant of a view.
*/
@@ -2275,6 +2277,38 @@ public class AccessibilityNodeInfo implements Parcelable {
setBooleanProperty(BOOLEAN_PROPERTY_SCROLLABLE, scrollable);
}
/**
* Gets if the node has selectable text.
*
* <p>
* Services should use {@link #ACTION_SET_SELECTION} for selection. Editable text nodes must
* also be selectable. But not all UIs will populate this field, so services should consider
* 'isTextSelectable | isEditable' to ensure they don't miss nodes with selectable text.
* </p>
*
* @see #isEditable
* @return True if the node has selectable text.
*/
public boolean isTextSelectable() {
return getBooleanProperty(BOOLEAN_PROPERTY_IS_TEXT_SELECTABLE);
}
/**
* Sets if the node has selectable text.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param selectableText True if the node has selectable text, false otherwise.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setTextSelectable(boolean selectableText) {
setBooleanProperty(BOOLEAN_PROPERTY_IS_TEXT_SELECTABLE, selectableText);
}
/**
* Gets if the node is editable.
*
@@ -4327,8 +4361,12 @@ public class AccessibilityNodeInfo implements Parcelable {
return "ACTION_CANCEL_DRAG";
case R.id.accessibilityActionDragDrop:
return "ACTION_DROP";
default:
default: {
if (action == R.id.accessibilityActionShowSuggestions) {
return "ACTION_SHOW_SUGGESTIONS";
}
return "ACTION_UNKNOWN";
}
}
}
@@ -4462,6 +4500,7 @@ public class AccessibilityNodeInfo implements Parcelable {
builder.append("; importantForAccessibility: ").append(isImportantForAccessibility());
builder.append("; visible: ").append(isVisibleToUser());
builder.append("; actions: ").append(mActions);
builder.append("; isTextSelectable: ").append(isTextSelectable());
return builder.toString();
}

View File

@@ -12197,6 +12197,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
EXTRA_DATA_RENDERING_INFO_KEY,
EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
));
info.setTextSelectable(isTextSelectable());
} else {
info.setAvailableExtraData(Arrays.asList(
EXTRA_DATA_RENDERING_INFO_KEY

View File

@@ -58,7 +58,7 @@ public class AccessibilityNodeInfoTest {
// The number of flags held in boolean properties. Their values should also be double-checked
// in the methods above.
private static final int NUM_BOOLEAN_PROPERTIES = 23;
private static final int NUM_BOOLEAN_PROPERTIES = 24;
@Test
public void testStandardActions_serializationFlagIsValid() {