175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/*
275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Copyright (C) 2009 The Android Open Source Project
375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *
475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Licensed under the Apache License, Version 2.0 (the "License");
575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * you may not use this file except in compliance with the License.
675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * You may obtain a copy of the License at
775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *
875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *      http://www.apache.org/licenses/LICENSE-2.0
975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *
1075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Unless required by applicable law or agreed to in writing, software
1175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * distributed under the License is distributed on an "AS IS" BASIS,
1275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * See the License for the specific language governing permissions and
1475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * limitations under the License.
1575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */
1675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovpackage android.accessibilityservice;
1875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.app.Service;
2079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganovimport android.content.Context;
2175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Intent;
2275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.IBinder;
2379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganovimport android.os.Looper;
2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Message;
2575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.RemoteException;
2675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.Log;
27c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslavimport android.view.KeyEvent;
2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent;
29d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganovimport android.view.accessibility.AccessibilityInteractionClient;
308643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
32d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganovimport com.android.internal.os.HandlerCaller;
33d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
3475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/**
3575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * An accessibility service runs in the background and receives callbacks by the system
3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
3775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * in the user interface, for example, the focus has changed, a button has been clicked,
3838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * etc. Such a service can optionally request the capability for querying the content
39b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * of the active window. Development of an accessibility service requires extending this
40b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * class and implementing its abstract methods.
41e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez *
42e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez * <div class="special reference">
43e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez * <h3>Developer Guides</h3>
44e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez * <p>For more information about creating AccessibilityServices, read the
45e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
46e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez * developer guide.</p>
47e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez * </div>
48e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez *
49b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Lifecycle</h3>
5075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
5138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * The lifecycle of an accessibility service is managed exclusively by the system and
5238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * follows the established service life cycle. Additionally, starting or stopping an
5338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * accessibility service is triggered exclusively by an explicit user action through
5475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * enabling or disabling it in the device settings. After the system binds to a service it
5575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * calls {@link AccessibilityService#onServiceConnected()}. This method can be
56cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * overriden by clients that want to perform post binding setup.
578643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * </p>
58b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Declaration</h3>
5938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
6038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * An accessibility is declared as any other service in an AndroidManifest.xml but it
6138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * must also specify that it handles the "android.accessibilityservice.AccessibilityService"
6238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link android.content.Intent}. Failure to declare this intent will cause the system to
63636fd528f7ad51f565a390226d9f469f8c675ccfDianne Hackborn * ignore the accessibility service. Additionally an accessibility service must request the
64636fd528f7ad51f565a390226d9f469f8c675ccfDianne Hackborn * {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission to ensure
65636fd528f7ad51f565a390226d9f469f8c675ccfDianne Hackborn * that only the system
6653e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov * can bind to it. Failure to declare this intent will cause the system to ignore the
6753e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov * accessibility service. Following is an example declaration:
6838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
6953e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov * <pre> &lt;service android:name=".MyAccessibilityService"
7053b0fda5fd7c532fc1d93abd5f8a85276821cc6dScott Main *         android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"&gt;
7138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov *     &lt;intent-filter&gt;
72b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
7338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov *     &lt;/intent-filter&gt;
7438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov *     . . .
75b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * &lt;/service&gt;</pre>
76b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Configuration</h3>
7738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * An accessibility service can be configured to receive specific types of accessibility events,
798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * listen only to specific packages, get events from each type only once in a given time frame,
808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * retrieve window content, specify a settings activity, etc.
81cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * </p>
8238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
83cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * There are two approaches for configuring an accessibility service:
8438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
85cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * <ul>
8638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <li>
8738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Providing a {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring
8838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * the service. A service declaration with a meta-data tag is presented below:
89b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <pre> &lt;service android:name=".MyAccessibilityService"&gt;
9038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov *     &lt;intent-filter&gt;
91b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;
9238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov *     &lt;/intent-filter&gt;
9338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov *     &lt;meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /&gt;
94b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * &lt;/service&gt;</pre>
95b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <p class="note">
96b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <strong>Note:</strong> This approach enables setting all properties.
9738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
9838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
9938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * For more details refer to {@link #SERVICE_META_DATA} and
100b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>.
10138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
10238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </li>
10338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <li>
10438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Calling {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. Note
10538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * that this method can be called any time to dynamically change the service configuration.
106b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <p class="note">
10738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <strong>Note:</strong> This approach enables setting only dynamically configurable properties:
10838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityServiceInfo#eventTypes},
10938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityServiceInfo#feedbackType},
11038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityServiceInfo#flags},
11138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityServiceInfo#notificationTimeout},
11238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityServiceInfo#packageNames}
11338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
11438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
11538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * For more details refer to {@link AccessibilityServiceInfo}.
11638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
11738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </li>
118cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * </ul>
119b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Retrieving window content</h3>
12038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
121f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * A service can specify in its declaration that it can retrieve the active window
12238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * content which is represented as a tree of {@link AccessibilityNodeInfo}. Note that
12338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * declaring this capability requires that the service declares its configuration via
12438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * an XML resource referenced by {@link #SERVICE_META_DATA}.
12538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
12638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
12738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * For security purposes an accessibility service can retrieve only the content of the
12838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * currently active window. The currently active window is defined as the window from
12938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * which was fired the last event of the following types:
1304e2a762eae1f6981d32e6098a95498865ad7f795Svetoslav Ganov * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED},
13138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER},
13238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT},
1334e2a762eae1f6981d32e6098a95498865ad7f795Svetoslav Ganov * In other words, the last window that was shown or the last window that the user has touched
1344e2a762eae1f6981d32e6098a95498865ad7f795Svetoslav Ganov * during touch exploration.
13538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
13638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
13738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * The entry point for retrieving window content is through calling
13838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * {@link AccessibilityEvent#getSource() AccessibilityEvent.getSource()} of the last received
13938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * event of the above types or a previous event from the same window
14038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * (see {@link AccessibilityEvent#getWindowId() AccessibilityEvent.getWindowId()}). Invoking
14138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * this method will return an {@link AccessibilityNodeInfo} that can be used to traverse the
14238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * window content which represented as a tree of such objects.
14338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
144b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <p class="note">
145b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <strong>Note</strong> An accessibility service may have requested to be notified for
14638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * a subset of the event types, thus be unaware that the active window has changed. Therefore
14738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * accessibility service that would like to retrieve window content should:
14838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <ul>
14938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <li>
15038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Register for all event types with no notification timeout and keep track for the active
15138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * window by calling {@link AccessibilityEvent#getWindowId()} of the last received event and
15238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * compare this with the {@link AccessibilityNodeInfo#getWindowId()} before calling retrieval
15338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * methods on the latter.
15438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </li>
15538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <li>
15638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Prepare that a retrieval method on {@link AccessibilityNodeInfo} may fail since the
15738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * active window has changed and the service did not get the accessibility event yet. Note
158b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * that it is possible to have a retrieval method failing even adopting the strategy
15938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * specified in the previous bullet because the accessibility event dispatch is asynchronous
16038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * and crosses process boundaries.
16138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </li>
16238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </ul>
16338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
164b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Notification strategy</h3>
16575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
16675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * For each feedback type only one accessibility service is notified. Services are notified
16775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * in the order of registration. Hence, if two services are registered for the same
16875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * feedback type in the same package the first one wins. It is possible however, to
16975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * register a service as the default one for a given feedback type. In such a case this
17075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * service is invoked if no other service was interested in the event. In other words, default
17175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * services do not compete with other services and are notified last regardless of the
17275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * registration order. This enables "generic" accessibility services that work reasonably
17375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * well with most applications to coexist with "polished" ones that are targeted for
17475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * specific applications.
17538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
176b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <p class="note">
17738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
17838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * events to the client too frequently since this is accomplished via an expensive
17938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * interprocess call. One can think of the timeout as a criteria to determine when
180b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * event generation has settled down.</p>
181b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Event types</h3>
182b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <ul>
183b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}
184b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
185b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
186b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}
187b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
188b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
189b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
190b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
191b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
192b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
193b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
194b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
195b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
196b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
197b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * </ul>
198b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <h3>Feedback types</h3>
199b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <ul>
200b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
201b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
202b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
203b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
204b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
205b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * </ul>
206b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * @see AccessibilityEvent
207b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * @see AccessibilityServiceInfo
208b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * @see android.view.accessibility.AccessibilityManager
20975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */
21075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovpublic abstract class AccessibilityService extends Service {
2114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe up gesture on the touch screen.
2144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_UP = 1;
2164213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe down gesture on the touch screen.
2194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_DOWN = 2;
2214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe left gesture on the touch screen.
2244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_LEFT = 3;
2264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe right gesture on the touch screen.
2294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_RIGHT = 4;
2314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe left and right gesture on the touch screen.
2344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_LEFT_AND_RIGHT = 5;
2364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe right and left gesture on the touch screen.
2394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_RIGHT_AND_LEFT = 6;
2414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe up and down gesture on the touch screen.
2444213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_UP_AND_DOWN = 7;
2464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
2484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * The user has performed a swipe down and up gesture on the touch screen.
2494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
2504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public static final int GESTURE_SWIPE_DOWN_AND_UP = 8;
2514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
2524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
253005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed a left and up gesture on the touch screen.
254005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
25565d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_LEFT_AND_UP = 9;
256005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
257005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
258005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed a left and down gesture on the touch screen.
259005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
26065d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 10;
261005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
262005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
263005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed a right and up gesture on the touch screen.
264005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
26565d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_RIGHT_AND_UP = 11;
266005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
267005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
268005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed a right and down gesture on the touch screen.
269005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
27065d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 12;
271005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
272005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
273005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed an up and left gesture on the touch screen.
274005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
27565d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_UP_AND_LEFT = 13;
276005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
277005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
278005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed an up and right gesture on the touch screen.
279005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
28065d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14;
281005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
282005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
283005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed an down and left gesture on the touch screen.
284005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
28565d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15;
286005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
287005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
288005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * The user has performed an down and right gesture on the touch screen.
289005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
29065d98ad5b3f2e5ec03f14cb0538c572a427ae1a8Svetoslav Ganov    public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
291005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
292005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
29375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * The {@link Intent} that must be declared as handled by the service.
29475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
29575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public static final String SERVICE_INTERFACE =
29675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        "android.accessibilityservice.AccessibilityService";
29775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
298cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov    /**
299cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * Name under which an AccessibilityService component publishes information
30038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * about itself. This meta-data must reference an XML resource containing an
301cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * <code>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>
302cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * tag. This is a a sample XML file configuring an accessibility service:
303b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main     * <pre> &lt;accessibility-service
30438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
30538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:packageNames="foo.bar, foo.baz"
30638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:accessibilityFeedbackType="feedbackSpoken"
30738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:notificationTimeout="100"
30838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:accessibilityFlags="flagDefault"
30938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:settingsActivity="foo.bar.TestBackActivity"
31038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     android:canRetrieveWindowContent="true"
311688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav     *     android:canRequestTouchExplorationMode="true"
312688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav     *     android:canRequestEnhancedWebAccessibility="true"
31338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *     . . .
314b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main     * /&gt;</pre>
315cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     */
316cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov    public static final String SERVICE_META_DATA = "android.accessibilityservice";
317cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov
318005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
319005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * Action to go back.
320005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
321005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    public static final int GLOBAL_ACTION_BACK = 1;
322005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
323005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
324005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * Action to go home.
325005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
326005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    public static final int GLOBAL_ACTION_HOME = 2;
327005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
328005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
329e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov     * Action to open the recent apps.
330005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
331005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    public static final int GLOBAL_ACTION_RECENTS = 3;
332005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
333005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
334005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * Action to open the notifications.
335005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
336005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    public static final int GLOBAL_ACTION_NOTIFICATIONS = 4;
337005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
338e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov    /**
339e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov     * Action to open the quick settings.
340e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov     */
341e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov    public static final int GLOBAL_ACTION_QUICK_SETTINGS = 5;
342e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov
34375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private static final String LOG_TAG = "AccessibilityService";
34475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
34580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    /**
34680943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov     * @hide
34780943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov     */
34880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public interface Callbacks {
34979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        public void onAccessibilityEvent(AccessibilityEvent event);
35079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        public void onInterrupt();
35179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        public void onServiceConnected();
35279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        public void onSetConnectionId(int connectionId);
353fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        public boolean onGesture(int gestureId);
354c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public boolean onKeyEvent(KeyEvent event);
35579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    }
35675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
357d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    private int mConnectionId;
35875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
35979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    private AccessibilityServiceInfo mInfo;
36079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
36175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
36275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Callback for {@link android.view.accessibility.AccessibilityEvent}s.
36375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
36475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param event An event.
36575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
36675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public abstract void onAccessibilityEvent(AccessibilityEvent event);
36775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
36875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
36975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Callback for interrupting the accessibility feedback.
37075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
37175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public abstract void onInterrupt();
37275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
37375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
37475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * This method is a part of the {@link AccessibilityService} lifecycle and is
37575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * called after the system has successfully bound to the service. If is
37675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * convenient to use this method for setting the {@link AccessibilityServiceInfo}.
37775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
37875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @see AccessibilityServiceInfo
37975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @see #setServiceInfo(AccessibilityServiceInfo)
38075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
38175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    protected void onServiceConnected() {
38275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
38375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
38475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
38575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
3864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * Called by the system when the user performs a specific gesture on the
387e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov     * touch screen.
388fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     *
389e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov     * <strong>Note:</strong> To receive gestures an accessibility service must
390e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov     * request that the device is in touch exploration mode by setting the
3917b1e0c7046abefc0b40884b36197c8a803d9cf6dSvetoslav Ganov     * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE}
392e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov     * flag.
3934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     *
3944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @param gestureId The unique id of the performed gesture.
3954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     *
396fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @return Whether the gesture was handled.
397fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     *
3984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @see #GESTURE_SWIPE_UP
399fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_UP_AND_LEFT
4004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @see #GESTURE_SWIPE_UP_AND_DOWN
401fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_UP_AND_RIGHT
402fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_DOWN
403fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_DOWN_AND_LEFT
4044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @see #GESTURE_SWIPE_DOWN_AND_UP
405fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_DOWN_AND_RIGHT
406fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_LEFT
407fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_LEFT_AND_UP
4084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @see #GESTURE_SWIPE_LEFT_AND_RIGHT
409fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_LEFT_AND_DOWN
410fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_RIGHT
411fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_RIGHT_AND_UP
4124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @see #GESTURE_SWIPE_RIGHT_AND_LEFT
413fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov     * @see #GESTURE_SWIPE_RIGHT_AND_DOWN
4144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
415fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov    protected boolean onGesture(int gestureId) {
416fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        return false;
4174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
4184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
4194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
420c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * Callback that allows an accessibility service to observe the key events
421c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * before they are passed to the rest of the system. This means that the events
422c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * are first delivered here before they are passed to the device policy, the
423c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * input method, or applications.
424c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * <p>
425c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * <strong>Note:</strong> It is important that key events are handled in such
426c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * a way that the event stream that would be passed to the rest of the system
427c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * is well-formed. For example, handling the down event but not the up event
428c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * and vice versa would generate an inconsistent event stream.
429c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * </p>
430c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * <p>
431c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * <strong>Note:</strong> The key events delivered in this method are copies
432c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * and modifying them will have no effect on the events that will be passed
433c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * to the system. This method is intended to perform purely filtering
434c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * functionality.
435c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * <p>
436c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     *
437c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * @param event The event to be processed.
438c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     * @return If true then the event will be consumed and not delivered to
439c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     *         applications, otherwise it will be delivered as usual.
440c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav     */
441c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    protected boolean onKeyEvent(KeyEvent event) {
442c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        return false;
443c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    }
444c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
445c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    /**
4460846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov     * Gets the root node in the currently active window if this service
4470846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov     * can retrieve window content.
4480846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov     *
4490846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov     * @return The root node if this service can retrieve window content.
4500846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov     */
4510846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov    public AccessibilityNodeInfo getRootInActiveWindow() {
452fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        return AccessibilityInteractionClient.getInstance().getRootInActiveWindow(mConnectionId);
4530846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov    }
4540846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov
4550846e29d0b5640cfad4496c8484fb9aaa2ba4ccfSvetoslav Ganov    /**
456005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * Performs a global action. Such an action can be performed
457005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * at any moment regardless of the current application or user
458005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * location in that application. For example going back, going
459005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * home, opening recents, etc.
460005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     *
461005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * @param action The action to perform.
462005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * @return Whether the action was successfully performed.
463005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     *
464005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * @see #GLOBAL_ACTION_BACK
465005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * @see #GLOBAL_ACTION_HOME
466005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * @see #GLOBAL_ACTION_NOTIFICATIONS
467005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     * @see #GLOBAL_ACTION_RECENTS
468005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov     */
469005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    public final boolean performGlobalAction(int action) {
470005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        IAccessibilityServiceConnection connection =
471005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
472005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        if (connection != null) {
473005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            try {
474fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov                return connection.performGlobalAction(action);
475005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            } catch (RemoteException re) {
476005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                Log.w(LOG_TAG, "Error while calling performGlobalAction", re);
477005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            }
478005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        }
479005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        return false;
480005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    }
481005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
482005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov    /**
4834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * Gets the an {@link AccessibilityServiceInfo} describing this
4844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * {@link AccessibilityService}. This method is useful if one wants
4854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * to change some of the dynamically configurable properties at
4864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * runtime.
4874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     *
4884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * @return The accessibility service info.
4894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     *
490bbfa585d70a6e406ccb59c17eec73ccd55e5c8e0Svetoslav     * @see AccessibilityServiceInfo
4914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
4924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public final AccessibilityServiceInfo getServiceInfo() {
4934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        IAccessibilityServiceConnection connection =
4944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
4954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        if (connection != null) {
4964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            try {
4974213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return connection.getServiceInfo();
4984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            } catch (RemoteException re) {
4994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                Log.w(LOG_TAG, "Error while getting AccessibilityServiceInfo", re);
5004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
5014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
5024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        return null;
5034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
5044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
5054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
50675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Sets the {@link AccessibilityServiceInfo} that describes this service.
50775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * <p>
50875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Note: You can call this method any time but the info will be picked up after
50975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *       the system has bound to this service and when this method is called thereafter.
51075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
51175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param info The info.
51275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
51375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public final void setServiceInfo(AccessibilityServiceInfo info) {
51475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        mInfo = info;
51575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        sendServiceInfo();
51675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
51775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
51875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
51975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Sets the {@link AccessibilityServiceInfo} for this service if the latter is
52075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * properly set and there is an {@link IAccessibilityServiceConnection} to the
52175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * AccessibilityManagerService.
52275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
52375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private void sendServiceInfo() {
524d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        IAccessibilityServiceConnection connection =
525d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
526d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        if (mInfo != null && connection != null) {
52775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            try {
528d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                connection.setServiceInfo(mInfo);
5294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                mInfo = null;
5304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                AccessibilityInteractionClient.getInstance().clearCache();
53175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } catch (RemoteException re) {
53275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re);
53375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
53475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
53575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
53675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
5377f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn    /**
5387f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn     * Implement to return the implementation of the internal accessibility
5398643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * service interface.
5407f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn     */
54175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    @Override
54275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public final IBinder onBind(Intent intent) {
5434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        return new IAccessibilityServiceClientWrapper(this, getMainLooper(), new Callbacks() {
54479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            @Override
54579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            public void onServiceConnected() {
54679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                AccessibilityService.this.onServiceConnected();
54779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
54879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
54979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            @Override
55079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            public void onInterrupt() {
55179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                AccessibilityService.this.onInterrupt();
55279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
55379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
55479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            @Override
55579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            public void onAccessibilityEvent(AccessibilityEvent event) {
55679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                AccessibilityService.this.onAccessibilityEvent(event);
55779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
55879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
55979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            @Override
56079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            public void onSetConnectionId( int connectionId) {
56179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                mConnectionId = connectionId;
56279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
5634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
5644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            @Override
565fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov            public boolean onGesture(int gestureId) {
566fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov                return AccessibilityService.this.onGesture(gestureId);
5674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
568c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
569c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            @Override
570c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public boolean onKeyEvent(KeyEvent event) {
571c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                return AccessibilityService.this.onKeyEvent(event);
572c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
57379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        });
57475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
57575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
57675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
5774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * Implements the internal {@link IAccessibilityServiceClient} interface to convert
57875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * incoming calls to it back to calls on an {@link AccessibilityService}.
57980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov     *
58080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov     * @hide
58175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
58280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov    public static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub
58375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            implements HandlerCaller.Callback {
58475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
58579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        static final int NO_ID = -1;
58679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
58775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private static final int DO_SET_SET_CONNECTION = 10;
58875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private static final int DO_ON_INTERRUPT = 20;
58975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private static final int DO_ON_ACCESSIBILITY_EVENT = 30;
5904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private static final int DO_ON_GESTURE = 40;
591152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        private static final int DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE = 50;
592c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        private static final int DO_ON_KEY_EVENT = 60;
59375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
59475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private final HandlerCaller mCaller;
59575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
59679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        private final Callbacks mCallback;
59775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
598c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        private int mConnectionId;
599c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
6004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public IAccessibilityServiceClientWrapper(Context context, Looper looper,
6014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                Callbacks callback) {
60279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            mCallback = callback;
603ed218c706d9e91e75b94c448cee2e6150aaee57fMita Yun            mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/);
60475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
60575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
606d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        public void setConnection(IAccessibilityServiceConnection connection, int connectionId) {
607d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            Message message = mCaller.obtainMessageIO(DO_SET_SET_CONNECTION, connectionId,
608d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                    connection);
60975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller.sendMessage(message);
61075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
61175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
61275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void onInterrupt() {
61375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Message message = mCaller.obtainMessage(DO_ON_INTERRUPT);
61475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller.sendMessage(message);
61575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
61675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
61775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void onAccessibilityEvent(AccessibilityEvent event) {
61875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Message message = mCaller.obtainMessageO(DO_ON_ACCESSIBILITY_EVENT, event);
61975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller.sendMessage(message);
62075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
62175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
6227b1e0c7046abefc0b40884b36197c8a803d9cf6dSvetoslav Ganov        public void onGesture(int gestureId) {
6237b1e0c7046abefc0b40884b36197c8a803d9cf6dSvetoslav Ganov            Message message = mCaller.obtainMessageI(DO_ON_GESTURE, gestureId);
6244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            mCaller.sendMessage(message);
6254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
6264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
627152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        public void clearAccessibilityNodeInfoCache() {
628152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            Message message = mCaller.obtainMessage(DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE);
629152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            mCaller.sendMessage(message);
630152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
631152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
632c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        @Override
633c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public void onKeyEvent(KeyEvent event, int sequence) {
634c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            Message message = mCaller.obtainMessageIO(DO_ON_KEY_EVENT, sequence, event);
635c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mCaller.sendMessage(message);
636c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
637c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
63875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void executeMessage(Message message) {
63975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            switch (message.what) {
640c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case DO_ON_ACCESSIBILITY_EVENT: {
64175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    AccessibilityEvent event = (AccessibilityEvent) message.obj;
6427ed6ee5692c808cf0ebb3ee208fc8ee1314622c2Dianne Hackborn                    if (event != null) {
64379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                        AccessibilityInteractionClient.getInstance().onAccessibilityEvent(event);
64479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                        mCallback.onAccessibilityEvent(event);
6457ed6ee5692c808cf0ebb3ee208fc8ee1314622c2Dianne Hackborn                        event.recycle();
64685f6fb713feb258197f17a86c45874d542194b71Charles Chen                    }
647c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } return;
648c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case DO_ON_INTERRUPT: {
64979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    mCallback.onInterrupt();
650c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } return;
651c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case DO_SET_SET_CONNECTION: {
652c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    mConnectionId = message.arg1;
653d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                    IAccessibilityServiceConnection connection =
654d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                        (IAccessibilityServiceConnection) message.obj;
655d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                    if (connection != null) {
656c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        AccessibilityInteractionClient.getInstance().addConnection(mConnectionId,
657d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                                connection);
658c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        mCallback.onSetConnectionId(mConnectionId);
65979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                        mCallback.onServiceConnected();
660d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                    } else {
661c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        AccessibilityInteractionClient.getInstance().removeConnection(mConnectionId);
662f7e50993edfbbe4bc84e60cea84d18b935d0ad0dSvetoslav                        AccessibilityInteractionClient.getInstance().clearCache();
66379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                        mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID);
664d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                    }
665c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } return;
666c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case DO_ON_GESTURE: {
6674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    final int gestureId = message.arg1;
6687b1e0c7046abefc0b40884b36197c8a803d9cf6dSvetoslav Ganov                    mCallback.onGesture(gestureId);
669c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } return;
670c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE: {
671152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    AccessibilityInteractionClient.getInstance().clearCache();
672c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } return;
673c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case DO_ON_KEY_EVENT: {
674c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    KeyEvent event = (KeyEvent) message.obj;
675c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    try {
676c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        IAccessibilityServiceConnection connection = AccessibilityInteractionClient
677c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                                .getInstance().getConnection(mConnectionId);
678c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        if (connection != null) {
679c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            final boolean result = mCallback.onKeyEvent(event);
680c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            final int sequence = message.arg1;
681c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            try {
682c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                                connection.setOnKeyEventResult(result, sequence);
683c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            } catch (RemoteException re) {
684c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                                /* ignore */
685c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            }
686c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        }
687c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    } finally {
688c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        event.recycle();
689c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    }
690c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } return;
69175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                default :
69275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    Log.w(LOG_TAG, "Unknown message type " + message.what);
69375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
69475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
69575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
69675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov}
697