Bug 1203697 - Add braille navigation. r=yzen r=mfinkle
authorEitan Isaacson <eitan@monotonous.org>
Mon, 14 Sep 2015 23:34:30 -0700
changeset 262547 b10bb607c2f0d42d863ad76a4a209536b27e67c9
parent 262546 bc496e1c596316188b986f1c6c8ab632794d7e4e
child 262548 f04c038de23638385e8652f84682eaf00cfa017f
push id29375
push usercbook@mozilla.com
push dateTue, 15 Sep 2015 13:05:38 +0000
treeherdermozilla-central@5d61714cf5c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen, mfinkle
bugs1203697
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1203697 - Add braille navigation. r=yzen r=mfinkle
accessible/jsat/AccessFu.jsm
mobile/android/base/GeckoAccessibility.java
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -853,21 +853,22 @@ var Input = {
 
   androidScroll: function androidScroll(aDirection) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     mm.sendAsyncMessage('AccessFu:AndroidScroll',
                         { direction: aDirection, origin: 'top' });
   },
 
   moveByGranularity: function moveByGranularity(aDetails) {
-    const MOVEMENT_GRANULARITY_PARAGRAPH = 8;
+    const GRANULARITY_PARAGRAPH = 8;
+    const GRANULARITY_LINE = 4;
 
     if (!this.editState.editing) {
-      if (aDetails.granularity === MOVEMENT_GRANULARITY_PARAGRAPH) {
-        this.moveCursor('move' + aDetails.direction, 'Paragraph', 'gesture');
+      if (aDetails.granularity & (GRANULARITY_PARAGRAPH | GRANULARITY_LINE)) {
+        this.moveCursor('move' + aDetails.direction, 'Simple', 'gesture');
         return;
       }
     } else {
       aDetails.atStart = this.editState.atStart;
       aDetails.atEnd = this.editState.atEnd;
     }
 
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
--- a/mobile/android/base/GeckoAccessibility.java
+++ b/mobile/android/base/GeckoAccessibility.java
@@ -332,16 +332,17 @@ public class GeckoAccessibility {
                                 info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
                                 info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
                                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
                                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
                                 info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
                                 info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
                                 info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER |
                                                               AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD |
+                                                              AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE |
                                                               AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
                                 break;
                             }
                             return info;
                         }
 
                         @Override
                         public boolean performAction (int virtualViewId, int action, Bundle arguments) {
@@ -385,51 +386,59 @@ public class GeckoAccessibility {
                                     traversalRule = arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
                                 }
                                 GeckoAppShell.
                                     sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:PreviousObject", traversalRule));
                                 return true;
                             } else if (action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY &&
                                        virtualViewId == VIRTUAL_CURSOR_POSITION) {
                                 // XXX: Self brailling gives this action with a bogus argument instead of an actual click action;
-                                // the argument value is the BRAILLE_CLICK_BASE_INDEX - the index of the routing key that was hit
+                                // the argument value is the BRAILLE_CLICK_BASE_INDEX - the index of the routing key that was hit.
+                                // Other negative values are used by ChromeVox, but we don't support them.
+                                // FAKE_GRANULARITY_READ_CURRENT = -1
+                                // FAKE_GRANULARITY_READ_TITLE = -2
+                                // FAKE_GRANULARITY_STOP_SPEECH = -3
+                                // FAKE_GRANULARITY_CHANGE_SHIFTER = -4
                                 int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
                                 if (granularity <= BRAILLE_CLICK_BASE_INDEX) {
                                     int keyIndex = BRAILLE_CLICK_BASE_INDEX - granularity;
                                     JSONObject activationData = new JSONObject();
                                     try {
                                         activationData.put("keyIndex", keyIndex);
                                     } catch (JSONException e) {
                                         return true;
                                     }
                                     GeckoAppShell.
                                         sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:ActivateObject", activationData.toString()));
-                                } else {
+                                } else if (granularity > 0) {
                                     JSONObject movementData = new JSONObject();
                                     try {
                                         movementData.put("direction", "Next");
                                         movementData.put("granularity", granularity);
                                     } catch (JSONException e) {
                                         return true;
                                     }
                                     GeckoAppShell.
                                         sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:MoveByGranularity", movementData.toString()));
                                 }
                                 return true;
                             } else if (action == AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY &&
                                        virtualViewId == VIRTUAL_CURSOR_POSITION) {
                                 JSONObject movementData = new JSONObject();
+                                int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
                                 try {
                                     movementData.put("direction", "Previous");
-                                    movementData.put("granularity", arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT));
+                                    movementData.put("granularity", granularity);
                                 } catch (JSONException e) {
                                     return true;
                                 }
-                                GeckoAppShell.
-                                    sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:MoveByGranularity", movementData.toString()));
+                                if (granularity > 0) {
+                                    GeckoAppShell.
+                                      sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:MoveByGranularity", movementData.toString()));
+                                }
                                 return true;
                             }
                             return host.performAccessibilityAction(action, arguments);
                         }
                     };
 
             return mAccessibilityNodeProvider;
         }