This page is deprecated. Redirecting to https://developer.android.com/studio/intro/accessibility.html
(Current status: This work was integrated into Android Studio 1.4.)
The source editor in Android Studio 1.0 and 1.1 does not support screen readers. This is something we're trying to fix, and this document describes the technical issues involved.
The source editor is custom component (EditorComponentImpl extends JComponent), which means it doesn't have any builtin accessibility handling.
To fix this, we need to
That's all pretty straightforward. But unfortunately, when I tested this on OSX, it didn't work. The screen reader reads the text at the current caret, but when you move the caret around, or enter text, nothing happens!
It turns out that while Swing is accessible, at least on Mac OSX that's not fully true: The support for text is hardcoded to JTextComponents. And the IntelliJ source editor is not a JTextComponent (which is how it's able to do a lot of advanced features like folding text within a single line etc). Take a look at the source code for CAccessible.java, line 102:
In other words, the accessibility support is not responding to caret and document modification events by listening to properties being fired, as the documentation suggests it should. Instead, it only listens for these events by directly casting to a JTextComponent and directly listening on the document and carets, and doing nothing for non-JTextComponents.
I tried to fix this in two ways.
The first way is to create a "dummy" JTextComponent, which basically wraps the real source editor's mode. The methods to get the caret position and text contents delegate to calls in the IntelliJ source editor, and change events in the source editor are mapped back to Swing JTextComponent events. The second step here is to pretend to the accessibility system that this document component is the real source editor. I tried to do this by inserting the JTextComponent's accessibility handler into the accessibility hierarchy (e.g. the getAccessibleChildrenCount() and getAccessibleChild(int index) methods). However, I could not get this to work. I suspect there's some code in the accessibility framework or screen reader code which checks that the focused component (which has to be the real editor) is really the same as the accessibility component.
The second way, which does work, is to make the source editor component (EditorComponentImpl) actually extend JTextComponent. Note that I'm not talking about actually making the editor really be a JTextComponent. I mean make the class extend JTextComponent, and then lobotomize all the functionality such that we don't end up doing a lot of extra work. We do this by overriding all the applicable methods from JTextComponent such that they become no-ops. With the notable exception of course of the getDocument() and addCaretListeners() methods, where we return objects that can map through to the real source editor. The final challenge is that the JTextComponent constructor unconditionally does some operations that we can't avoid (since they're done in the constructor which we can't replace). This requires some extra care such that the work done is cheap (e.g. it tries to install a UI delegate, so make that a no op etc).
This is not a great solution for obvious reasons:
This is proposed in the following CL:
There are a couple of other wrinkles:
Just like CAccessible.java makes JTextComponent assumptions, so does CAccessibleText.java, so we have to make our JTextComponent implement some additional methods used there, e.g. getVisibleRect(), viewToModel(), and even Swing's Document model, getDefaultRootElement() and getElementIndex(). This is shown in the changelist.
Furthermore, also in the JDK OSX integration for accessibility, AccessibleRole.TEXT is hardcoded to be read out as a "text field", but we can create a new AccessibleRole with the exact text "textarea" which will be handled correctly.
With those changes, the source editor properly reads out source text, responds to edits and navigation around in the document.
There are other accessibility changes necessary to make this work well (in particular, the editor tabs), but those are (or soon will be) described in the general accessibility implementation document.