summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Chen <clchen@google.com>2012-05-17 16:55:40 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-05-17 16:55:40 -0700
commitc6015df128811a52faf918bd34d0d7296c8a6834 (patch)
tree3f2c8f6f6e072bd1f7072df6930a8284f87931e0
parent9a9a041cb75a803856b22191db7e6bde7f1412e8 (diff)
parent6a62b77dfb95364e863b44662c13d6deec47f7d2 (diff)
downloadframeworks_base-c6015df128811a52faf918bd34d0d7296c8a6834.zip
frameworks_base-c6015df128811a52faf918bd34d0d7296c8a6834.tar.gz
frameworks_base-c6015df128811a52faf918bd34d0d7296c8a6834.tar.bz2
Merge "Add actions to non-JavaScript accessibility handler." into jb-dev
-rw-r--r--core/java/android/webkit/AccessibilityInjector.java23
-rw-r--r--core/java/android/webkit/AccessibilityInjectorFallback.java100
2 files changed, 99 insertions, 24 deletions
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index bea97c5..cc490bd 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -63,7 +63,7 @@ class AccessibilityInjector {
// Lazily loaded helper objects.
private AccessibilityManager mAccessibilityManager;
- private AccessibilityInjectorFallback mAccessibilityInjector;
+ private AccessibilityInjectorFallback mAccessibilityInjectorFallback;
private JSONObject mAccessibilityJSONObject;
// Whether the accessibility script has been injected into the current page.
@@ -200,10 +200,9 @@ class AccessibilityInjector {
if (mAccessibilityScriptInjected) {
return sendActionToAndroidVox(action, arguments);
}
-
- if (mAccessibilityInjector != null) {
- // TODO: Implement actions for non-JS handler.
- return false;
+
+ if (mAccessibilityInjectorFallback != null) {
+ return mAccessibilityInjectorFallback.performAccessibilityAction(action, arguments);
}
return false;
@@ -238,11 +237,11 @@ class AccessibilityInjector {
return true;
}
- if (mAccessibilityInjector != null) {
+ if (mAccessibilityInjectorFallback != null) {
// if an accessibility injector is present (no JavaScript enabled or
// the site opts out injecting our JavaScript screen reader) we let
// it decide whether to act on and consume the event.
- return mAccessibilityInjector.onKeyEvent(event);
+ return mAccessibilityInjectorFallback.onKeyEvent(event);
}
return false;
@@ -255,8 +254,8 @@ class AccessibilityInjector {
* @param selectionString The selection string.
*/
public void handleSelectionChangedIfNecessary(String selectionString) {
- if (mAccessibilityInjector != null) {
- mAccessibilityInjector.onSelectionStringChange(selectionString);
+ if (mAccessibilityInjectorFallback != null) {
+ mAccessibilityInjectorFallback.onSelectionStringChange(selectionString);
}
}
@@ -304,10 +303,10 @@ class AccessibilityInjector {
* {@code false} to disable it.
*/
private void toggleFallbackAccessibilityInjector(boolean enabled) {
- if (enabled && (mAccessibilityInjector == null)) {
- mAccessibilityInjector = new AccessibilityInjectorFallback(mWebViewClassic);
+ if (enabled && (mAccessibilityInjectorFallback == null)) {
+ mAccessibilityInjectorFallback = new AccessibilityInjectorFallback(mWebViewClassic);
} else {
- mAccessibilityInjector = null;
+ mAccessibilityInjectorFallback = null;
}
}
diff --git a/core/java/android/webkit/AccessibilityInjectorFallback.java b/core/java/android/webkit/AccessibilityInjectorFallback.java
index 9bf52ca..4d9c26c 100644
--- a/core/java/android/webkit/AccessibilityInjectorFallback.java
+++ b/core/java/android/webkit/AccessibilityInjectorFallback.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -23,6 +24,7 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.webkit.WebViewCore.EventHub;
import java.util.ArrayList;
@@ -48,7 +50,7 @@ import java.util.Stack;
* {@link #setCurrentAxis(int, boolean, String)}, or
* {@link #traverseCurrentAxis(int, boolean, String)}
* {@link #traverseGivenAxis(int, int, boolean, String)}
- * {@link #prefromAxisTransition(int, int, boolean, String)}
+ * {@link #performAxisTransition(int, int, boolean, String)}
* referred via the values of:
* {@link #ACTION_SET_CURRENT_AXIS},
* {@link #ACTION_TRAVERSE_CURRENT_AXIS},
@@ -72,15 +74,30 @@ class AccessibilityInjectorFallback {
private static final int ACTION_PERFORM_AXIS_TRANSITION = 3;
private static final int ACTION_TRAVERSE_DEFAULT_WEB_VIEW_BEHAVIOR_AXIS = 4;
- // the default WebView behavior abstracted as a navigation axis
+ // WebView navigation axes from WebViewCore.h, plus an additional axis for
+ // the default behavior.
+ private static final int NAVIGATION_AXIS_CHARACTER = 0;
+ private static final int NAVIGATION_AXIS_WORD = 1;
+ private static final int NAVIGATION_AXIS_SENTENCE = 2;
+ @SuppressWarnings("unused")
+ private static final int NAVIGATION_AXIS_HEADING = 3;
+ private static final int NAVIGATION_AXIS_SIBLING = 5;
+ @SuppressWarnings("unused")
+ private static final int NAVIGATION_AXIS_PARENT_FIRST_CHILD = 5;
+ private static final int NAVIGATION_AXIS_DOCUMENT = 6;
private static final int NAVIGATION_AXIS_DEFAULT_WEB_VIEW_BEHAVIOR = 7;
+ // WebView navigation directions from WebViewCore.h.
+ private static final int NAVIGATION_DIRECTION_BACKWARD = 0;
+ private static final int NAVIGATION_DIRECTION_FORWARD = 1;
+
// these are the same for all instances so make them process wide
private static ArrayList<AccessibilityWebContentKeyBinding> sBindings =
new ArrayList<AccessibilityWebContentKeyBinding>();
// handle to the WebViewClassic this injector is associated with.
private final WebViewClassic mWebView;
+ private final WebView mWebViewInternal;
// events scheduled for sending as soon as we receive the selected text
private final Stack<AccessibilityEvent> mScheduledEventStack = new Stack<AccessibilityEvent>();
@@ -104,6 +121,7 @@ class AccessibilityInjectorFallback {
*/
public AccessibilityInjectorFallback(WebViewClassic webView) {
mWebView = webView;
+ mWebViewInternal = mWebView.getWebView();
ensureWebContentKeyBindings();
}
@@ -176,7 +194,7 @@ class AccessibilityInjectorFallback {
int fromAxis = binding.getFirstArgument(i);
int toAxis = binding.getSecondArgument(i);
sendEvent = (binding.getThirdArgument(i) == 1);
- prefromAxisTransition(fromAxis, toAxis, sendEvent, contentDescription);
+ performAxisTransition(fromAxis, toAxis, sendEvent, contentDescription);
mLastDownEventHandled = true;
break;
case ACTION_TRAVERSE_DEFAULT_WEB_VIEW_BEHAVIOR_AXIS:
@@ -214,7 +232,8 @@ class AccessibilityInjectorFallback {
private void setCurrentAxis(int axis, boolean sendEvent, String contentDescription) {
mCurrentAxis = axis;
if (sendEvent) {
- AccessibilityEvent event = getPartialyPopulatedAccessibilityEvent();
+ final AccessibilityEvent event = getPartialyPopulatedAccessibilityEvent(
+ AccessibilityEvent.TYPE_ANNOUNCEMENT);
event.getText().add(String.valueOf(axis));
event.setContentDescription(contentDescription);
sendAccessibilityEvent(event);
@@ -229,7 +248,7 @@ class AccessibilityInjectorFallback {
* @param sendEvent Flag if to send an event to announce successful transition.
* @param contentDescription A description of the performed action.
*/
- private void prefromAxisTransition(int fromAxis, int toAxis, boolean sendEvent,
+ private void performAxisTransition(int fromAxis, int toAxis, boolean sendEvent,
String contentDescription) {
if (mCurrentAxis == fromAxis) {
setCurrentAxis(toAxis, sendEvent, contentDescription);
@@ -249,6 +268,62 @@ class AccessibilityInjectorFallback {
String contentDescription) {
return traverseGivenAxis(direction, mCurrentAxis, sendEvent, contentDescription);
}
+
+ boolean performAccessibilityAction(int action, Bundle arguments) {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
+ case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
+ final int direction = getDirectionForAction(action);
+ final int axis = getAxisForGranularity(arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT));
+ return traverseGivenAxis(direction, axis, true, null);
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns the {@link WebView}-defined direction for the given
+ * {@link AccessibilityNodeInfo}-defined action.
+ *
+ * @param action An accessibility action identifier.
+ * @return A web view navigation direction.
+ */
+ private static int getDirectionForAction(int action) {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
+ return NAVIGATION_DIRECTION_FORWARD;
+ case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
+ return NAVIGATION_DIRECTION_BACKWARD;
+ default:
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the {@link WebView}-defined axis for the given
+ * {@link AccessibilityNodeInfo}-defined granularity.
+ *
+ * @param granularity An accessibility granularity identifier.
+ * @return A web view navigation axis.
+ */
+ private static int getAxisForGranularity(int granularity) {
+ switch (granularity) {
+ case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER:
+ return NAVIGATION_AXIS_CHARACTER;
+ case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD:
+ return NAVIGATION_AXIS_WORD;
+ case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE:
+ return NAVIGATION_AXIS_SENTENCE;
+ case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH:
+ // TODO: Figure out what nextSibling() actually means.
+ return NAVIGATION_AXIS_SIBLING;
+ case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE:
+ return NAVIGATION_AXIS_DOCUMENT;
+ default:
+ return -1;
+ }
+ }
/**
* Traverse the document along the given navigation axis.
@@ -268,7 +343,8 @@ class AccessibilityInjectorFallback {
AccessibilityEvent event = null;
if (sendEvent) {
- event = getPartialyPopulatedAccessibilityEvent();
+ event = getPartialyPopulatedAccessibilityEvent(
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
// the text will be set upon receiving the selection string
event.setContentDescription(contentDescription);
}
@@ -296,8 +372,10 @@ class AccessibilityInjectorFallback {
return;
}
AccessibilityEvent event = mScheduledEventStack.pop();
- if (event != null) {
+ if ((event != null) && (selectionString != null)) {
event.getText().add(selectionString);
+ event.setFromIndex(0);
+ event.setToIndex(selectionString.length());
sendAccessibilityEvent(event);
}
}
@@ -323,11 +401,9 @@ class AccessibilityInjectorFallback {
* @return An accessibility event whose members are populated except its
* text and content description.
*/
- private AccessibilityEvent getPartialyPopulatedAccessibilityEvent() {
- AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SELECTED);
- event.setClassName(mWebView.getClass().getName());
- event.setPackageName(mWebView.getContext().getPackageName());
- event.setEnabled(mWebView.getWebView().isEnabled());
+ private AccessibilityEvent getPartialyPopulatedAccessibilityEvent(int eventType) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+ mWebViewInternal.onInitializeAccessibilityEvent(event);
return event;
}