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.view.accessibility;
1875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
19736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovimport android.accessibilityservice.AccessibilityServiceInfo;
2075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context;
2175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.ServiceInfo;
2275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Binder;
2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Handler;
2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.IBinder;
2575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Looper;
2675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Message;
2775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.RemoteException;
2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.ServiceManager;
2975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.SystemClock;
3058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.UserHandle;
3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.Log;
328643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.IWindow;
338643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.View;
3475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
35cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganovimport java.util.ArrayList;
3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Collections;
3775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.List;
388643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport java.util.concurrent.CopyOnWriteArrayList;
3975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
4075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/**
4138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * System level service that serves as an event dispatch for {@link AccessibilityEvent}s,
4238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * and provides facilities for querying the accessibility state of the system.
4338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Accessibility events are generated when something notable happens in the user interface,
4475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * for example an {@link android.app.Activity} starts, the focus or selection of a
4575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link android.view.View} changes etc. Parties interested in handling accessibility
4675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * events implement and register an accessibility service which extends
4775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link android.accessibilityservice.AccessibilityService}.
4838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
4938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * To obtain a handle to the accessibility manager do the following:
5038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
5138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p>
5238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <code>
53b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <pre>AccessibilityManager accessibilityManager =
54b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main *        (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);</pre>
5538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </code>
5638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p>
5775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov *
5875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see AccessibilityEvent
5938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityNodeInfo
6075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see android.accessibilityservice.AccessibilityService
6138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see Context#getSystemService
6238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see Context#ACCESSIBILITY_SERVICE
6375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */
6475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovpublic final class AccessibilityManager {
65736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    private static final boolean DEBUG = false;
66736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
6775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private static final String LOG_TAG = "AccessibilityManager";
6875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
6900aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    /** @hide */
7000aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    public static final int STATE_FLAG_ACCESSIBILITY_ENABLED = 0x00000001;
7100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov
7200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    /** @hide */
7300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002;
7400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov
7575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    static final Object sInstanceSync = new Object();
7675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
7775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private static AccessibilityManager sInstance;
7875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
7900aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    private static final int DO_SET_STATE = 10;
8075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
8175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    final IAccessibilityManager mService;
8275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
8358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    final int mUserId;
8458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
8575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    final Handler mHandler;
8675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
8775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    boolean mIsEnabled;
8875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
8935bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov    boolean mIsTouchExplorationEnabled;
9035bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov
918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    final CopyOnWriteArrayList<AccessibilityStateChangeListener> mAccessibilityStateChangeListeners =
928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        new CopyOnWriteArrayList<AccessibilityStateChangeListener>();
938643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
95b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main     * Listener for the system accessibility state. To listen for changes to the accessibility
96b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main     * state on the device, implement this interface and register it with the system by
97b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main     * calling {@link AccessibilityManager#addAccessibilityStateChangeListener
98b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main     * addAccessibilityStateChangeListener()}.
998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
1008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public interface AccessibilityStateChangeListener {
10138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov
1028643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        /**
1038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov         * Called back on change in the accessibility state.
1048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov         *
10538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov         * @param enabled Whether accessibility is enabled.
1068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov         */
1078643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        public void onAccessibilityStateChanged(boolean enabled);
1088643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
1098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
11075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() {
11100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        public void setState(int state) {
11200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            mHandler.obtainMessage(DO_SET_STATE, state, 0).sendToTarget();
11375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
11475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    };
11575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
11675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    class MyHandler extends Handler {
11775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
11875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        MyHandler(Looper mainLooper) {
11975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            super(mainLooper);
12075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
12175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
12275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        @Override
12375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void handleMessage(Message message) {
12475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            switch (message.what) {
12500aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov                case DO_SET_STATE :
12600aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov                    setState(message.arg1);
12775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    return;
12875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                default :
12975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    Log.w(LOG_TAG, "Unknown message type: " + message.what);
13075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
13175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
13275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
13375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
13475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
13558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * Creates the singleton AccessibilityManager to be shared across users. This
13658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * has to be called before the local AccessibilityManager is created to ensure
13758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * it registers itself in the system correctly.
13858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * <p>
13958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * Note: Calling this method requires INTERACT_ACROSS_USERS_FULL or
14058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     *       INTERACT_ACROSS_USERS permission.
14158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * </p>
14258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param context Context in which this manager operates.
14358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @throws IllegalStateException if not called before the local
14458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     *     AccessibilityManager is instantiated.
14558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     *
14658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @hide
14758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     */
14858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public static void createAsSharedAcrossUsers(Context context) {
14958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        synchronized (sInstanceSync) {
15058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (sInstance != null) {
15158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                throw new IllegalStateException("AccessibilityManager already created.");
15258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
15358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            createSingletonInstance(context, UserHandle.USER_CURRENT);
15458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
15558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
15658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
15758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    /**
15875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Get an AccessibilityManager instance (create one if necessary).
15975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
16058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param context Context in which this manager operates.
16158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     *
16275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @hide
16375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
16475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public static AccessibilityManager getInstance(Context context) {
16575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        synchronized (sInstanceSync) {
16675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            if (sInstance == null) {
16758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                createSingletonInstance(context, UserHandle.myUserId());
16875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
16975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
17075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        return sInstance;
17175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
17275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
17375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
17458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * Creates the singleton instance.
17558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     *
17658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param context Context in which this manager operates.
17758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param userId The user id under which to operate.
17858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     */
17958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private static void createSingletonInstance(Context context, int userId) {
18058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
18158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
18258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        sInstance = new AccessibilityManager(context, service, userId);
18358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
18458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
18558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    /**
18675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Create an instance.
18775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
18875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param context A {@link Context}.
189af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     * @param service An interface to the backing service.
19058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param userId User id under which to run.
191af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     *
192af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     * @hide
19375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
19458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
19575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        mHandler = new MyHandler(context.getMainLooper());
196af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov        mService = service;
19758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        mUserId = userId;
198af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov
19975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        try {
20058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int stateFlags = mService.addClient(mClient, userId);
20100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov            setState(stateFlags);
20275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        } catch (RemoteException re) {
20375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
20475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
20575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
20675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
20775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
20838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * Returns if the accessibility in the system is enabled.
20975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
21038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @return True if accessibility is enabled, false otherwise.
21175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
21275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public boolean isEnabled() {
21375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        synchronized (mHandler) {
21475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            return mIsEnabled;
21575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
21675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
21775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
21875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
21935bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov     * Returns if the touch exploration in the system is enabled.
22035bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov     *
22135bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov     * @return True if touch exploration is enabled, false otherwise.
22235bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov     */
22335bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov    public boolean isTouchExplorationEnabled() {
22435bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov        synchronized (mHandler) {
22535bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov            return mIsTouchExplorationEnabled;
22635bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov        }
22735bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov    }
22835bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov
22935bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov    /**
230af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     * Returns the client interface this instance registers in
231af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     * the centralized accessibility manager service.
232af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     *
233af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     * @return The client.
234af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     *
235af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     * @hide
236af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov     */
237af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov    public IAccessibilityManagerClient getClient() {
2384dfecf55c1afcc7ffe0cef931df67c4934a13e34Jim Miller       return (IAccessibilityManagerClient) mClient.asBinder();
239af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov    }
240af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov
241af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov    /**
24238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * Sends an {@link AccessibilityEvent}.
24375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
24438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @param event The event to send.
24575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
24638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @throws IllegalStateException if accessibility is not enabled.
2474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     *
2484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * <strong>Note:</strong> The preferred mechanism for sending custom accessibility
2494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * events is through calling
2504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * {@link android.view.ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
2514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * instead of this method to allow predecessors to augment/filter events sent by
2524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * their descendants.
25375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
25475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public void sendAccessibilityEvent(AccessibilityEvent event) {
25575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        if (!mIsEnabled) {
25675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            throw new IllegalStateException("Accessibility off. Did you forget to check that?");
25775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
25875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        boolean doRecycle = false;
25975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        try {
26075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            event.setEventTime(SystemClock.uptimeMillis());
26175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            // it is possible that this manager is in the same process as the service but
26275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            // client using it is called through Binder from another process. Example: MMS
26375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            // app adds a SMS notification and the NotificationManagerService calls this method
26475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            long identityToken = Binder.clearCallingIdentity();
26558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            doRecycle = mService.sendAccessibilityEvent(event, mUserId);
26675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Binder.restoreCallingIdentity(identityToken);
267736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            if (DEBUG) {
26875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                Log.i(LOG_TAG, event + " sent");
26975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
27075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        } catch (RemoteException re) {
27175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Log.e(LOG_TAG, "Error during sending " + event + " ", re);
27275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        } finally {
27375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            if (doRecycle) {
27475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                event.recycle();
27575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
27675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
27775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
27875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
27975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
28038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * Requests feedback interruption from all accessibility services.
28175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
28275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public void interrupt() {
28375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        if (!mIsEnabled) {
28475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            throw new IllegalStateException("Accessibility off. Did you forget to check that?");
28575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
28675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        try {
28758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mService.interrupt(mUserId);
288736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            if (DEBUG) {
28975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                Log.i(LOG_TAG, "Requested interrupt from all services");
29075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
29175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        } catch (RemoteException re) {
29275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Log.e(LOG_TAG, "Error while requesting interrupt from all services. ", re);
29375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
29475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
29575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
29675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
29775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Returns the {@link ServiceInfo}s of the installed accessibility services.
29875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
29975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @return An unmodifiable list with {@link ServiceInfo}s.
300cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     *
301cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * @deprecated Use {@link #getInstalledAccessibilityServiceList()}
30275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
303cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov    @Deprecated
30475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public List<ServiceInfo> getAccessibilityServiceList() {
305cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        List<AccessibilityServiceInfo> infos = getInstalledAccessibilityServiceList();
306cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        List<ServiceInfo> services = new ArrayList<ServiceInfo>();
307cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        final int infoCount = infos.size();
308cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        for (int i = 0; i < infoCount; i++) {
309cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            AccessibilityServiceInfo info = infos.get(i);
310cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            services.add(info.getResolveInfo().serviceInfo);
311cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        }
312cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        return Collections.unmodifiableList(services);
313cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov    }
314cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov
315cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov    /**
316cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * Returns the {@link AccessibilityServiceInfo}s of the installed accessibility services.
317cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     *
318cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
319cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     */
320cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
321cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        List<AccessibilityServiceInfo> services = null;
32275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        try {
32358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            services = mService.getInstalledAccessibilityServiceList(mUserId);
324736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            if (DEBUG) {
325736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
326736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            }
327736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        } catch (RemoteException re) {
328736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re);
329736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        }
330736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return Collections.unmodifiableList(services);
331736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
332736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
333736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    /**
334cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
335736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * for a given feedback type.
336736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     *
33738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @param feedbackTypeFlags The feedback type flags.
338cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov     * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
33938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     *
34038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
34138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
34238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
34338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
34438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
345736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     */
34638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
34738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov            int feedbackTypeFlags) {
348cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        List<AccessibilityServiceInfo> services = null;
349736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        try {
35058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags, mUserId);
351736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            if (DEBUG) {
35275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
35375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
35475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        } catch (RemoteException re) {
35575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re);
35675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
35775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        return Collections.unmodifiableList(services);
35875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
3598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
36138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * Registers an {@link AccessibilityStateChangeListener} for changes in
36238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov     * the global accessibility state of the system.
3638643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     *
3648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @param listener The listener.
3658643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @return True if successfully registered.
3668643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
3678643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public boolean addAccessibilityStateChangeListener(
3688643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            AccessibilityStateChangeListener listener) {
3698643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        return mAccessibilityStateChangeListeners.add(listener);
3708643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
3718643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3728643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
3738643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * Unregisters an {@link AccessibilityStateChangeListener}.
3748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     *
3758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @param listener The listener.
3768643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @return True if successfully unregistered.
3778643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
3788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public boolean removeAccessibilityStateChangeListener(
3798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            AccessibilityStateChangeListener listener) {
3808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        return mAccessibilityStateChangeListeners.remove(listener);
3818643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
3828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3838643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
38400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov     * Sets the current state.
38500aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov     *
38600aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov     * @param stateFlags The state flags.
38700aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov     */
38800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    private void setState(int stateFlags) {
38900aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        final boolean accessibilityEnabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
39000aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        setAccessibilityState(accessibilityEnabled);
39100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov        mIsTouchExplorationEnabled = (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0;
39200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    }
39300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov
39400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    /**
3958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * Sets the enabled state.
3968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     *
3978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @param isEnabled The accessibility state.
3988643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
3998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    private void setAccessibilityState(boolean isEnabled) {
4008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        synchronized (mHandler) {
4018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            if (isEnabled != mIsEnabled) {
4028643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                mIsEnabled = isEnabled;
4038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                notifyAccessibilityStateChanged();
4048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
4058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
4068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
4078643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
4088643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
4098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * Notifies the registered {@link AccessibilityStateChangeListener}s.
4108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
4118643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    private void notifyAccessibilityStateChanged() {
4128643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        final int listenerCount = mAccessibilityStateChangeListeners.size();
4138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        for (int i = 0; i < listenerCount; i++) {
4148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(mIsEnabled);
4158643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
4168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
4178643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
4188643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
4198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * Adds an accessibility interaction connection interface for a given window.
4208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @param windowToken The window token to which a connection is added.
4218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @param connection The connection.
4228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     *
4238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @hide
4248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
4258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public int addAccessibilityInteractionConnection(IWindow windowToken,
4268643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            IAccessibilityInteractionConnection connection) {
4278643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
42858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            return mService.addAccessibilityInteractionConnection(windowToken, connection, mUserId);
4298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } catch (RemoteException re) {
4308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re);
4318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
4328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        return View.NO_ID;
4338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
4348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
4358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    /**
4368643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * Removed an accessibility interaction connection interface for a given window.
4378643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @param windowToken The window token to which a connection is removed.
4388643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     *
4398643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     * @hide
4408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov     */
4418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public void removeAccessibilityInteractionConnection(IWindow windowToken) {
4428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        try {
4438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            mService.removeAccessibilityInteractionConnection(windowToken);
4448643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        } catch (RemoteException re) {
4458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            Log.e(LOG_TAG, "Error while removing an accessibility interaction connection. ", re);
4468643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
4478643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
44875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov}
449