1# Chrome Accessibility on Android 2 3Chrome plays an important role on Android - not only is it the default 4browser, but Chrome powers WebView, which is used by many built-in and 5third-party apps to display all sorts of content. 6 7This document covers some of the technical details of how Chrome 8implements its accessibility support on Android. 9 10As background reading, you should be familiar with 11[https://developer.android.com/guide/topics/ui/accessibility](Android Accessibility) 12and in particular 13[https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo](AccessibilityNodeInfo) 14and 15[https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeProvider](AccessibilityNodeProvider). 16 17## WebContentsAccessibility 18 19The main Java class that implements the accessibility protocol in Chrome is 20[https://cs.chromium.org/chromium/src/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java](WebContentsAccessibilityImpl.java). It implements the AccessibilityNodeProvider 21interface, so a single Android View can be represented by an entire tree 22of virtual views. Note that WebContentsAccessibilityImpl represents an 23entire web page, including all frames. The ids in the java code are unique IDs, 24not frame-local IDs. 25 26On most platforms, we create a native object for every AXNode in a web page, 27and we implement a bunch of methods on that object that assistive technology 28can query. 29 30Android is different - it's more lightweight in one way, in that we only 31create a native AccessibilityNodeInfo when specifically requested, when 32an Android accessibility service is exploring the virtual tree. In another 33sense it's more heavyweight, though, because every time a virtual view is 34requested we have to populate it with every possible accessibility attribute, 35and there are quite a few. 36 37## Populating AccessibilityNodeInfo 38 39Populating AccessibilityNodeInfo is a bit complicated for reasons of 40Android version compatibility and also code efficiency. 41 42WebContentsAccessibilityImpl.createAccessibilityNodeInfo is the starting 43point. That's called by the Android framework when we need to provide the 44info about one virtual view (a web node). 45 46We call into C++ code - 47[https://cs.chromium.org/chromium/src/content/browser/accessibility/web_contents_accessibility_android.cc](web_contents_accessibility_android.cc) from 48there, because all of the information about the accessibility tree is 49using the shared C++ BrowserAccessibilityManager code. 50 51However, the C++ code then calls back into Java in order to set all of the 52properties of AccessibilityNodeInfo, because those have to be set in Java. 53Each of those methods, like setAccessibilityNodeInfoBooleanAttributes, is 54often overridden by an Android-version-specific subclass to take advantage 55of newer APIs where available. 56 57Having the Java code query C++ for every individual attribute one at a time 58would be too expensive, we'd be going across the JNI boundary too many times. 59That's why it's structured the way it is now. 60 61## Touch Exploration 62 63The way touch exploration works on Android is complicated: 64 65* When the user taps or drags their finger, our View gets a hover event. 66* Accessibility code sends a hit test action to the renderer process 67* The renderer process fires a HOVER accessibility event on the accessibility 68 node at that coordinate 69* WebContentsAccessibilityImpl.handleHover is called with that node. We fire 70 an Android TYPE_VIEW_HOVER_ENTER event on that node and a 71 TYPE_VIEW_HOVER_EXIT event on the previous node. 72* Finally, TalkBack sets accessibility focus to that node. 73