Set accessibility cursor position in non-editable views with content description.
While an accessibility service can set the cursor position in an editable
text field, it was not possible to set it for non-editable views with
content description. This patch enables that.
bug:8134469
Change-Id: I28b0ef1666b9e3ed5c0642718fbe63d4c9616569
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 11c80c26..adefa5a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5082,6 +5082,7 @@
}
if (mContentDescription != null && mContentDescription.length() > 0) {
+ info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
@@ -7022,6 +7023,24 @@
return previousAtGranularity(granularity, extendSelection);
}
} break;
+ case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
+ CharSequence text = getIterableTextForAccessibility();
+ if (text == null) {
+ return false;
+ }
+ final int start = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
+ final int end = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
+ // Only cursor position can be specified (selection length == 0)
+ if ((getAccessibilitySelectionStart() != start
+ || getAccessibilitySelectionEnd() != end)
+ && (start == end)) {
+ setAccessibilitySelection(start, end);
+ notifyAccessibilityStateChanged();
+ return true;
+ }
+ } break;
}
return false;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2f02780..1579e79 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8030,28 +8030,30 @@
} return false;
case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
if (isFocused() && canSelectText()) {
- final int start = (arguments != null) ? arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
- final int end = (arguments != null) ? arguments.getInt(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
CharSequence text = getIterableTextForAccessibility();
if (text == null) {
return false;
}
- // No arguments clears the selection.
- if (start == end && end == -1) {
- Selection.removeSelection((Spannable) text);
- notifyAccessibilityStateChanged();
- return true;
- }
- if (start >= 0 && start <= end && end <= text.length()) {
- Selection.setSelection((Spannable) text, start, end);
- // Make sure selection mode is engaged.
- if (mEditor != null) {
- mEditor.startSelectionActionMode();
+ final int start = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
+ final int end = (arguments != null) ? arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
+ if ((getSelectionStart() != start || getSelectionEnd() != end)) {
+ // No arguments clears the selection.
+ if (start == end && end == -1) {
+ Selection.removeSelection((Spannable) text);
+ notifyAccessibilityStateChanged();
+ return true;
}
- notifyAccessibilityStateChanged();
- return true;
+ if (start >= 0 && start <= end && end <= text.length()) {
+ Selection.setSelection((Spannable) text, start, end);
+ // Make sure selection mode is engaged.
+ if (mEditor != null) {
+ mEditor.startSelectionActionMode();
+ }
+ notifyAccessibilityStateChanged();
+ return true;
+ }
}
}
} return false;