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

Commit 1e75fbd8 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Updating accessibility documentation."

parents 43b944f1 38e8b4e5
Loading
Loading
Loading
Loading
+155 −110
Original line number Diff line number Diff line
@@ -31,70 +31,86 @@ 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.
 * <p>
 * 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:
 * <p>
 * <code>
 * &lt;service android:name=".MyAccessibilityService"&gt;<br>
 * &nbsp;&nbsp;&lt;intent-filter&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;<br>
 * &nbsp;&nbsp;&lt;/intent-filter&gt;<br>
 * &lt;/service&gt;<br>
 * </code>
 * <strong>Lifecycle</strong>
 * </p>
 * <p>
 * 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.
 * </p>
 * <p>
 * <strong>Declaration</strong>
 * </p>
 * <p>
 * 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:
 * </p>
 * <p>
 * <code>
 * <pre>
 *   &lt;service android:name=".MyAccessibilityService"&gt;
 *     &lt;intent-filter&gt;
 *       &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
 *     &lt;/intent-filter&gt;
 *     . . .
 *   &lt;/service&gt;
 * </pre>
 * </code>
 * </p>
 * <p>
 * <strong>Configuration</strong>
 * </p>
 * <p>
 * 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.
 * </p>
 * <p>
 * There are two approaches for configuring an accessibility service:
 * </p>
 * <ul>
 * <li>
 * 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:
 * <p>
 * <code>
 *         &lt;service android:name=".MyAccessibilityService"&gt;<br>
 *         &nbsp;&nbsp;&lt;intent-filter&gt;<br>
 *         &nbsp;&nbsp;&nbsp;&nbsp;&lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;<br>
 *         &nbsp;&nbsp;&lt;/intent-filter&gt;<br>
 *         &nbsp;&nbsp;&lt;meta-data android:name="android.accessibilityservice.as" android:resource="@xml/accessibilityservice" /&gt;<br>
 *         &lt;/service&gt;<br>
 * <pre>
 *   &lt;service android:name=".MyAccessibilityService"&gt;
 *     &lt;intent-filter&gt;
 *       &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
 *     &lt;/intent-filter&gt;
 *     &lt;meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /&gt;
 *   &lt;/service&gt;
 * </pre>
 * </code>
 * </p>
 * <p>
 *     <strong>
 *       This approach enables setting all accessibility service properties.
 *     </strong>
 * <strong>Note:</strong>This approach enables setting all properties.
 * </p>
 * <p>
 *       For more details refer to {@link #SERVICE_META_DATA}.
 * For more details refer to {@link #SERVICE_META_DATA} and
 * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>..
 * </p>
 * </li>
 * <li>
 * Calling {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. Note
 *     that this method can be called any time to change the service configuration.<br>
 * that this method can be called any time to dynamically change the service configuration.
 * <p>
 *     <strong>
 *       This approach enables setting only dynamically configurable accessibility
 *       service properties:
 * <strong>Note:</strong> This approach enables setting only dynamically configurable properties:
 * {@link AccessibilityServiceInfo#eventTypes},
 * {@link AccessibilityServiceInfo#feedbackType},
 * {@link AccessibilityServiceInfo#flags},
 * {@link AccessibilityServiceInfo#notificationTimeout},
 * {@link AccessibilityServiceInfo#packageNames}
 *     </strong>
 * </p>
 * <p>
 * For more details refer to {@link AccessibilityServiceInfo}.
@@ -102,11 +118,64 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * </li>
 * </ul>
 * <p>
 * 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.
 * <strong>Retrieving window content</strong>
 * </p>
 * <p>
 * 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}.
 * </p>
 * <p>
 * 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.
 * </p>
 * <p>
 * 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.
 * </p>
 * <p>
 * <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
 * accessibility service that would like to retrieve window content should:
 * <ul>
 * <li>
 * Register for all event types with no notification timeout and keep track for the active
 * window by calling {@link AccessibilityEvent#getWindowId()} of the last received event and
 * compare this with the {@link AccessibilityNodeInfo#getWindowId()} before calling retrieval
 * methods on the latter.
 * </li>
 * <li>
 * 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
 * that it is possible to have a retrieval method failing event adopting the strategy
 * specified in the previous bullet because the accessibility event dispatch is asynchronous
 * and crosses process boundaries.
 * </li>
 * </ul>
 * </p>
 * <p>
 * <b>Notification strategy</b>
 * </p>
 * <p>
 * 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.
 * </p>
 * <p>
 * <b>Event types</b>
 * <p>
 * </p>
 * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}
 * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
 * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
@@ -127,6 +197,13 @@ import android.view.accessibility.AccessibilityNodeInfo;
 * {@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>
@@ -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.
 * <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
 * 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
     * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>
     * tag. This is a a sample XML file configuring an accessibility service:
     * <p>
     * <code>
     *   &lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
     *   &lt;accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"<br>
     *   &nbsp;&nbsp;android:accessibilityEventTypes="typeViewClicked|typeViewFocused"<br>
     *   &nbsp;&nbsp;android:packageNames="foo.bar, foo.baz"<br>
     *   &nbsp;&nbsp;android:accessibilityFeedbackType="feedbackSpoken"<br>
     *   &nbsp;&nbsp;android:notificationTimeout="100"<br>
     *   &nbsp;&nbsp;android:accessibilityFlags="flagDefault"<br>
     *   &nbsp;&nbsp;android:settingsActivity="foo.bar.TestBackActivity"<br>
     *   &nbsp;&nbsp;. . .<br>
     * <pre>
     *   &lt;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"
     *     . . .
     *   /&gt;
     * </pre>
     * </code>
     * </p>
     * <p>
     *  <strong>Note:</strong> 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:
     *          <ul>
     *            <li>
     *              Register for all event types with no notification timeout and keep track
     *              for the active window by calling
     *              {@link AccessibilityEvent#getWindowId()} of the last received
     *              event and compare this with the
     *              {@link AccessibilityNodeInfo#getWindowId()} before calling
     *              retrieval methods on the latter.
     *            </li>
     *            <li>
     *              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. Note that it is possible to have a retrieval method
     *              failing event adopting the strategy specified in the previous bullet
     *              because the accessibility event dispatch is asynchronous and crosses
     *              process boundaries. 
     *            </li>
     *          <ul>
     * </p>
     */
    public static final String SERVICE_META_DATA = "android.accessibilityservice";

+18 −11
Original line number Diff line number Diff line
@@ -37,13 +37,13 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;

/**
 * This class describes an {@link AccessibilityService}. The system
 * notifies an {@link AccessibilityService} for
 * {@link android.view.accessibility.AccessibilityEvent}s
 * This class describes an {@link AccessibilityService}. The system notifies an
 * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
 * according to the information encapsulated in this class.
 *
 * @see AccessibilityService
 * @see android.view.accessibility.AccessibilityEvent
 * @see android.view.accessibility.AccessibilityManager
 */
public class AccessibilityServiceInfo implements Parcelable {

@@ -93,12 +93,19 @@ public class AccessibilityServiceInfo implements Parcelable {
     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED
     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
     * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START
     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END
     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER
     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT
     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED
     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED
     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
     */
    public int eventTypes;

    /**
     * The package names an {@link AccessibilityService} is interested in. Setting
     * to null is equivalent to all packages.
     * to <code>null</code> is equivalent to all packages.
     * <p>
     *   <strong>Can be dynamically set at runtime.</strong>
     * </p>
@@ -125,10 +132,10 @@ public class AccessibilityServiceInfo implements Parcelable {
     *   <strong>Can be dynamically set at runtime.</strong>.
     * </p>
     * <p>
     * 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
     * <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
     *       interprocess call. One can think of the timeout as a criteria to determine when
     *       event generation has settled down.
     */
    public long notificationTimeout;

@@ -159,7 +166,7 @@ public class AccessibilityServiceInfo implements Parcelable {
    private String mSettingsActivityName;

    /**
     * Flag whether this accessibility service can retrieve screen content.
     * Flag whether this accessibility service can retrieve window content.
     */
    private boolean mCanRetrieveWindowContent;

@@ -296,12 +303,12 @@ public class AccessibilityServiceInfo implements Parcelable {
    }

    /**
     * Whether this service can retrieve the currently focused window content.
     * Whether this service can retrieve the current window's content.
     * <p>
     *    <strong>Statically set from
     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
     * </p>
     * @return True screen content is retrieved.
     * @return True window content can be retrieved.
     */
    public boolean getCanRetrieveWindowContent() {
        return mCanRetrieveWindowContent;
+22 −0
Original line number Diff line number Diff line
<html>
<body>
<p>
  The classes in this package are used for development of accessibility service that
  provide alternative or augmented feedback to the user.
</p>
<p>
  An {@link android.accessibilityservice.AccessibilityService} runs in the background and
  receives callbacks by the system when {@link android.view.accessibility.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. 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.
</p>
<p>
  An {@link android.accessibilityservice.AccessibilityServiceInfo} describes an
  {@link android.accessibilityservice.AccessibilityService}. The system notifies an
  AccessibilityService for {@link android.view.accessibility.AccessibilityEvent}s
  according to the information encapsulated in this class.
</p>
</body>
</html>
+111 −77

File changed.

Preview size limit exceeded, changes collapsed.

+8 −6
Original line number Diff line number Diff line
@@ -24,11 +24,12 @@ public interface AccessibilityEventSource {
    /**
     * Handles the request for sending an {@link AccessibilityEvent} given
     * the event type. The method must first check if accessibility is on
     * via calling {@link AccessibilityManager#isEnabled()}, obtain
     * an {@link AccessibilityEvent} from the event pool through calling
     * {@link AccessibilityEvent#obtain(int)}, populate the event, and
     * send it for dispatch via calling
     * {@link AccessibilityManager#sendAccessibilityEvent(AccessibilityEvent)}.
     * via calling {@link AccessibilityManager#isEnabled() AccessibilityManager.isEnabled()},
     * obtain an {@link AccessibilityEvent} from the event pool through calling
     * {@link AccessibilityEvent#obtain(int) AccessibilityEvent.obtain(int)}, populate the
     * event, and send it for dispatch via calling
     * {@link AccessibilityManager#sendAccessibilityEvent(AccessibilityEvent)
     * AccessibilityManager.sendAccessibilityEvent(AccessibilityEvent)}.
     *
     * @see AccessibilityEvent
     * @see AccessibilityManager
@@ -41,7 +42,8 @@ public interface AccessibilityEventSource {
     * Handles the request for sending an {@link AccessibilityEvent}. The
     * method does not guarantee to check if accessibility is on before
     * sending the event for dispatch. It is responsibility of the caller
     * to do the check via calling {@link AccessibilityManager#isEnabled()}.
     * to do the check via calling {@link AccessibilityManager#isEnabled()
     * AccessibilityManager.isEnabled()}.
     *
     * @see AccessibilityEvent
     * @see AccessibilityManager
Loading