Android accessibility debugging with Stetho

Brett Lavalla

Android has a powerful built-in accessibility system that allows people to use applications through an alternative interaction mode called “focus navigation.” Rather than directly touching the screen to activate an element, focus navigation allows people who use accessibility services such as screen readers, physical switch devices, refreshable Braille displays, or voice control to focus on and activate different elements of an interface.

Although focus navigation is built into the Android platform, many engineers don’t consider it when designing, building, and testing their applications. This can lead to a variety of problems, such as the inability to activate buttons or content being announced in the wrong order, which can be difficult to debug.

Accessibility is important to our work at Facebook, so to help with the above challenges we’ve added support for accessibility properties to Stetho, our open source Android debugging tool. Now engineers can easily find elements that aren’t accessible through focus navigation, understand the reasons behind the bug, and implement a fix.

Let’s go over an example of a UI with a focus navigation issue and show how Stetho makes the problem easier to debug.

Screenshot showing the currently focused element highlighted in green.

Example problem

In this fairly simple UI, there are two TextViews and a Button inside a LinearLayout. The LinearLayout is found inside a ListView.

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
              android:text="Heading One"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              />
        <Button
              android:text="Action"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              />
        <TextView
              android:text="Heading Two"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              />
</LinearLayout>    
    

Which views would you expect to be focusable? If you answered "the TextViews and the Button," you'd be wrong. The correct answer is the Button and the LinearLayout.

Since focus will first fall on the LinearLayout, screen reader users will hear the content of both TextViews before the Button that is between them. This could cause confusion if the context of the button's action depended on being preceded by the first heading. For example, if the button said “Buy Now,” and the headings were the names of two different products, a user may not understand which product they would be purchasing by clicking the button. So why is this the case, how can we fix it, and most importantly, how could we have predicted this would happen?

Well, you could run every view through this flow chart, and keep note of what is focusable and what isn't.

A flow chart showing exactly why a given view may or may not be focusable.

Stetho

Or you could use Stetho! Stetho is an Android debugging platform that we open sourced last year. Since then, we've added a ton of new features, including accessibility inspection.

Screenshot of the new Stetho Accessibility Properties panel.

Stetho now includes an Accessibility Properties section that shows:

  • Whether or not a View is focusable
  • Why a View is or isn't focusable
  • Whether it is the currently focused View
  • The description that will be sent to any Accessibility Service
  • A list of supported AccessibilityActions, including any custom actions.

Let's go over these in detail.

  • Ignored: A boolean displaying whether a View will be ignored by Accessibility Services. This will always be the opposite of focusable.
  • Focusable: A boolean displaying whether a view will be focusable by Accessibility Services. This will always be the opposite of ignored.
  • Ignored-reasons: For ignored Views, a plain-text message explaining precisely why the View is being ignored.
  • Focusable-reasons: For focusable Views, a plain-text message explaining precisely why the View is focusable.

Note that "actionable" in this context means a View is clickable, long-clickable, or focusable. This could be set explicitly via setting any of those attributes, or implicitly via adding click, long-click or focus listeners.

  • Focused: For focusable Views, a boolean displaying whether this is the currently focused view.
  • Description: For focusable Views, the description that will be sent to Accessibility Services. This may simply be the contentDescription or text of the View itself, or may be computed by concatenating the descriptions of un-focusable child views.

This will not contain any additional text that individual Accessibility Services may add, such as the current state (selected, disabled, etc.) or position (in list, out of list, etc.) of the View.

  • Actions: For focusable Views, a list of all supported AccessibilityActions that can be taken on this view, including any custom actions.

Running Stetho on the original example given shows that the TextViews are not focusable because they are not actionable, and therefore their description was co-opted by their ancestor, the LinearLayout.

Screenshot showing the accessibility properties of the example TextView.

Setting android:focusable="true" on the TextViews will solve the problem by making them actionable.

<TextView
          android:text="Heading One"
          android:focusable="true"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"    
          />

When both of the TextViews are focusable, the LinearLayout will inherently become un-focusable since it has no description of its own. Stetho will tell you this is the ignored reason when you inspect the LinearLayout.

Screenshot showing the accessibility properties of the example LinearLayout.

The new accessibility additions to Stetho made the problem easy to debug and provided a clearer understanding of why the problem occurred. Stetho now makes it easier than ever to ensure your app will be a great experience for people with disabilities and other users of assistive technology.

To learn how to integrate Stetho into your app, check out our documentation. If you're interested in contributing to the project, check out Stetho on GitHub.

Keep Updated

Stay up-to-date via RSS with the latest open source project releases from Facebook, news from our Engineering teams, and upcoming events.

Subscribe
Facebook © 2017