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

Commit 40ded287 authored by Phil Weaver's avatar Phil Weaver
Browse files

Clean up some accessibility documentation.

Removed and updated some obsolete documentation about window
content. Stated the purpose of accessibility. Updated docs
for getTextSelection to include its ability to get cursor
position. Clarified wording for accessibility overlays.

Change-Id: Iaa11b499c2b7ece12ca182d336376d97b961b54f
parent 104aff50
Loading
Loading
Loading
Loading
+46 −53
Original line number Original line Diff line number Diff line
@@ -49,7 +49,8 @@ import com.android.internal.os.SomeArgs;
import java.util.List;
import java.util.List;


/**
/**
 * An accessibility service runs in the background and receives callbacks by the system
 * Accessibility services are intended to assist users with disabilities in using
 * Android devices and apps. They run in the background and receive callbacks by the system
 * 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
@@ -66,22 +67,31 @@ import java.util.List;
 * <h3>Lifecycle</h3>
 * <h3>Lifecycle</h3>
 * <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. Starting an accessibility service is triggered
 * accessibility service is triggered exclusively by an explicit user action through
 * exclusively by the user explicitly turning the service on in device settings. After the system
 * enabling or disabling it in the device settings. After the system binds to a service it
 * binds to a service, it calls {@link AccessibilityService#onServiceConnected()}. This method can
 * calls {@link AccessibilityService#onServiceConnected()}. This method can be
 * be overriden by clients that want to perform post binding setup.
 * overriden by clients that want to perform post binding setup.
 * </p>
 * <p>
 * An accessibility service stops either when the user turns it off in device settings or when
 * it calls {@link AccessibilityService#disableSelf()}.
 * </p>
 * </p>
 * <h3>Declaration</h3>
 * <h3>Declaration</h3>
 * <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 do two things:
 * {@link android.content.Intent}. Failure to declare this intent will cause the system to
 * <ul>
 * ignore the accessibility service. Additionally an accessibility service must request the
 *     <ol>
 * {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission to ensure
 *         Specify that it handles the "android.accessibilityservice.AccessibilityService"
 * that only the system
 *         {@link android.content.Intent}.
 * can bind to it. Failure to declare this intent will cause the system to ignore the
 *     </ol>
 * accessibility service. Following is an example declaration:
 *     <ol>
 *         Request the {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission to
 *         ensure that only the system can bind to it.
 *     </ol>
 * </ul>
 * If either of these items is missing, the system will ignore the accessibility service.
 * Following is an example declaration:
 * </p>
 * </p>
 * <pre> &lt;service android:name=".MyAccessibilityService"
 * <pre> &lt;service android:name=".MyAccessibilityService"
 *         android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"&gt;
 *         android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"&gt;
@@ -135,48 +145,24 @@ import java.util.List;
 * </ul>
 * </ul>
 * <h3>Retrieving window content</h3>
 * <h3>Retrieving window content</h3>
 * <p>
 * <p>
 * A service can specify in its declaration that it can retrieve the active window
 * A service can specify in its declaration that it can retrieve window
 * content which is represented as a tree of {@link AccessibilityNodeInfo}. Note that
 * content which is represented as a tree of {@link AccessibilityWindowInfo} and
 * {@link AccessibilityNodeInfo} objects. Note that
 * declaring this capability requires that the service declares its configuration via
 * declaring this capability requires that the service declares its configuration via
 * an XML resource referenced by {@link #SERVICE_META_DATA}.
 * an XML resource referenced by {@link #SERVICE_META_DATA}.
 * </p>
 * </p>
 * <p>
 * <p>
 * For security purposes an accessibility service can retrieve only the content of the
 * Window content may be retrieved with
 * currently active window. The currently active window is defined as the window from
 * {@link AccessibilityEvent#getSource() AccessibilityEvent.getSource()},
 * which was fired the last event of the following types:
 * {@link AccessibilityService#findFocus(int)},
 * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED},
 * {@link AccessibilityService#getWindows()}, or
 * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER},
 * {@link AccessibilityService#getRootInActiveWindow()}.
 * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT},
 * In other words, the last window that was shown or the last window that the user has touched
 * during touch exploration.
 * </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>
 * <p class="note">
 * <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, and thus be unaware when the node hierarchy has changed. It is also
 * accessibility service that would like to retrieve window content should:
 * possible for a node to contain outdated information because the window content may change at any
 * <ul>
 * time.
 * <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 even adopting the strategy
 * specified in the previous bullet because the accessibility event dispatch is asynchronous
 * and crosses process boundaries.
 * </li>
 * </ul>
 * </p>
 * </p>
 * <h3>Notification strategy</h3>
 * <h3>Notification strategy</h3>
 * <p>
 * <p>
@@ -328,7 +314,6 @@ public abstract class AccessibilityService extends Service {
     *     android:settingsActivity="foo.bar.TestBackActivity"
     *     android:settingsActivity="foo.bar.TestBackActivity"
     *     android:canRetrieveWindowContent="true"
     *     android:canRetrieveWindowContent="true"
     *     android:canRequestTouchExplorationMode="true"
     *     android:canRequestTouchExplorationMode="true"
     *     android:canRequestEnhancedWebAccessibility="true"
     *     . . .
     *     . . .
     * /&gt;</pre>
     * /&gt;</pre>
     */
     */
@@ -528,6 +513,14 @@ public abstract class AccessibilityService extends Service {
     * is currently touching or the window with input focus, if the user is not
     * is currently touching or the window with input focus, if the user is not
     * touching any window.
     * touching any window.
     * <p>
     * <p>
     * The currently active window is defined as the window that most recently fired one
     * of the following events:
     * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED},
     * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER},
     * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}.
     * In other words, the last window shown that also has input focus.
     * </p>
     * <p>
     * <strong>Note:</strong> In order to access the root node your service has
     * <strong>Note:</strong> In order to access the root node your service has
     * to declare the capability to retrieve window content by setting the
     * to declare the capability to retrieve window content by setting the
     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
@@ -541,8 +534,8 @@ public abstract class AccessibilityService extends Service {
    }
    }


    /**
    /**
     * This method allows accessibility service turn itself off
     * Disables the service. After calling this method, the service will be disabled and settings
     * and the service will become disabled from the Settings.
     * will show that it is turned off.
     */
     */
    public final void disableSelf() {
    public final void disableSelf() {
        final IAccessibilityServiceConnection connection =
        final IAccessibilityServiceConnection connection =
+2 −2
Original line number Original line Diff line number Diff line
@@ -589,14 +589,14 @@ public interface WindowManager extends ViewManager {
        public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;
        public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;


        /**
        /**
         * Window type: Windows that are overlaid <em>only</em> by an {@link
         * Window type: Windows that are overlaid <em>only</em> by a connected {@link
         * android.accessibilityservice.AccessibilityService} for interception of
         * android.accessibilityservice.AccessibilityService} for interception of
         * user interactions without changing the windows an accessibility service
         * user interactions without changing the windows an accessibility service
         * can introspect. In particular, an accessibility service can introspect
         * can introspect. In particular, an accessibility service can introspect
         * only windows that a sighted user can interact with which is they can touch
         * only windows that a sighted user can interact with which is they can touch
         * these windows or can type into these windows. For example, if there
         * these windows or can type into these windows. For example, if there
         * is a full screen accessibility overlay that is touchable, the windows
         * is a full screen accessibility overlay that is touchable, the windows
         * below it will be introspectable by an accessibility service regardless
         * below it will be introspectable by an accessibility service even though
         * they are covered by a touchable window.
         * they are covered by a touchable window.
         */
         */
        public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32;
        public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32;
+19 −7
Original line number Original line Diff line number Diff line
@@ -38,8 +38,8 @@ import java.util.List;
/**
/**
 * This class represents a node of the window content as well as actions that
 * This class represents a node of the window content as well as actions that
 * can be requested from its source. From the point of view of an
 * can be requested from its source. From the point of view of an
 * {@link android.accessibilityservice.AccessibilityService} a window content is
 * {@link android.accessibilityservice.AccessibilityService} a window's content is
 * presented as tree of accessibility node info which may or may not map one-to-one
 * presented as a tree of accessibility node infos, which may or may not map one-to-one
 * to the view hierarchy. In other words, a custom view is free to report itself as
 * to the view hierarchy. In other words, a custom view is free to report itself as
 * a tree of accessibility node info.
 * a tree of accessibility node info.
 * </p>
 * </p>
@@ -50,7 +50,7 @@ import java.util.List;
 * <p>
 * <p>
 * Please refer to {@link android.accessibilityservice.AccessibilityService} for
 * Please refer to {@link android.accessibilityservice.AccessibilityService} for
 * details about how to obtain a handle to window content as a tree of accessibility
 * details about how to obtain a handle to window content as a tree of accessibility
 * node info as well as familiarizing with the security model.
 * node info as well as details about the security model.
 * </p>
 * </p>
 * <div class="special reference">
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <h3>Developer Guides</h3>
@@ -2422,18 +2422,30 @@ public class AccessibilityNodeInfo implements Parcelable {
    }
    }


    /**
    /**
     * Gets the text selection start.
     * Gets the text selection start or the cursor position.
     * <p>
     * If no text is selected, both this method and
     * {@link AccessibilityNodeInfo#getTextSelectionEnd()} return the same value:
     * the current location of the cursor.
     * </p>
     *
     *
     * @return The text selection start if there is selection or -1.
     * @return The text selection start, the cursor location if there is no selection, or -1 if
     *         there is no text selection and no cursor.
     */
     */
    public int getTextSelectionStart() {
    public int getTextSelectionStart() {
        return mTextSelectionStart;
        return mTextSelectionStart;
    }
    }


    /**
    /**
     * Gets the text selection end.
     * Gets the text selection end if text is selected.
     * <p>
     * If no text is selected, both this method and
     * {@link AccessibilityNodeInfo#getTextSelectionStart()} return the same value:
     * the current location of the cursor.
     * </p>
     *
     *
     * @return The text selection end if there is selection or -1.
     * @return The text selection end, the cursor location if there is no selection, or -1 if
     *         there is no text selection and no cursor.
     */
     */
    public int getTextSelectionEnd() {
    public int getTextSelectionEnd() {
        return mTextSelectionEnd;
        return mTextSelectionEnd;