From 38e8b4e5bc3c93affdffbc064fd9db5aeccc3e8e Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Wed, 29 Jun 2011 20:00:53 -0700 Subject: Updating accessibility documentation. Change-Id: Ice8cf9ac6918b3bfa553776c68d4619fa6559cf8 --- .../accessibilityservice/AccessibilityService.java | 265 ++++++++++++--------- .../AccessibilityServiceInfo.java | 29 ++- .../java/android/accessibilityservice/package.html | 22 ++ .../view/accessibility/AccessibilityEvent.java | 188 +++++++++------ .../accessibility/AccessibilityEventSource.java | 14 +- .../view/accessibility/AccessibilityManager.java | 56 +++-- .../view/accessibility/AccessibilityNodeInfo.java | 158 ++++++++---- .../view/accessibility/AccessibilityRecord.java | 89 ++++--- core/java/android/view/accessibility/package.html | 39 +++ core/res/res/values/attrs.xml | 28 ++- 10 files changed, 572 insertions(+), 316 deletions(-) create mode 100644 core/java/android/accessibilityservice/package.html create mode 100644 core/java/android/view/accessibility/package.html diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 164acbcdf71f..68c992671f97 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -31,82 +31,151 @@ import android.view.accessibility.AccessibilityNodeInfo; * An accessibility service runs in the background and receives callbacks by the system * 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, - * etc. + * 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 + * class and implements its abstract methods. *

- * An accessibility service extends this class and implements its abstract methods. Such - * a service is declared as any other service in an AndroidManifest.xml but it must also - * specify that it handles the "android.accessibilityservice.AccessibilityService" - * {@link android.content.Intent}. Following is an example of such a declaration: - *

- * - * <service android:name=".MyAccessibilityService">
- *   <intent-filter>
- *     <action android:name="android.accessibilityservice.AccessibilityService" />
- *   </intent-filter>
- * </service>
- *
+ * Lifecycle *

*

- * The lifecycle of an accessibility service is managed exclusively by the system. Starting - * or stopping an accessibility service is triggered by an explicit user action through + * The lifecycle of an accessibility service is managed exclusively by the system and + * follows the established service life cycle. Additionally, starting or stopping an + * accessibility service is triggered exclusively by an explicit user action through * enabling or disabling it in the device settings. After the system binds to a service it * calls {@link AccessibilityService#onServiceConnected()}. This method can be * overriden by clients that want to perform post binding setup. *

*

+ * Declaration + *

+ *

+ * An accessibility is declared as any other service in an AndroidManifest.xml but it + * must also specify that it handles the "android.accessibilityservice.AccessibilityService" + * {@link android.content.Intent}. Failure to declare this intent will cause the system to + * ignore the accessibility service. Following is an example declaration: + *

+ *

+ * + *

+ *   <service android:name=".MyAccessibilityService">
+ *     <intent-filter>
+ *       <action android:name="android.accessibilityservice.AccessibilityService" />
+ *     </intent-filter>
+ *     . . .
+ *   </service>
+ * 
+ * + *

+ *

+ * Configuration + *

+ *

* 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, * retrieve window content, specify a settings activity, etc. *

+ *

* There are two approaches for configuring an accessibility service: + *

* *

- * An accessibility service can be registered for events in specific packages to provide a - * specific type of feedback and is notified with a certain timeout after the last event - * of interest has been fired. + * Retrieving window content + *

+ *

+ * 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 + * declaring this capability requires that the service declares its configuration via + * an XML resource referenced by {@link #SERVICE_META_DATA}. + *

+ *

+ * For security purposes an accessibility service can retrieve only the content of the + * currently active window. The currently active window is defined as the window from + * which was fired the last event of the following types: + * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}, + * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}, + * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}, + * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}, + * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}, + * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}, + * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}, + * {@link AccessibilityEvent#TYPE_VIEW_SELECTED}, + * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}, + * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}, + * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED}, + * {@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}, + * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}. + * In other words, the active window is the one where the user interaction is taking place. + *

+ *

+ * The entry point for retrieving window content is through calling + * {@link AccessibilityEvent#getSource() AccessibilityEvent.getSource()} of the last received + * event of the above types or a previous event from the same window + * (see {@link AccessibilityEvent#getWindowId() AccessibilityEvent.getWindowId()}). Invoking + * this method will return an {@link AccessibilityNodeInfo} that can be used to traverse the + * window content which represented as a tree of such objects. + *

+ *

+ * NoteAn 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 + * accessibility service that would like to retrieve window content should: + *

+ *

*

* Notification strategy + *

*

* 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 @@ -117,9 +186,10 @@ import android.view.accessibility.AccessibilityNodeInfo; * registration order. This enables "generic" accessibility services that work reasonably * well with most applications to coexist with "polished" ones that are targeted for * specific applications. + *

*

* Event types - *

+ *

* {@link AccessibilityEvent#TYPE_VIEW_CLICKED} * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED} * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED} @@ -127,9 +197,16 @@ import android.view.accessibility.AccessibilityNodeInfo; * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED} * {@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED} - *

- * Feedback types - *

+ * {@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} + *

+ * Feedback types + *

* {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE} * {@link AccessibilityServiceInfo#FEEDBACK_HAPTIC} * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE} @@ -140,10 +217,10 @@ import android.view.accessibility.AccessibilityNodeInfo; * @see AccessibilityServiceInfo * @see android.view.accessibility.AccessibilityManager * - * Note: The event notification timeout is useful to avoid propagating 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 event generation has - * settled down. + * Note: The event notification timeout is useful to avoid propagating + * 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 + * event generation has settled down. */ public abstract class AccessibilityService extends Service { /** @@ -154,57 +231,25 @@ public abstract class AccessibilityService extends Service { /** * Name under which an AccessibilityService component publishes information - * about itself. This meta-data must reference an XML resource containing - * an + * about itself. This meta-data must reference an XML resource containing an * <{@link android.R.styleable#AccessibilityService accessibility-service}> * tag. This is a a sample XML file configuring an accessibility service: *

* - * <?xml version="1.0" encoding="utf-8"?>
- * <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
- *   android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
- *   android:packageNames="foo.bar, foo.baz"
- *   android:accessibilityFeedbackType="feedbackSpoken"
- *   android:notificationTimeout="100"
- *   android:accessibilityFlags="flagDefault"
- *   android:settingsActivity="foo.bar.TestBackActivity"
- *   . . .
+ *

+     *   <accessibility-service
+     *     android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
+     *     android:packageNames="foo.bar, foo.baz"
+     *     android:accessibilityFeedbackType="feedbackSpoken"
+     *     android:notificationTimeout="100"
+     *     android:accessibilityFlags="flagDefault"
+     *     android:settingsActivity="foo.bar.TestBackActivity"
+     *     android:canRetrieveWindowContent="true"
+     *     . . .
      *   />
+     * 
* *

- *

- * Note: A service can retrieve only the content of the active window. - * An active window is the source of the most recent event of type - * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}, - * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}, - * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}, - * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}, - * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}, - * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}, - * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}, - * {@link AccessibilityEvent#TYPE_VIEW_SELECTED}, - * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}, - * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}. - * Therefore the service should: - *