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> <service android:name=".MyAccessibilityService" 7053b0fda5fd7c532fc1d93abd5f8a85276821cc6dScott Main * android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> 7138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <intent-filter> 72b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <action android:name="android.accessibilityservice.AccessibilityService" /> 7338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </intent-filter> 7438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * . . . 75b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * </service></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> <service android:name=".MyAccessibilityService"> 9038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <intent-filter> 91b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <action android:name="android.accessibilityservice.AccessibilityService" /> 9238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </intent-filter> 9338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /> 94b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * </service></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><{@link android.R.styleable#AccessibilityService accessibility-service}></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><{@link android.R.styleable#AccessibilityService accessibility-service}></code> 302cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * tag. This is a a sample XML file configuring an accessibility service: 303b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <pre> <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 * /></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