Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b303d838 authored by Scott Main's avatar Scott Main
Browse files

docs: a couple notes for a11y methods in View and cleanup to the

A11y service HTML to be semantically correct and thus improve its accessibility :)

Change-Id: I483a8a441d802b056f68f82e0e782d86a73298ac
parent f4b40de6
Loading
Loading
Loading
Loading
+52 −81
Original line number Original line Diff line number Diff line
@@ -32,11 +32,9 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
 * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
 * in the user interface, for example, the focus has changed, a button has been clicked,
 * in the user interface, for example, the focus has changed, a button has been clicked,
 * etc. Such a service can optionally request the capability for querying the content
 * etc. Such a service can optionally request the capability for querying the content
 * of the active window. Development of an accessibility service requires extends this
 * of the active window. Development of an accessibility service requires extending this
 * class and implements its abstract methods.
 * class and implementing its abstract methods.
 * <p>
 * <h3>Lifecycle</h3>
 * <strong>Lifecycle</strong>
 * </p>
 * <p>
 * <p>
 * The lifecycle of an accessibility service is managed exclusively by the system and
 * The lifecycle of an accessibility service is managed exclusively by the system and
 * follows the established service life cycle. Additionally, starting or stopping an
 * follows the established service life cycle. Additionally, starting or stopping an
@@ -45,30 +43,20 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * calls {@link AccessibilityService#onServiceConnected()}. This method can be
 * calls {@link AccessibilityService#onServiceConnected()}. This method can be
 * overriden by clients that want to perform post binding setup.
 * overriden by clients that want to perform post binding setup.
 * </p>
 * </p>
 * <p>
 * <h3>Declaration</h3>
 * <strong>Declaration</strong>
 * </p>
 * <p>
 * <p>
 * An accessibility is declared as any other service in an AndroidManifest.xml but it
 * An accessibility is declared as any other service in an AndroidManifest.xml but it
 * must also specify that it handles the "android.accessibilityservice.AccessibilityService"
 * must also specify that it handles the "android.accessibilityservice.AccessibilityService"
 * {@link android.content.Intent}. Failure to declare this intent will cause the system to
 * {@link android.content.Intent}. Failure to declare this intent will cause the system to
 * ignore the accessibility service. Following is an example declaration:
 * ignore the accessibility service. Following is an example declaration:
 * </p>
 * </p>
 * <p>
 * <pre> &lt;service android:name=".MyAccessibilityService"&gt;
 * <code>
 * <pre>
 *   &lt;service android:name=".MyAccessibilityService"&gt;
 *     &lt;intent-filter&gt;
 *     &lt;intent-filter&gt;
 *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
 *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
 *     &lt;/intent-filter&gt;
 *     &lt;/intent-filter&gt;
 *     . . .
 *     . . .
 *   &lt;/service&gt;
 * &lt;/service&gt;</pre>
 * </pre>
 * <h3>Configuration</h3>
 * </code>
 * </p>
 * <p>
 * <strong>Configuration</strong>
 * </p>
 * <p>
 * <p>
 * An accessibility service can be configured to receive specific types of accessibility events,
 * An accessibility service can be configured to receive specific types of accessibility events,
 * listen only to specific packages, get events from each type only once in a given time frame,
 * listen only to specific packages, get events from each type only once in a given time frame,
@@ -81,30 +69,24 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * <li>
 * <li>
 * Providing a {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring
 * Providing a {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring
 * the service. A service declaration with a meta-data tag is presented below:
 * the service. A service declaration with a meta-data tag is presented below:
 * <p>
 * <pre> &lt;service android:name=".MyAccessibilityService"&gt;
 * <code>
 * <pre>
 *   &lt;service android:name=".MyAccessibilityService"&gt;
 *     &lt;intent-filter&gt;
 *     &lt;intent-filter&gt;
 *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
 *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
 *     &lt;/intent-filter&gt;
 *     &lt;/intent-filter&gt;
 *     &lt;meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /&gt;
 *     &lt;meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /&gt;
 *   &lt;/service&gt;
 * &lt;/service&gt;</pre>
 * </pre>
 * <p class="note">
 * </code>
 * </p>
 * <p>
 * <strong>Note:</strong> This approach enables setting all properties.
 * <strong>Note:</strong> This approach enables setting all properties.
 * </p>
 * </p>
 * <p>
 * <p>
 * For more details refer to {@link #SERVICE_META_DATA} and
 * For more details refer to {@link #SERVICE_META_DATA} and
 * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>..
 * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>.
 * </p>
 * </p>
 * </li>
 * </li>
 * <li>
 * <li>
 * Calling {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. Note
 * Calling {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. Note
 * that this method can be called any time to dynamically change the service configuration.
 * that this method can be called any time to dynamically change the service configuration.
 * <p>
 * <p class="note">
 * <strong>Note:</strong> This approach enables setting only dynamically configurable properties:
 * <strong>Note:</strong> This approach enables setting only dynamically configurable properties:
 * {@link AccessibilityServiceInfo#eventTypes},
 * {@link AccessibilityServiceInfo#eventTypes},
 * {@link AccessibilityServiceInfo#feedbackType},
 * {@link AccessibilityServiceInfo#feedbackType},
@@ -117,9 +99,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * </p>
 * </p>
 * </li>
 * </li>
 * </ul>
 * </ul>
 * <p>
 * <h3>Retrieving window content</h3>
 * <strong>Retrieving window content</strong>
 * </p>
 * <p>
 * <p>
 * An service can specify in its declaration that it can retrieve the active window
 * An service can specify in its declaration that it can retrieve the active window
 * content which is represented as a tree of {@link AccessibilityNodeInfo}. Note that
 * content which is represented as a tree of {@link AccessibilityNodeInfo}. Note that
@@ -144,7 +124,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * this method will return an {@link AccessibilityNodeInfo} that can be used to traverse the
 * this method will return an {@link AccessibilityNodeInfo} that can be used to traverse the
 * window content which represented as a tree of such objects.
 * window content which represented as a tree of such objects.
 * </p>
 * </p>
 * <p>
 * <p class="note">
 * <strong>Note</strong> An accessibility service may have requested to be notified for
 * <strong>Note</strong> An accessibility service may have requested to be notified for
 * a subset of the event types, thus be unaware that the active window has changed. Therefore
 * a subset of the event types, thus be unaware that the active window has changed. Therefore
 * accessibility service that would like to retrieve window content should:
 * accessibility service that would like to retrieve window content should:
@@ -158,15 +138,13 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * <li>
 * <li>
 * Prepare that a retrieval method on {@link AccessibilityNodeInfo} may fail since the
 * Prepare that a retrieval method on {@link AccessibilityNodeInfo} may fail since the
 * active window has changed and the service did not get the accessibility event yet. Note
 * active window has changed and the service did not get the accessibility event yet. Note
 * that it is possible to have a retrieval method failing event adopting the strategy
 * that it is possible to have a retrieval method failing even adopting the strategy
 * specified in the previous bullet because the accessibility event dispatch is asynchronous
 * specified in the previous bullet because the accessibility event dispatch is asynchronous
 * and crosses process boundaries.
 * and crosses process boundaries.
 * </li>
 * </li>
 * </ul>
 * </ul>
 * </p>
 * </p>
 * <p>
 * <h3>Notification strategy</h3>
 * <b>Notification strategy</b>
 * </p>
 * <p>
 * <p>
 * For each feedback type only one accessibility service is notified. Services are notified
 * For each feedback type only one accessibility service is notified. Services are notified
 * in the order of registration. Hence, if two services are registered for the same
 * in the order of registration. Hence, if two services are registered for the same
@@ -178,40 +156,39 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * well with most applications to coexist with "polished" ones that are targeted for
 * well with most applications to coexist with "polished" ones that are targeted for
 * specific applications.
 * specific applications.
 * </p>
 * </p>
 * <p>
 * <p class="note">
 * <b>Event types</b>
 * </p>
 * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}
 * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
 * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
 * {@link AccessibilityEvent#TYPE_VIEW_SELECTED}
 * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
 * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
 * {@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
 * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
 * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
 * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
 * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
 * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
 * {@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
 * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
 * <p>
 * <b>Feedback types</b>
 * <p>
 * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
 * {@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
 * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
 * {@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
 * {@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
 *
 * @see AccessibilityEvent
 * @see AccessibilityServiceInfo
 * @see android.view.accessibility.AccessibilityManager
 *
 * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
 * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
 * events to the client too frequently since this is accomplished via an expensive
 * events to the client too frequently since this is accomplished via an expensive
 * interprocess call. One can think of the timeout as a criteria to determine when
 * interprocess call. One can think of the timeout as a criteria to determine when
 * event generation has settled down.
 * event generation has settled down.</p>
 * <h3>Event types</h3>
 * <ul>
 * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
 * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
 * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
 * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
 * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
 * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
 * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
 * </ul>
 * <h3>Feedback types</h3>
 * <ul>
 * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
 * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
 * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
 * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
 * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
 * </ul>
 * @see AccessibilityEvent
 * @see AccessibilityServiceInfo
 * @see android.view.accessibility.AccessibilityManager
 */
 */
public abstract class AccessibilityService extends Service {
public abstract class AccessibilityService extends Service {
    /**
    /**
@@ -225,10 +202,7 @@ public abstract class AccessibilityService extends Service {
     * about itself. This meta-data must reference an XML resource containing an
     * about itself. This meta-data must reference an XML resource containing an
     * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>
     * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>
     * tag. This is a a sample XML file configuring an accessibility service:
     * tag. This is a a sample XML file configuring an accessibility service:
     * <p>
     * <pre> &lt;accessibility-service
     * <code>
     * <pre>
     *   &lt;accessibility-service
     *     android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
     *     android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
     *     android:packageNames="foo.bar, foo.baz"
     *     android:packageNames="foo.bar, foo.baz"
     *     android:accessibilityFeedbackType="feedbackSpoken"
     *     android:accessibilityFeedbackType="feedbackSpoken"
@@ -237,10 +211,7 @@ public abstract class AccessibilityService extends Service {
     *     android:settingsActivity="foo.bar.TestBackActivity"
     *     android:settingsActivity="foo.bar.TestBackActivity"
     *     android:canRetrieveWindowContent="true"
     *     android:canRetrieveWindowContent="true"
     *     . . .
     *     . . .
     *   /&gt;
     * /&gt;</pre>
     * </pre>
     * </code>
     * </p>
     */
     */
    public static final String SERVICE_META_DATA = "android.accessibilityservice";
    public static final String SERVICE_META_DATA = "android.accessibilityservice";


+22 −20
Original line number Original line Diff line number Diff line
@@ -3810,7 +3810,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * responsible for handling this call.
     * responsible for handling this call.
     * </p>
     * </p>
     *
     *
     * @param eventType The type of the event to send.
     * @param eventType The type of the event to send, as defined by several types from
     * {@link android.view.accessibility.AccessibilityEvent}, such as
     * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or
     * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}.
     *
     *
     * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
     * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
     * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
     * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
@@ -3923,27 +3926,28 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
    /**
    /**
     * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
     * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
     * giving a chance to this View to populate the accessibility event with its
     * giving a chance to this View to populate the accessibility event with its
     * text content. While the implementation is free to modify other event
     * text content. While this method is free to modify event
     * attributes this should be performed in
     * attributes other than text content, doing so should normally be performed in
     * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
     * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
     * <p>
     * <p>
     * Example: Adding formatted date string to an accessibility event in addition
     * Example: Adding formatted date string to an accessibility event in addition
     *          to the text added by the super implementation.
     *          to the text added by the super implementation:
     * </p><p><pre><code>
     * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
     * public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
     *     super.onPopulateAccessibilityEvent(event);
     *     super.onPopulateAccessibilityEvent(event);
     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
     *         mCurrentDate.getTimeInMillis(), flags);
     *         mCurrentDate.getTimeInMillis(), flags);
     *     event.getText().add(selectedDateUtterance);
     *     event.getText().add(selectedDateUtterance);
     * }
     * }</pre>
     * </code></pre></p>
     * <p>
     * <p>
     * If an {@link AccessibilityDelegate} has been specified via calling
     * If an {@link AccessibilityDelegate} has been specified via calling
     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
     * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
     * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
     * is responsible for handling this call.
     * is responsible for handling this call.
     * </p>
     * </p>
     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
     * information to the event, in case the default implementation has basic information to add.
     * </p>
     *
     *
     * @param event The accessibility event which to populate.
     * @param event The accessibility event which to populate.
     *
     *
@@ -3974,20 +3978,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * the event.
     * the event.
     * <p>
     * <p>
     * Example: Setting the password property of an event in addition
     * Example: Setting the password property of an event in addition
     *          to properties set by the super implementation.
     *          to properties set by the super implementation:
     * </p><p><pre><code>
     * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
     * public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
     *     super.onInitializeAccessibilityEvent(event);
     *     super.onInitializeAccessibilityEvent(event);
     *     event.setPassword(true);
     *     event.setPassword(true);
     * }
     * }</pre>
     * </code></pre></p>
     * <p>
     * <p>
     * If an {@link AccessibilityDelegate} has been specified via calling
     * If an {@link AccessibilityDelegate} has been specified via calling
     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
     * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
     * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
     * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
     * is responsible for handling this call.
     * is responsible for handling this call.
     * </p>
     * </p>
     *
     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
     * information to the event, in case the default implementation has basic information to add.
     * </p>
     * @param event The event to initialize.
     * @param event The event to initialize.
     *
     *
     * @see #sendAccessibilityEvent(int)
     * @see #sendAccessibilityEvent(int)
@@ -6159,8 +6163,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * are delivered to the view under the pointer.  All other generic motion events are
     * are delivered to the view under the pointer.  All other generic motion events are
     * delivered to the focused view.
     * delivered to the focused view.
     * </p>
     * </p>
     * <code>
     * <pre> public boolean onGenericMotionEvent(MotionEvent event) {
     * public boolean onGenericMotionEvent(MotionEvent event) {
     *     if ((event.getSource() &amp; InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
     *     if ((event.getSource() &amp; InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
     *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
     *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
     *             // process the joystick movement...
     *             // process the joystick movement...
@@ -6178,8 +6181,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     *         }
     *         }
     *     }
     *     }
     *     return super.onGenericMotionEvent(event);
     *     return super.onGenericMotionEvent(event);
     * }
     * }</pre>
     * </code>
     *
     *
     * @param event The generic motion event being processed.
     * @param event The generic motion event being processed.
     * @return True if the event was handled, false otherwise.
     * @return True if the event was handled, false otherwise.
+6 −5
Original line number Original line Diff line number Diff line
@@ -49,10 +49,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
 * </p>
 * </p>
 * <p>
 * <p>
 * <code>
 * <code>
 * <pre>
 * <pre>AccessibilityManager accessibilityManager =
 *   AccessibilityManager accessibilityManager =
 *        (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);</pre>
 *           (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
 * </pre>
 * </code>
 * </code>
 * </p>
 * </p>
 *
 *
@@ -91,7 +89,10 @@ public final class AccessibilityManager {
        new CopyOnWriteArrayList<AccessibilityStateChangeListener>();
        new CopyOnWriteArrayList<AccessibilityStateChangeListener>();


    /**
    /**
     * Listener for the accessibility state.
     * Listener for the system accessibility state. To listen for changes to the accessibility
     * state on the device, implement this interface and register it with the system by
     * calling {@link AccessibilityManager#addAccessibilityStateChangeListener
     * addAccessibilityStateChangeListener()}.
     */
     */
    public interface AccessibilityStateChangeListener {
    public interface AccessibilityStateChangeListener {