summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2013-05-07 18:49:51 -0700
committerSvetoslav <svetoslavganov@google.com>2013-05-10 20:14:40 -0700
commitabad55d860be793b8b9b3e288a74214da89fb368 (patch)
treee4de52f7efb278a07bae350fb39152d9fb9b11a1 /core
parenta6303d8a211543a8e1f5fd2425024a1c4d0f88ff (diff)
downloadframeworks_base-abad55d860be793b8b9b3e288a74214da89fb368.zip
frameworks_base-abad55d860be793b8b9b3e288a74214da89fb368.tar.gz
frameworks_base-abad55d860be793b8b9b3e288a74214da89fb368.tar.bz2
Fixing the accessibility text traversal in extend mode.
We added APIs to allow an accessibility service to extend the selection while moving the cursor at a given granularity such as word, character, etc. The problem is that the traversal was extending only the end of the selection while moving forward and the start of the selection while moving backward. This leads to a case in which the user cannot shrink/extend the selection because for example instead of shrinking the end of the selection the implementation was extending the start. Now extending the selection moves only the selection end. This is the same behavior as text view using a keyboard. Tests: https://googleplex-android-review.googlesource.com/#/c/307062 bug:8839844 Change-Id: Id6965b102647df909f61301fcc8ec05458dd5881
Diffstat (limited to 'core')
-rw-r--r--core/java/android/view/View.java66
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java2
-rw-r--r--core/java/android/widget/TextView.java8
3 files changed, 26 insertions, 50 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c47e111..4f3a391 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7069,7 +7069,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
final boolean extendSelection = arguments.getBoolean(
AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
- return nextAtGranularity(granularity, extendSelection);
+ return traverseAtGranularity(granularity, true, extendSelection);
}
} break;
case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
@@ -7078,7 +7078,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
final boolean extendSelection = arguments.getBoolean(
AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
- return previousAtGranularity(granularity, extendSelection);
+ return traverseAtGranularity(granularity, false, extendSelection);
}
} break;
case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
@@ -7103,7 +7103,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return false;
}
- private boolean nextAtGranularity(int granularity, boolean extendSelection) {
+ private boolean traverseAtGranularity(int granularity, boolean forward,
+ boolean extendSelection) {
CharSequence text = getIterableTextForAccessibility();
if (text == null || text.length() == 0) {
return false;
@@ -7114,60 +7115,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
int current = getAccessibilitySelectionEnd();
if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
- current = 0;
+ current = forward ? 0 : text.length();
}
- final int[] range = iterator.following(current);
+ final int[] range = forward ? iterator.following(current) : iterator.preceding(current);
if (range == null) {
return false;
}
- final int start = range[0];
- final int end = range[1];
+ final int segmentStart = range[0];
+ final int segmentEnd = range[1];
+ int selectionStart;
+ int selectionEnd;
if (extendSelection && isAccessibilitySelectionExtendable()) {
- int selectionStart = getAccessibilitySelectionStart();
+ selectionStart = getAccessibilitySelectionStart();
if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
- selectionStart = start;
+ selectionStart = forward ? segmentStart : segmentEnd;
}
- setAccessibilitySelection(selectionStart, end);
+ selectionEnd = forward ? segmentEnd : segmentStart;
} else {
- setAccessibilitySelection(end, end);
+ selectionStart = selectionEnd= forward ? segmentEnd : segmentStart;
}
- sendViewTextTraversedAtGranularityEvent(
- AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
- granularity, start, end);
- return true;
- }
-
- private boolean previousAtGranularity(int granularity, boolean extendSelection) {
- CharSequence text = getIterableTextForAccessibility();
- if (text == null || text.length() == 0) {
- return false;
- }
- TextSegmentIterator iterator = getIteratorForGranularity(granularity);
- if (iterator == null) {
- return false;
- }
- int current = getAccessibilitySelectionStart();
- if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
- current = text.length();
- }
- final int[] range = iterator.preceding(current);
- if (range == null) {
- return false;
- }
- final int start = range[0];
- final int end = range[1];
- if (extendSelection && isAccessibilitySelectionExtendable()) {
- int selectionEnd = getAccessibilitySelectionEnd();
- if (selectionEnd == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
- selectionEnd = end;
- }
- setAccessibilitySelection(start, selectionEnd);
- } else {
- setAccessibilitySelection(start, start);
- }
- sendViewTextTraversedAtGranularityEvent(
- AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
- granularity, start, end);
+ setAccessibilitySelection(selectionStart, selectionEnd);
+ final int action = forward ? AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+ : AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+ sendViewTextTraversedAtGranularityEvent(action, granularity, segmentStart, segmentEnd);
return true;
}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 9603fe5..dbeca1f 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -1248,7 +1248,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
if (eventTypeCount > 0) {
builder.append(", ");
}
- builder.append("TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED");
+ builder.append("TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY");
eventTypeCount++;
} break;
case TYPE_GESTURE_DETECTION_START: {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9e3f87f..8e6c739 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8722,8 +8722,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
&& getAccessibilitySelectionEnd() == end) {
return;
}
+ // Hide all selection controllers used for adjusting selection
+ // since we are doing so explicitlty by other means and these
+ // controllers interact with how selection behaves.
+ if (mEditor != null) {
+ mEditor.hideControllers();
+ }
CharSequence text = getIterableTextForAccessibility();
- if (start >= 0 && start <= end && end <= text.length()) {
+ if (Math.min(start, end) >= 0 && Math.max(start, end) <= text.length()) {
Selection.setSelection((Spannable) text, start, end);
} else {
Selection.removeSelection((Spannable) text);