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