diff options
-rw-r--r-- | core/java/android/webkit/AccessibilityInjector.java | 47 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 50 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewCore.java | 28 | ||||
-rw-r--r-- | packages/SettingsProvider/res/values/defaults.xml | 8 |
4 files changed, 102 insertions, 31 deletions
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java index bb20fb6..5198a0e 100644 --- a/core/java/android/webkit/AccessibilityInjector.java +++ b/core/java/android/webkit/AccessibilityInjector.java @@ -71,6 +71,7 @@ class AccessibilityInjector { private static final int ACTION_TRAVERSE_CURRENT_AXIS = 1; private static final int ACTION_TRAVERSE_GIVEN_AXIS = 2; 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 private static final int NAVIGATION_AXIS_DEFAULT_WEB_VIEW_BEHAVIOR = 7; @@ -153,7 +154,6 @@ class AccessibilityInjector { direction = binding.getFirstArgument(i); // on second null selection string in same direction => WebView handle the event if (direction == mLastDirection && mIsLastSelectionStringNull) { - mLastDirection = direction; mIsLastSelectionStringNull = false; return false; } @@ -170,6 +170,22 @@ class AccessibilityInjector { prefromAxisTransition(fromAxis, toAxis, sendEvent, contentDescription); mLastDownEventHandled = true; break; + case ACTION_TRAVERSE_DEFAULT_WEB_VIEW_BEHAVIOR_AXIS: + // This is a special case since we treat the default WebView navigation + // behavior as one of the possible navigation axis the user can use. + // If we are not on the default WebView navigation axis this is NOP. + if (mCurrentAxis == NAVIGATION_AXIS_DEFAULT_WEB_VIEW_BEHAVIOR) { + // While WebVew handles navigation we do not get null selection + // strings so do not check for that here as the cases above. + mLastDirection = binding.getFirstArgument(i); + sendEvent = (binding.getSecondArgument(i) == 1); + traverseGivenAxis(mLastDirection, NAVIGATION_AXIS_DEFAULT_WEB_VIEW_BEHAVIOR, + sendEvent, contentDescription); + mLastDownEventHandled = false; + } else { + mLastDownEventHandled = true; + } + break; default: Log.w(LOG_TAG, "Unknown action code: " + actionCode); } @@ -236,21 +252,26 @@ class AccessibilityInjector { */ private boolean traverseGivenAxis(int direction, int axis, boolean sendEvent, String contentDescription) { - // if the axis is the default let WebView handle the event - if (axis == NAVIGATION_AXIS_DEFAULT_WEB_VIEW_BEHAVIOR) { + WebViewCore webViewCore = mWebView.getWebViewCore(); + if (webViewCore == null) { return false; } - WebViewCore webViewCore = mWebView.getWebViewCore(); - if (webViewCore != null) { - AccessibilityEvent event = null; - if (sendEvent) { - event = getPartialyPopulatedAccessibilityEvent(); - // the text will be set upon receiving the selection string - event.setContentDescription(contentDescription); - } - mScheduledEventStack.push(event); - webViewCore.sendMessage(EventHub.MODIFY_SELECTION, direction, axis); + + AccessibilityEvent event = null; + if (sendEvent) { + event = getPartialyPopulatedAccessibilityEvent(); + // the text will be set upon receiving the selection string + event.setContentDescription(contentDescription); } + mScheduledEventStack.push(event); + + // if the axis is the default let WebView handle the event which will + // result in cursor ring movement and selection of its content + if (axis == NAVIGATION_AXIS_DEFAULT_WEB_VIEW_BEHAVIOR) { + return false; + } + + webViewCore.sendMessage(EventHub.MODIFY_SELECTION, direction, axis); return true; } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index d068d82..31636bd 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -4540,19 +4540,23 @@ public class WebView extends AbsoluteLayout // Bubble up the key event if // 1. it is a system key; or // 2. the host application wants to handle it; - // 3. the accessibility injector is present and wants to handle it; if (event.isSystem() - || mCallbackProxy.uiOverrideKeyEvent(event) - || (mAccessibilityInjector != null && mAccessibilityInjector.onKeyEvent(event))) { + || mCallbackProxy.uiOverrideKeyEvent(event)) { return false; } - // if an accessibility script is injected we delegate to it the key handling. - // this script is a screen reader which is a fully fledged solution for blind - // users to navigate in and interact with web pages. + // accessibility support if (accessibilityScriptInjected()) { + // if an accessibility script is injected we delegate to it the key handling. + // this script is a screen reader which is a fully fledged solution for blind + // users to navigate in and interact with web pages. mWebViewCore.sendMessage(EventHub.KEY_DOWN, event); return true; + } else if (mAccessibilityInjector != null && mAccessibilityInjector.onKeyEvent(event)) { + // 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 true; } if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT @@ -4702,19 +4706,23 @@ public class WebView extends AbsoluteLayout // Bubble up the key event if // 1. it is a system key; or // 2. the host application wants to handle it; - // 3. the accessibility injector is present and wants to handle it; if (event.isSystem() - || mCallbackProxy.uiOverrideKeyEvent(event) - || (mAccessibilityInjector != null && mAccessibilityInjector.onKeyEvent(event))) { + || mCallbackProxy.uiOverrideKeyEvent(event)) { return false; } - // if an accessibility script is injected we delegate to it the key handling. - // this script is a screen reader which is a fully fledged solution for blind - // users to navigate in and interact with web pages. + // accessibility support if (accessibilityScriptInjected()) { + // if an accessibility script is injected we delegate to it the key handling. + // this script is a screen reader which is a fully fledged solution for blind + // users to navigate in and interact with web pages. mWebViewCore.sendMessage(EventHub.KEY_UP, event); return true; + } else if (mAccessibilityInjector != null && mAccessibilityInjector.onKeyEvent(event)) { + // 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 true; } if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT @@ -7791,6 +7799,24 @@ public class WebView extends AbsoluteLayout cursorData()); } + /* + * Called from JNI when the cursor has moved. This method + * sends a message to the WebCore requesting the given + * nodePtr in the given framePrt to be selected which will + * result in firing an accessibility event announing its + * content. + * + * Note: Accessibility support. + */ + @SuppressWarnings("unused") + // called from JNI + private void sendMoveSelection(int framePtr, int nodePtr) { + if (AccessibilityManager.getInstance(mContext).isEnabled() + && mAccessibilityInjector != null) { + mWebViewCore.sendMessage(EventHub.MOVE_SELECTION, framePtr, nodePtr); + } + } + // called by JNI private void sendMotionUp(int touchGeneration, int frame, int node, int x, int y) { diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 5479d55..a482b74 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -627,6 +627,8 @@ final class WebViewCore { /** * Modifies the current selection. * + * Note: Accessibility support. + * * @param direction The direction in which to alter the selection. * @param granularity The granularity of the selection modification. * @@ -634,6 +636,18 @@ final class WebViewCore { */ private native String nativeModifySelection(int direction, int granularity); + /** + * Moves the selection to given node i.e. selects that node. + * + * Note: Accessibility support. + * + * @param framePtr Pointer to the frame containing the node to be selected. + * @param nodePtr Pointer to the node to be selected. + * + * @return The selection string. + */ + private native String nativeMoveSelection(int framePtr, int nodePtr); + // EventHub for processing messages private final EventHub mEventHub; // WebCore thread handler @@ -994,6 +1008,9 @@ final class WebViewCore { static final int PROXY_CHANGED = 193; + // accessibility support + static final int MOVE_SELECTION = 194; + // private message ids private static final int DESTROY = 200; @@ -1401,9 +1418,16 @@ final class WebViewCore { break; case MODIFY_SELECTION: - String selectionString = nativeModifySelection(msg.arg1, msg.arg2); + String modifiedSelectionString = nativeModifySelection(msg.arg1, + msg.arg2); + mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED, + modifiedSelectionString).sendToTarget(); + break; + + case MOVE_SELECTION: + String movedSelectionString = nativeMoveSelection(msg.arg1, msg.arg2); mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED, - selectionString).sendToTarget(); + movedSelectionString).sendToTarget(); break; case LISTBOX_CHOICES: diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 8a6e82d..066b8e7 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -85,10 +85,10 @@ 0x13=0x01000100; <!-- DPAD/Trackball DOWN maps to traverse next on current axis and send an event. --> 0x14=0x01010100; - <!-- DPAD/Trackball LEFT maps to action in non-android default navigation axis. --> - 0x15=0x04000000; - <!-- DPAD/Trackball RIGHT maps to no action in non-android default navigation axis. --> - 0x16=0x04000000; + <!-- DPAD/Trackball LEFT maps to action in the android default navigation axis. --> + 0x15=0x04000100; + <!-- DPAD/Trackball RIGHT maps to no action in the android default navigation axis. --> + 0x16=0x04010100; <!-- Left Alt+DPAD/Trackball UP transitions from an axis to another and sends an event. --> <!-- Axis transitions: 2 -> 7; 1 -> 2; 0 -> 1; 3 -> 0; 4 -> 0; 5 -> 0; 6 -> 0; --> 0x120013=0x03020701:0x03010201:0x03000101:0x03030001:0x03040001:0x03050001:0x03060001; |