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 com.android.internal.os.HandlerCaller;
2075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
2175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.app.Service;
2275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Intent;
2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.IBinder;
2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Message;
2575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.RemoteException;
2675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.Log;
2775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent;
2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
2975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/**
3075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * An accessibility service runs in the background and receives callbacks by the system
3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
3275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * in the user interface, for example, the focus has changed, a button has been clicked,
3375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * etc.
3475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
3575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * An accessibility service extends this class and implements its abstract methods. Such
3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * a service is declared as any other service in an AndroidManifest.xml but it must also
3775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * specify that it handles the "android.accessibilityservice.AccessibilityService"
3875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link android.content.Intent}. Following is an example of such a declaration:
3975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
4075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <code>
4175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * &lt;service android:name=".MyAccessibilityService"&gt;<br>
4275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *     &lt;intent-filter&gt;<br>
4375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;<br>
4475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *     &lt;/intent-filter&gt;<br>
4575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * &lt;/service&gt;<br>
4675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * </code>
4775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
4875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * The lifecycle of an accessibility service is managed exclusively by the system. Starting
4975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * or stopping an accessibility service is triggered by an explicit user action through
5075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * enabling or disabling it in the device settings. After the system binds to a service it
5175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * calls {@link AccessibilityService#onServiceConnected()}. This method can be
5275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * overriden by clients that want to perform post binding setup. An accessibility service
5375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * is configured though setting an {@link AccessibilityServiceInfo} by calling
5475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. You can call this
5575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * method any time to change the service configuration but it is good practice to do that
5675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * in the overriden {@link AccessibilityService#onServiceConnected()}.
5775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
5875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * An accessibility service can be registered for events in specific packages to provide a
5975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * specific type of feedback and is notified with a certain timeout after the last event
6075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * of interest has been fired.
6175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
6275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <b>Notification strategy</b>
6375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
6475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * For each feedback type only one accessibility service is notified. Services are notified
6575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * in the order of registration. Hence, if two services are registered for the same
6675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * feedback type in the same package the first one wins. It is possible however, to
6775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * register a service as the default one for a given feedback type. In such a case this
6875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * service is invoked if no other service was interested in the event. In other words, default
6975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * services do not compete with other services and are notified last regardless of the
7075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * registration order. This enables "generic" accessibility services that work reasonably
7175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * well with most applications to coexist with "polished" ones that are targeted for
7275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * specific applications.
7375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
7475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <b>Event types</b>
7575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * <p>
7675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}
7775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
7875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
7975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_VIEW_SELECTED}
8075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
8175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
8275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
8375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *  <p>
8475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *  <b>Feedback types</b>
8575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *  <p>
8675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
8775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
8875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
8975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
9075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
9175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *
9275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see AccessibilityEvent
9375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see AccessibilityServiceInfo
9475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see android.view.accessibility.AccessibilityManager
9575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *
9675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Note: The event notification timeout is useful to avoid propagating events to the client
9775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *       too frequently since this is accomplished via an expensive interprocess call.
9875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *       One can think of the timeout as a criteria to determine when event generation has
9975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *       settled down.
10075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */
10175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovpublic abstract class AccessibilityService extends Service {
10275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
10375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * The {@link Intent} that must be declared as handled by the service.
10475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
10575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public static final String SERVICE_INTERFACE =
10675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        "android.accessibilityservice.AccessibilityService";
10775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
10875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private static final String LOG_TAG = "AccessibilityService";
10975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
11075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private AccessibilityServiceInfo mInfo;
11175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
11275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    IAccessibilityServiceConnection mConnection;
11375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
11475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
11575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Callback for {@link android.view.accessibility.AccessibilityEvent}s.
11675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
11775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param event An event.
11875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
11975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public abstract void onAccessibilityEvent(AccessibilityEvent event);
12075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
12175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
12275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Callback for interrupting the accessibility feedback.
12375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
12475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public abstract void onInterrupt();
12575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
12675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
12775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * This method is a part of the {@link AccessibilityService} lifecycle and is
12875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * called after the system has successfully bound to the service. If is
12975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * convenient to use this method for setting the {@link AccessibilityServiceInfo}.
13075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
13175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @see AccessibilityServiceInfo
13275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @see #setServiceInfo(AccessibilityServiceInfo)
13375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
13475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    protected void onServiceConnected() {
13575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
13675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
13775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
13875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
13975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Sets the {@link AccessibilityServiceInfo} that describes this service.
14075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * <p>
14175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Note: You can call this method any time but the info will be picked up after
14275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *       the system has bound to this service and when this method is called thereafter.
14375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
14475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param info The info.
14575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
14675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public final void setServiceInfo(AccessibilityServiceInfo info) {
14775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        mInfo = info;
14875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        sendServiceInfo();
14975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
15075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
15175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
15275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Sets the {@link AccessibilityServiceInfo} for this service if the latter is
15375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * properly set and there is an {@link IAccessibilityServiceConnection} to the
15475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * AccessibilityManagerService.
15575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
15675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private void sendServiceInfo() {
15775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        if (mInfo != null && mConnection != null) {
15875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            try {
15975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                mConnection.setServiceInfo(mInfo);
16075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } catch (RemoteException re) {
16175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re);
16275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
16375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
16475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
16575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1667f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn    /**
1677f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn     * Implement to return the implementation of the internal accessibility
1687f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn     * service interface.  Subclasses should not override.
1697f2054392e9957d3ba8579ef08c29cfb27df564eDianne Hackborn     */
17075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    @Override
17175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public final IBinder onBind(Intent intent) {
17275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        return new IEventListenerWrapper(this);
17375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
17475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
17575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
17675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Implements the internal {@link IEventListener} interface to convert
17775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * incoming calls to it back to calls on an {@link AccessibilityService}.
17875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
17975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    class IEventListenerWrapper extends IEventListener.Stub
18075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            implements HandlerCaller.Callback {
18175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
18275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private static final int DO_SET_SET_CONNECTION = 10;
18375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private static final int DO_ON_INTERRUPT = 20;
18475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private static final int DO_ON_ACCESSIBILITY_EVENT = 30;
18575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
18675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        private final HandlerCaller mCaller;
18775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1887ed6ee5692c808cf0ebb3ee208fc8ee1314622c2Dianne Hackborn        private final AccessibilityService mTarget;
18975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
19075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public IEventListenerWrapper(AccessibilityService context) {
19175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mTarget = context;
19275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller = new HandlerCaller(context, this);
19375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
19475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
19575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void setConnection(IAccessibilityServiceConnection connection) {
19675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Message message = mCaller.obtainMessageO(DO_SET_SET_CONNECTION, connection);
19775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller.sendMessage(message);
19875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
19975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
20075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void onInterrupt() {
20175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Message message = mCaller.obtainMessage(DO_ON_INTERRUPT);
20275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller.sendMessage(message);
20375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
20475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
20575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void onAccessibilityEvent(AccessibilityEvent event) {
20675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Message message = mCaller.obtainMessageO(DO_ON_ACCESSIBILITY_EVENT, event);
20775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mCaller.sendMessage(message);
20875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
20975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
21075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void executeMessage(Message message) {
21175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            switch (message.what) {
21275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                case DO_ON_ACCESSIBILITY_EVENT :
21375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    AccessibilityEvent event = (AccessibilityEvent) message.obj;
2147ed6ee5692c808cf0ebb3ee208fc8ee1314622c2Dianne Hackborn                    if (event != null) {
2157ed6ee5692c808cf0ebb3ee208fc8ee1314622c2Dianne Hackborn                        mTarget.onAccessibilityEvent(event);
2167ed6ee5692c808cf0ebb3ee208fc8ee1314622c2Dianne Hackborn                        event.recycle();
21785f6fb713feb258197f17a86c45874d542194b71Charles Chen                    }
21875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    return;
21975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                case DO_ON_INTERRUPT :
22075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    mTarget.onInterrupt();
22175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    return;
22275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                case DO_SET_SET_CONNECTION :
22375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    mConnection = ((IAccessibilityServiceConnection) message.obj);
22475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    mTarget.onServiceConnected();
22575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    return;
22675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                default :
22775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    Log.w(LOG_TAG, "Unknown message type " + message.what);
22875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
22975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
23075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
23175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov}
232