Loading core/java/android/webkit/AccessibilityInjector.java +34 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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); } Loading Loading @@ -236,12 +252,11 @@ 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(); Loading @@ -249,8 +264,14 @@ class AccessibilityInjector { event.setContentDescription(contentDescription); } mScheduledEventStack.push(event); webViewCore.sendMessage(EventHub.MODIFY_SELECTION, direction, axis); // 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; } Loading core/java/android/webkit/WebView.java +38 −12 Original line number Diff line number Diff line Loading @@ -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; } // 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. if (accessibilityScriptInjected()) { 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 Loading Loading @@ -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; } // 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. if (accessibilityScriptInjected()) { 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 Loading Loading @@ -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) { Loading core/java/android/webkit/WebViewCore.java +26 −2 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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: Loading packages/SettingsProvider/res/values/defaults.xml +4 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
core/java/android/webkit/AccessibilityInjector.java +34 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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); } Loading Loading @@ -236,12 +252,11 @@ 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(); Loading @@ -249,8 +264,14 @@ class AccessibilityInjector { event.setContentDescription(contentDescription); } mScheduledEventStack.push(event); webViewCore.sendMessage(EventHub.MODIFY_SELECTION, direction, axis); // 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; } Loading
core/java/android/webkit/WebView.java +38 −12 Original line number Diff line number Diff line Loading @@ -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; } // 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. if (accessibilityScriptInjected()) { 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 Loading Loading @@ -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; } // 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. if (accessibilityScriptInjected()) { 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 Loading Loading @@ -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) { Loading
core/java/android/webkit/WebViewCore.java +26 −2 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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: Loading
packages/SettingsProvider/res/values/defaults.xml +4 −4 Original line number Diff line number Diff line Loading @@ -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; Loading