blob: 70586e678a9a01c22d4211ac4652170b38aead3c [file] [log] [blame] [view]
dmazzoni2f489752017-02-16 03:39:161# Accessibility Overview
2
3Accessibility means ensuring that all users, including users with disabilities,
4have equal access to software. One piece of this involves basic design
5principles such as using appropriate font sizes and color contrast,
6avoiding using color to convey important information, and providing keyboard
7alternatives for anything that is normally accomplished with a pointing device.
8However, when you see the word "accessibility" in a directory name in Chromium,
9that code's purpose is to provide full access to Chromium's UI via external
10accessibility APIs that are utilized by assistive technology.
11
12**Assistive technology** here refers to software or hardware which
13makes use of these APIs to create an alternative interface for the user to
14accommodate some specific needs, for example:
15
16Assistive technology includes:
17
18* Screen readers for blind users that describe the screen using
19 synthesized speech or braille
20* Voice control applications that let you speak to the computer,
Anastasia Helfinstein4cc18b2d2019-11-12 18:22:0021* Switch Access that lets you control the computer with a small number
dmazzoni2f489752017-02-16 03:39:1622 of physical switches,
23* Magnifiers that magnify a portion of the screen, and often highlight the
24 cursor and caret for easier viewing, and
25* Assistive learning and literacy software that helps users who have a hard
26 time reading print, by highlighting and/or speaking selected text
27
28In addition, because accessibility APIs provide a convenient and universal
29way to explore and control applications, they're often used for automated
30testing scripts, and UI automation software like password managers.
31
32Web browsers play an important role in this ecosystem because they need
33to not only provide access to their own UI, but also provide access to
34all of the content of the web.
35
36Each operating system has its own native accessibility API. While the
37core APIs tend to be well-documented, it's unfortunately common for
38screen readers in particular to depend on additional undocumented or
39vendor-specific APIs in order to fully function, especially with web
40browsers, because the standard APIs are insufficient to handle the
41complexity of the web.
42
43Chromium needs to support all of these operating system and
44vendor-specific accessibility APIs in order to be usable with the full
45ecosystem of assistive technology on all platforms. Just like Chromium
46sometimes mimics the quirks and bugs of older browsers, Chromium often
47needs to mimic the quirks and bugs of other browsers' implementation
48of accessibility APIs, too.
49
50## Concepts
51
52While each operating system and vendor accessibility API is different,
53there are some concepts all of them share.
54
551. The *tree*, which models the entire interface as a tree of objects, exposed
56 to assistive technology via accessibility APIs;
572. *Events*, which let assistive technology know that a part of the tree has
58 changed somehow;
593. *Actions*, which come from assistive technology and ask the interface to
60 change.
61
62Consider the following small HTML file:
63
64```
65<html>
66<head>
67 <title>How old are you?</title>
68</head>
69<body>
70 <label for="age">Age</label>
71 <input id="age" type="number" name="age" value="42">
72 <div>
73 <button>Back</button>
74 <button>Next</button>
75 </div>
76</body>
77</html>
78```
79
80### The Accessibility Tree and Accessibility Attributes
81
82Internally, Chromium represents the accessibility tree for that web page
83using a data structure something like this:
84
85```
86id=1 role=WebArea name="How old are you?"
87 id=2 role=Label name="Age"
88 id=3 role=TextField labelledByIds=[2] value="42"
89 id=4 role=Group
90 id=5 role=Button name="Back"
91 id=6 role=Button name="Next"
92```
93
94Note that the tree structure closely resembles the structure of the
95HTML elements, but slightly simplified. Each node in the accessibility
96tree has an ID and a role. Many have a name. The text field has a value,
97and instead of a name it has labelledByIds, which indicates that its
98accessible name comes from another node in the tree, the label node
99with id=2.
100
101On a particular platform, each node in the accessibility tree is implemented
102by an object that conforms to a particular protocol.
103
104On Windows, the root node implements the IAccessible protocol and
105if you call IAccessible::get_accRole, it returns ROLE_SYSTEM_DOCUMENT,
106and if you call IAccessible::get_accName, it returns "How old are you?".
107Other methods let you walk the tree.
108
Jacobo Aragunde Pérez0af076da2022-01-13 15:38:55109The Linux accessibility API, [ATK](https://gnome.pages.gitlab.gnome.org/atk/),
110is similar to [IAccessible2](https://wiki.linuxfoundation.org/accessibility/iaccessible2/start),
Aaron Leventhal6d0183a2021-12-20 19:59:40111aka IA2. Historical note: IA2 was developed to extend MSAA/IAccessible to add
112richer document support, in a way that was harmonious with ATK, in order to
113simplify implementing them both within the same product. Both APIs are
114maintained by the Linux Foundation.
115
dmazzoni2f489752017-02-16 03:39:16116On macOS, the root node implements the NSAccessibility protocol and
117if you call [NSAccessibility accessibilityRole], it returns @"AXWebArea",
118and if you call [NSAccessibility accessibilityLabel], it returns
119"How old are you?".
120
dmazzoni2f489752017-02-16 03:39:16121The Android accessibility API is of course based on Java. The main
122data structure is AccessibilityNodeInfo. It doesn't have a role, but
123if you call AccessibilityNodeInfo.getClassName() on the root node
124it returns "android.webkit.WebView", and if you call
125AccessibilityNodeInfo.getContentDescription() it returns "How old are you?".
126
127On Chrome OS, we use our own accessibility API that closely maps to
128Chrome's internal accessibility API.
129
130So while the details of the interface vary, the underlying concepts are
131similar. Both IAccessible and NSAccessibility have a concept of a role,
132but IAccessible uses a role of "document" for a web page, while NSAccessibility
133uses a role of "web area". Both IAccessible and NSAccessibility have a
134concept of the primary accessible text for a node, but IAccessible calls
135it the "name" while NSAccessibility calls it the "label", and Android
136calls it a "content description".
137
138**Historical note:** The internal names of roles and attributes in
139Chrome often tend to most closely match the macOS accessibility API
140because Chromium was originally based on WebKit, where most of the
141accessibility code was written by Apple. Over time we're slowly
142migrating internal names to match what those roles and attributes are
143called in web accessibility standards, like ARIA.
144
145### Accessibility Events
146
147In Chromium's internal terminology, an Accessibility Event always represents
148communication from the app to the assistive technology, indicating that the
149accessibility tree changed in some way.
150
151As an example, if the user were to press the Tab key and the text
152field from the example above became focused, Chromium would fire a
153"focus" accessibility event that assistive technology could listen
154to. A screen reader might then announce the name and current value of
155the text field. A magnifier might zoom the screen to its bounding
156box. If the user types some text into the text field, Chromium would
157fire a "value changed" accessibility event.
158
159As with nodes in the accessibility tree, each platform has a slightly different
160API for accessibility events. On Windows we'd fire EVENT_OBJECT_FOCUS for
161a focus change, and on Mac we'd fire @"AXFocusedUIElementChanged".
162Those are pretty similar. Sometimes they're quite different - to support
163live regions (notifications that certain key parts of a web page have changed),
164on Mac we simply fire @"AXLiveRegionChanged", but on Windows we need to
165fire IA2_EVENT_TEXT_INSERTED and IA2_EVENT_TEXT_REMOVED events individually
166on each affected node within the changed region, with additional attributes
167like "container-live:polite" to indicate that the affected node was part of
168a live region. This discussion is not meant to explain all of the technical
169details but just to illustrate that the concepts are similar,
170but the details of notifying software on each platform about changes can
171vary quite a bit.
172
173### Accessibility Actions
174
175Each native object that implements a platform's native accessibility API
176supports a number of actions, which are requests from the assistive
177technology to control or change the UI. This is the opposite of events,
178which are messages from Chromium to the assistive technology.
179
180For example, if the user had a voice control application running, such as
181Voice Access on Android, the user could just speak the name of one of the
182buttons on the page, like "Next". Upon recognizing that text and finding
183that it matches one of the UI elements on the page, the voice control
184app executes the action to click the button id=6 in Chromium's accessibility
185tree. Internally we call that action "do default" rather than click, since
186it represents the default action for any type of control.
187
188Other examples of actions include setting focus, changing the value of
189a control, and scrolling the page.
190
191### Parameterized attributes
192
193In addition to accessibility attributes, events, and actions, native
194accessibility APIs often have so-called "parameterized attributes".
195The most common example of this is for text - for example there may be
196a function to retrieve the bounding box for a range of text, or a
197function to retrieve the text properties (font family, font size,
198weight, etc.) at a specific character position.
199
200Parameterized attributes are particularly tricky to implement because
Katie Dektar4a165e1b2017-09-27 16:15:13201of Chromium's multi-process architecture. More on this below.
202
203### Tools for inspecting the Accessibility tree
204
205Developers can inspect the accessibility tree in several ways:
206
207* By navigating to [chrome://accessibility/](chrome://accessibility)
208and inspecting a tree directly. Note that you may want to enable the
209'Internal' option. Click 'show accessibility tree' for a particular tab,
210then click again to refresh that tree.
Jacobo Aragunde Pérez0af076da2022-01-13 15:38:55211* Using the [Automation API](
212https://developer.chrome.com/extensions/automation).
213* Installing the [Automation Inspector Chrome extension](
214https://github.com/google/automation-inspector).
David Tseng50445dd2022-04-12 19:42:02215* Building and using [ax_dump_tree or ax_dump_events](../../tools/accessibility/inspect/README.md).
Aaron Leventhal6d0183a2021-12-20 19:59:40216These can be used to view accessibility trees and events from any application on
217Windows, Mac or Linux.
Katie Dektar4a165e1b2017-09-27 16:15:13218* Or by using native tools:
219
220 - Android: UIAutomatorViewer
221 - macOS: Accessibility Inspector
222 - Windows: Inspect, AViewer, accProbe (and many others)
223
Amanda Lin Dietz375d922c92023-04-17 18:28:48224### Command Line Options
225
226Accessibility features in Chrome are off by default and enabled automatically
227on-demand. When running Chrome from the command line, certain options can be
228used to impact the behavior of the Chrome accessibility engine at launch.
229
230* `--force-renderer-accessibility=[basic|form-controls|complete]`: Force
231 accessibility to be enabled, with optional parameter to force the AXMode
Amanda Lin Dietz62d7a522023-04-18 21:16:13232 to one of the predefined bundles during the entire execution. If the optional
233 parameter is invalid, then the default AXMode will be `complete`. If the
234 optional parameter is missing, then the AXMode will initially default to
235 `complete` but allow changes to the mode during execution.
Amanda Lin Dietz375d922c92023-04-17 18:28:48236* `--disable-renderer-accessibility`: Disable accessibility
237
Kevin Babbitt805b7812021-06-14 18:18:16238### Supported Platforms and APIs
239
240* Windows: IAccessible (also known as Microsoft Active Accessibility or MSAA),
David Tseng7f8ddfb2021-11-01 19:32:59241 IAccessible2, [UI Automation](browser/uiautomation.md). Chromium also supports
242 [mapping between IAccessible2 and UI Automation nodes](browser/ia2_to_uia.md).
Kevin Babbitt805b7812021-06-14 18:18:16243* Mac: NSAccessibility
244* Linux: ATK
David Tseng7f8ddfb2021-11-01 19:32:59245* Android: [AccessibilityNodeInfo and AccessibilityNodeProvider](browser/android.md)
dmazzoni2f489752017-02-16 03:39:16246
247## Chromium's multi-process architecture
248
249Native accessibility APIs tend to have a *functional* interface, where
250Chromium implements an interface for a canonical accessible object that
251includes methods to return various attributes, walk the tree, or perform
252an action like click(), focus(), or setValue(...).
253
254In contrast, the web has a largely *declarative* interface. The shape
255of the accessibility tree is determined by the DOM tree (occasionally
256influenced by CSS), and the accessible semantics of a DOM element can
257be modified by adding ARIA attributes.
258
259One important complication is that all of these native accessibility APIs
260are *synchronous*, while Chromium is multi-process, with the contents of
261each web page living in a different process than the process that
262implements Chromium's UI and the native accessibility APIs. Furthermore,
263the renderer processes are *sandboxed*, so they can't implement
264operating system APIs directly.
265
266If you're unfamiliar with Chrome's multi-process architecture, see
267[this blog post introducing the concept](
268https://blog.chromium.org/2008/09/multi-process-architecture.html) or
269[the design doc on chromium.org](
270https://www.chromium.org/developers/design-documents/multi-process-architecture)
271for an intro.
272
273Chromium's multi-process architecture means that we can't implement
274accessibility APIs the same way that a single-process browser can -
275namely, by calling directly into the DOM to compute the result of each
276API call. For example, on some operating systems there might be an API
277to get the bounding box for a particular range of characters on the
278page. In other browsers, this might be implemented by creating a DOM
279selection object and asking for its bounding box.
280
281That implementation would be impossible in Chromium because it'd require
282blocking the main thread while waiting for a response from the renderer
283process that implements that web page's DOM. (Not only is blocking the
284main thread strictly disallowed, but the latency of doing this for every
285API call makes it prohibitively slow anyway.) Instead, Chromium takes an
286approach where a representation of the entire accessibility tree is
287cached in the main process. Great care needs to be taken to ensure that
288this representation is as concise as possible.
289
290In Chromium, we build a data structure representing all of the
291information for a web page's accessibility tree, send the data
292structure from the renderer process to the main browser process, cache
293it in the main browser process, and implement native accessibility
294APIs using solely the information in that cache.
295
296As the accessibility tree changes, tree updates and accessibility events
297get sent from the renderer process to the browser process. The browser
298cache is updated atomically in the main thread, so whenever an external
299client (like assistive technology) calls an accessibility API function,
300we're always returning something from a complete and consistent snapshot
301of the accessibility tree. From time to time, the cache may lag what's
302in the renderer process by a fraction of a second.
303
304Here are some of the specific challenges faced by this approach and
305how we've addressed them.
306
307### Sparse data
308
309There are a *lot* of possible accessibility attributes for any given
310node in an accessibility tree. For example, there are more than 150
311unique accessibility API methods that Chrome implements on the Windows
312platform alone. We need to implement all of those APIs, many of which
313request rather rare or obscure attributes, but storing all possible
314attribute values in a single struct would be quite wasteful.
315
316To avoid each accessible node object containing hundreds of fields the
317data for each accessibility node is stored in a relatively compact
318data structure, ui::AXNodeData. Every AXNodeData has an integer ID, a
319role enum, and a couple of other mandatory fields, but everything else
320is stored in attribute arrays, one for each major data type.
321
322```
323struct AXNodeData {
324 int32_t id;
Dominic Mazzonidcef1b732018-01-26 17:57:04325 ax::mojom::Role role;
dmazzoni2f489752017-02-16 03:39:16326 ...
Dominic Mazzonidcef1b732018-01-26 17:57:04327 std::vector<std::pair<ax::mojom::StringAttribute, std::string>> string_attributes;
328 std::vector<std::pair<ax::mojom::IntAttribute, int32_t>> int_attributes;
dmazzoni2f489752017-02-16 03:39:16329 ...
330}
331```
332
333So if a text field has a placeholder attribute, we can store
334that by adding an entry to `string_attributes` with an attribute
Dominic Mazzonidcef1b732018-01-26 17:57:04335of ax::mojom::StringAttribute::kPlaceholder and the placeholder string as the value.
dmazzoni2f489752017-02-16 03:39:16336
337### Incremental tree updates
338
339Web pages change frequently. It'd be terribly inefficient to send a
340new copy of the accessibility tree every time any part of it changes.
341However, the accessibility tree can change shape in complicated ways -
342for example, whole subtrees can be reparented dynamically.
343
344Rather than writing code to deal with every possible way the
345accessibility tree could be modified, Chromium has a general-purpose
346tree serializer class that's designed to send small incremental
347updates of a tree from one process to another. The tree serializer has
348just a few requirements:
349
350* Every node in the tree must have a unique integer ID.
351* The tree must be acyclic.
352* The tree serializer must be notified when a node's data changes.
353* The tree serializer must be notified when the list of child IDs of a
354 node changes.
355
356The tree serializer doesn't know anything about accessibility attributes.
357It keeps track of the previous state of the tree, and every time the tree
358structure changes (based on notifications of a node changing or a node's
359children changing), it walks the tree and builds up an incremental tree
360update that serializes as few nodes as possible.
361
362In the other process, the Unserialization code applies the incremental
363tree update atomically.
364
365### Text bounding boxes
366
367One challenge faced by Chromium is that accessibility clients want to be
368able to query the bounding box of an arbitrary range of text - not necessarily
369just the current cursor position or selection. As discussed above, it's
370not possible to block Chromium's main browser process while waiting for this
371information from Blink, so instead we cache enough information to satisfy these
372queries in the accessibility tree.
373
374To compactly store the bounding box of every character on the page, we
375split the text into *inline text boxes*, sometimes called *text runs*.
376For example, in a typical paragraph, each line of text would be its own
Quinten Yearsley317532d2021-10-20 17:10:31377inline text box. In general, an inline text box or text run contains a
dmazzoni2f489752017-02-16 03:39:16378sequence of text characters that are all oriented in the same direction,
379in a line, with the same font, size, and style.
380
381Each inline text box stores its own bounding box, and then the relative
382x-coordinate of each character in its text (assuming left-to-right).
383From that it's possible to compute the bounding box
384of any individual character.
385
386The inline text boxes are part of Chromium's internal accessibility tree.
387They're used purely internally and aren't ever exposed directly via any
388native accessibility APIs.
389
390For example, suppose that a document contains a text field with the text
391"Hello world", but the field is narrow, so "Hello" is on the first line and
392"World" is on the second line. Internally Chromium's accessibility tree
393might look like this:
394
395```
396staticText location=(8, 8) size=(38, 36) name='Hello world'
397 inlineTextBox location=(0, 0) size=(36, 18) name='Hello ' characterOffsets=12,19,23,28,36
398 inlineTextBox location=(0, 18) size=(38, 18) name='world' characterOffsets=12,20,25,29,37
399```
400
401### Scrolling, transformations, and animation
402
403Native accessibility APIs typically want the bounding box of every element in the
404tree, either in window coordinates or global screen coordinates. If we
405stored the global screen coordinates for every node, we'd be constantly
406re-serializing the whole tree every time the user scrolls or drags the
407window.
408
409Instead, we store the bounding box of each node in the accessibility tree
410relative to its *offset container*, which can be any ancestor. If no offset
411container is specified, it's assumed to be the root of the tree.
412
413In addition, any offset container can contain scroll offsets, which can be
414used to scroll the bounding boxes of anything in that subtree.
415
416Finally, any offset container can also include an arbitrary 4x4 transformation
417matrix, which can be used to represent arbitrary 3-D rotations, translations, and
418scaling, and more. The transformation matrix applies to the whole subtree.
419
420Storing coordinates this way means that any time an object scrolls, moves, or
421animates its position and scale, only the root of the scrolling or animation
422needs to post updates to the accessibility tree. Everything in the subtree
423remains valid relative to that offset container.
424
425Computing the global screen coordinates for an object in the accessibility
426tree just means walking up its ancestor chain and applying offsets and
427occasionally multiplying by a 4x4 matrix.
428
429### Site isolation / out-of-process iframes
430
431At one point in time, all of the content of a single Tab or other web view
432was contained in the same Blink process, and it was possible to serialize
433the accessibility tree for a whole frame tree in a single pass.
434
435Today the situation is a bit more complicated, as Chromium supports
436out-of-process iframes. (It also supports "browser plugins" such as
437the `<webview>` tag in Chrome packaged apps, which embeds a whole
438browser inside a browser, but for the purposes of accessibility this
439is handled the same as frames.)
440
441Rather than a mix of in-process and out-of-process frames that are handled
442differently, Chromium builds a separate independent accessibility tree
443for each frame. Each frame gets its own tree ID, and it keeps track of
444the tree ID of its parent frame (if any) and any child frames.
445
446In Chrome's main browser process, the accessibility trees for each frame
447are cached separately, and when an accessibility client (assistive
448technology) walks the accessibility tree, Chromium dynamically composes
449all of the frames into a single virtual accessibility tree on the fly,
450using those aforementioned tree IDs.
451
452The node IDs for accessibility trees only need to be unique within a
453single frame. Where necessary, separate unique IDs are used within
454Chrome's main browser process. In Chromium accessibility, a "node ID"
455always means that ID that's only unique within a frame, and a "unique ID"
456means an ID that's globally unique.
457
458## Blink
459
460Blink constructs an accessibility tree (a hierarchy of [WebAXObject]s) from the
sashabb498325a2017-05-17 01:18:46461page it is rendering. WebAXObject is the public API wrapper around [AXObject],
462which is the core class of Blink's accessibility tree. AXObject is an abstract
dmazzoni2f489752017-02-16 03:39:16463class; the most commonly used concrete subclass of it is [AXNodeObject], which
464wraps a [Node]. In turn, most AXNodeObjects are actually [AXLayoutObject]s,
465which wrap both a [Node] and a [LayoutObject]. Access to the LayoutObject is
sashabb498325a2017-05-17 01:18:46466important because some elements are only in the AXObject tree depending on their
dmazzoni2f489752017-02-16 03:39:16467visibility, geometry, linewrapping, and so on. There are some subclasses of
468AXLayoutObject that implement special-case logic for specific types of Node.
sashabb498325a2017-05-17 01:18:46469There are also other subclasses of AXObject, which are mostly used for testing.
dmazzoni2f489752017-02-16 03:39:16470
471Note that not all AXLayoutObjects correspond to actual Nodes; some are synthetic
472layout objects which group related inline elements or similar.
473
474The central class responsible for dealing with accessibility events in Blink is
475[AXObjectCacheImpl], which is responsible for caching the corresponding
476AXObjects for Nodes or LayoutObjects. This class has many methods named
477`handleFoo`, which are called throughout Blink to notify the AXObjectCacheImpl
478that it may need to update its tree. Since this class is already aware of all
479accessibility events in Blink, it is also responsible for relaying accessibility
480events from Blink to the embedding content layer.
481
482## The content layer
483
484The content layer lives on both sides of the renderer/browser split. The content
Dan Clark22562222021-08-24 22:39:50485layer translates WebAXObjects into [ui::AXNodeData]. The ui::AXNodeData class
486and related classes are Chromium's cross-platform accessibility tree. The
487translation is implemented in [BlinkAXTreeSource]. This translation happens on
488the renderer side, so the ui::AXNodeData tree now needs to be sent to the
489browser, which is done by calling the remote method
490[ax.mojom.RenderAccessibilityHost::HandleAXEvents()] with the payload being
491serialized delta-updates to the tree, so that changes that happen on the
492renderer side can be reflected on the browser side.
dmazzoni2f489752017-02-16 03:39:16493
494On the browser side, these IPCs are received by [RenderFrameHostImpl], and then
495usually forwarded to [BrowserAccessibilityManager] which is responsible for:
496
4971. Merging AXNodeData trees into one tree of [BrowserAccessibility] objects,
498 by linking to other BrowserAccessibilityManagers. This is important because
499 each page has its own accessibility tree, but each Chromium *window* must
500 have only one accessibility tree, so trees from multiple pages need to be
501 combined (possibly also with trees from Views UI).
5022. Dispatching outgoing accessibility events to the platform's accessibility
503 APIs. This is done in the platform-specific subclasses of
504 BrowserAccessibilityManager, in a method named `NotifyAccessibilityEvent`.
5053. Dispatching incoming accessibility actions to the appropriate recipient, via
Nektarios Paisios5f9a4d9a2022-10-11 16:37:26506 [AXPlatformTreeManagerDelegate]. For messages destined for a renderer,
Jacques Newmanab0be722024-03-08 23:14:04507 [RenderFrameHostImpl] is responsible for calling the remote method
Mario Sanchez Prada52f04e72020-04-22 15:34:21508 [ax.mojom.RenderAccessibility.PerformAction()], implemented by the renderer,
509 with the appropriate payload (of type [ax.mojom.AXActionData]). This IPC call
510 will be received by [RenderAccessibilityManager], which will then relay on
511 the [RenderAccessibilityImpl] where the actual logic is implemented.
dmazzoni2f489752017-02-16 03:39:16512
513On Chrome OS, RenderFrameHostImpl does not route events to
514BrowserAccessibilityManager at all, since there is no platform screenreader
515outside Chromium to integrate with.
516
517## Views
518
David Tseng0fa4a632019-05-23 23:57:46519Views generates a [ViewAccessibility] for each View, which is used as the
dmazzoni2f489752017-02-16 03:39:16520delegate for an [AXPlatformNode] representing that View. This part is relatively
521straightforward, but then the generated tree must be combined with the web
522accessibility tree, which is handled by BrowserAccessibilityManager.
523
524## WebUI
525
526Since WebUI surfaces have renderer processes as normal, WebUI accessibility goes
527through the blink-to-content-to-platform pipeline described above. Accessibility
528for WebUI is largely implemented in JavaScript in [webui-js]; these classes take
529care of adding ARIA attributes and so on to DOM nodes as needed.
530
531## The Chrome OS layer
532
533The accessibility tree is also exposed via the [chrome.automation API], which
534gives extension JavaScript access to the accessibility tree, events, and
535actions. This API is implemented in C++ by [AutomationInternalCustomBindings],
536which is renderer-side code, and in JavaScript by the [automation API]. The API
537is defined by [automation.idl], which must be kept synchronized with
Chris Halldd6f87c2019-10-14 05:20:47538[ax_enums.mojom].
dmazzoni2f489752017-02-16 03:39:16539
Dominic Mazzoni7821334d2021-09-01 20:41:40540## Further reading
541
David Tseng7f8ddfb2021-11-01 19:32:59542For more detail on Chrome web contents and platform accessibility, read [How Chrome Accessibility Works](browser/how_a11y_works.md).
543
David Tsengb2b326c2022-02-09 15:41:31544For more detail on Chrome OS accessibility, read [How Chrome OS Accessibility Works](os/how_a11y_works.md).
Dominic Mazzoni7821334d2021-09-01 20:41:40545
John Palmer046f9872021-05-24 01:24:56546[ax.mojom.AXActionData]: https://source.chromium.org/chromium/chromium/src/+/main:ui/accessibility/mojom/ax_action_data.mojom;l=13
547[ax.mojom.RenderAccessibilityHost::HandleAXEvents()]: https://source.chromium.org/chromium/chromium/src/+/main:content/common/render_accessibility.mojom;l=47
548[ax.mojom.RenderAccessibility.PerformAction()]: https://source.chromium.org/chromium/chromium/src/+/main:content/common/render_accessibility.mojom;l=86
Katie De5c2c702019-06-26 17:54:50549[AutomationInternalCustomBindings]: https://cs.chromium.org/chromium/src/extensions/renderer/api/automation/automation_internal_custom_bindings.h
Kent Tamura6943cf792018-04-09 05:24:54550[AXLayoutObject]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
551[AXNodeObject]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/accessibility/ax_node_object.h
Sharon Yang8c9500e2019-06-14 17:41:40552[AXObject]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/accessibility/ax_object.h
Kent Tamura6943cf792018-04-09 05:24:54553[AXObjectImpl]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/accessibility/ax_object_impl.h
554[AXObjectCacheImpl]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
dmazzoni2f489752017-02-16 03:39:16555[AXPlatformNode]: https://cs.chromium.org/chromium/src/ui/accessibility/platform/ax_platform_node.h
556[AXTreeSerializer]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree_serializer.h
557[BlinkAXTreeSource]: https://cs.chromium.org/chromium/src/content/renderer/accessibility/blink_ax_tree_source.h
Jacques Newman6f230d782024-08-26 19:13:34558[BrowserAccessibility]: https://cs.chromium.org/chromium/src/ui/accessibility/platform/browser_accessibility.h
559[BrowserAccessibilityManager]: https://cs.chromium.org/chromium/src/ui/accessibility/platform/browser_accessibility_manager.h
Kent Tamura6943cf792018-04-09 05:24:54560[LayoutObject]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/layout/layout_object.h
Nektarios Paisios5f9a4d9a2022-10-11 16:37:26561[AXPlatformTreeManagerDelegate]: https://cs.chromium.org/chromium/src/ui/accessibility/platform/ax_platform_tree_manager_delegate.h
David Tseng0fa4a632019-05-23 23:57:46562[ViewAccessibility]: https://cs.chromium.org/chromium/src/ui/views/accessibility/view_accessibility.h
Sharon Yang8c9500e2019-06-14 17:41:40563[Node]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/dom/node.h
dmazzoni2f489752017-02-16 03:39:16564[RenderAccessibilityImpl]: https://cs.chromium.org/chromium/src/content/renderer/accessibility/render_accessibility_impl.h
John Palmer046f9872021-05-24 01:24:56565[RenderAccessibilityManager]: https://source.chromium.org/chromium/chromium/src/+/main:content/renderer/accessibility/render_accessibility_manager.h
danakjd3baa132020-09-10 15:33:56566[RenderFrameHostImpl]: https://cs.chromium.org/chromium/src/content/browser/renderer_host/render_frame_host_impl.h
dmazzoni2f489752017-02-16 03:39:16567[ui::AXNodeData]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_node_data.h
Kent Tamura6943cf792018-04-09 05:24:54568[WebAXObject]: https://cs.chromium.org/chromium/src/third_party/blink/public/web/web_ax_object.h
dmazzoni2f489752017-02-16 03:39:16569[automation API]: https://cs.chromium.org/chromium/src/chrome/renderer/resources/extensions/automation
Katie De5c2c702019-06-26 17:54:50570[automation.idl]: https://cs.chromium.org/chromium/src/extensions/common/api/automation.idl
Chris Halldd6f87c2019-10-14 05:20:47571[ax_enums.mojom]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_enums.mojom
dmazzoni2f489752017-02-16 03:39:16572[chrome.automation API]: https://developer.chrome.com/extensions/automation
573[webui-js]: https://cs.chromium.org/chromium/src/ui/webui/resources/js/cr/ui/