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; 3075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.Log; 318643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.IWindow; 328643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.View; 3375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 34cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganovimport java.util.ArrayList; 3575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Collections; 3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.List; 378643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport java.util.concurrent.CopyOnWriteArrayList; 3875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 3975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/** 4038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * System level service that serves as an event dispatch for {@link AccessibilityEvent}s, 4138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * and provides facilities for querying the accessibility state of the system. 4238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Accessibility events are generated when something notable happens in the user interface, 4375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * for example an {@link android.app.Activity} starts, the focus or selection of a 4475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link android.view.View} changes etc. Parties interested in handling accessibility 4575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * events implement and register an accessibility service which extends 4675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link android.accessibilityservice.AccessibilityService}. 4738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p> 4838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * To obtain a handle to the accessibility manager do the following: 4938e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p> 5038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <p> 5138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * <code> 52b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * <pre>AccessibilityManager accessibilityManager = 53b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);</pre> 5438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </code> 5538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * </p> 5675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 5775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see AccessibilityEvent 5838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityNodeInfo 5975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @see android.accessibilityservice.AccessibilityService 6038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see Context#getSystemService 6138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see Context#ACCESSIBILITY_SERVICE 6275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 6375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovpublic final class AccessibilityManager { 64736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov private static final boolean DEBUG = false; 65736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 6675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static final String LOG_TAG = "AccessibilityManager"; 6775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 6800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov /** @hide */ 6900aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov public static final int STATE_FLAG_ACCESSIBILITY_ENABLED = 0x00000001; 7000aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov 7100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov /** @hide */ 7200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002; 7300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov 7475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov static final Object sInstanceSync = new Object(); 7575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 7675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static AccessibilityManager sInstance; 7775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 7800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov private static final int DO_SET_STATE = 10; 7975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final IAccessibilityManager mService; 8175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final Handler mHandler; 8375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean mIsEnabled; 8575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8635bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov boolean mIsTouchExplorationEnabled; 8735bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov 888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final CopyOnWriteArrayList<AccessibilityStateChangeListener> mAccessibilityStateChangeListeners = 898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov new CopyOnWriteArrayList<AccessibilityStateChangeListener>(); 908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 92b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * Listener for the system accessibility state. To listen for changes to the accessibility 93b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * state on the device, implement this interface and register it with the system by 94b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * calling {@link AccessibilityManager#addAccessibilityStateChangeListener 95b303d8381d734f48c4e1de4f11bf25950b28adf1Scott Main * addAccessibilityStateChangeListener()}. 968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public interface AccessibilityStateChangeListener { 9838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov 998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 1008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Called back on change in the accessibility state. 1018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * 10238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @param enabled Whether accessibility is enabled. 1038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 1048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public void onAccessibilityStateChanged(boolean enabled); 1058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 1068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 10775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() { 10800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov public void setState(int state) { 10900aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov mHandler.obtainMessage(DO_SET_STATE, state, 0).sendToTarget(); 11075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 11175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov }; 11275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 11375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov class MyHandler extends Handler { 11475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 11575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov MyHandler(Looper mainLooper) { 11675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov super(mainLooper); 11775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 11875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 11975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 12075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void handleMessage(Message message) { 12175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov switch (message.what) { 12200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov case DO_SET_STATE : 12300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov setState(message.arg1); 12475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return; 12575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov default : 12675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.w(LOG_TAG, "Unknown message type: " + message.what); 12775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 12875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 12975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 13075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 13175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 13275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Get an AccessibilityManager instance (create one if necessary). 13375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 13475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @hide 13575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 13675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public static AccessibilityManager getInstance(Context context) { 13775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (sInstanceSync) { 13875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (sInstance == null) { 139af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE); 140af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder); 141af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov sInstance = new AccessibilityManager(context, service); 14275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 14375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 14475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return sInstance; 14575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 14675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 14775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 14875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Create an instance. 14975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 15075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param context A {@link Context}. 151af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * @param service An interface to the backing service. 152af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * 153af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * @hide 15475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 155af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov public AccessibilityManager(Context context, IAccessibilityManager service) { 15675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mHandler = new MyHandler(context.getMainLooper()); 157af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov mService = service; 158af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov 15975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 16000aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov final int stateFlags = mService.addClient(mClient); 16100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov setState(stateFlags); 16275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 16375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.e(LOG_TAG, "AccessibilityManagerService is dead", re); 16475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 16575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 16675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 16775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 16838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Returns if the accessibility in the system is enabled. 16975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 17038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @return True if accessibility is enabled, false otherwise. 17175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 17275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public boolean isEnabled() { 17375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mHandler) { 17475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return mIsEnabled; 17575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 17675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 17775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 17875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 17935bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov * Returns if the touch exploration in the system is enabled. 18035bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov * 18135bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov * @return True if touch exploration is enabled, false otherwise. 18235bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov */ 18335bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov public boolean isTouchExplorationEnabled() { 18435bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov synchronized (mHandler) { 18535bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov return mIsTouchExplorationEnabled; 18635bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov } 18735bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov } 18835bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov 18935bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov /** 190af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * Returns the client interface this instance registers in 191af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * the centralized accessibility manager service. 192af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * 193af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * @return The client. 194af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * 195af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov * @hide 196af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov */ 197af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov public IAccessibilityManagerClient getClient() { 1984dfecf55c1afcc7ffe0cef931df67c4934a13e34Jim Miller return (IAccessibilityManagerClient) mClient.asBinder(); 199af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov } 200af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov 201af7adab3e35863fff24e701039d5d04afbc060c5Svetoslav Ganov /** 20238e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Sends an {@link AccessibilityEvent}. 20375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 20438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @param event The event to send. 20575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 20638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @throws IllegalStateException if accessibility is not enabled. 20775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 20875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void sendAccessibilityEvent(AccessibilityEvent event) { 20975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (!mIsEnabled) { 21075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov throw new IllegalStateException("Accessibility off. Did you forget to check that?"); 21175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 21275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean doRecycle = false; 21375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 21475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov event.setEventTime(SystemClock.uptimeMillis()); 21575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // it is possible that this manager is in the same process as the service but 21675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // client using it is called through Binder from another process. Example: MMS 21775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // app adds a SMS notification and the NotificationManagerService calls this method 21875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov long identityToken = Binder.clearCallingIdentity(); 21975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov doRecycle = mService.sendAccessibilityEvent(event); 22075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Binder.restoreCallingIdentity(identityToken); 221736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov if (DEBUG) { 22275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.i(LOG_TAG, event + " sent"); 22375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 22475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 22575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.e(LOG_TAG, "Error during sending " + event + " ", re); 22675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } finally { 22775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (doRecycle) { 22875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov event.recycle(); 22975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 23075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 23175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 23275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 23375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 23438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Requests feedback interruption from all accessibility services. 23575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 23675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void interrupt() { 23775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (!mIsEnabled) { 23875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov throw new IllegalStateException("Accessibility off. Did you forget to check that?"); 23975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 24075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 24175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mService.interrupt(); 242736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov if (DEBUG) { 24375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.i(LOG_TAG, "Requested interrupt from all services"); 24475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 24575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 24675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.e(LOG_TAG, "Error while requesting interrupt from all services. ", re); 24775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 24875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 24975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 25075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 25175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Returns the {@link ServiceInfo}s of the installed accessibility services. 25275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 25375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @return An unmodifiable list with {@link ServiceInfo}s. 254cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * 255cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * @deprecated Use {@link #getInstalledAccessibilityServiceList()} 25675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 257cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov @Deprecated 25875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public List<ServiceInfo> getAccessibilityServiceList() { 259cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov List<AccessibilityServiceInfo> infos = getInstalledAccessibilityServiceList(); 260cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov List<ServiceInfo> services = new ArrayList<ServiceInfo>(); 261cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov final int infoCount = infos.size(); 262cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov for (int i = 0; i < infoCount; i++) { 263cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov AccessibilityServiceInfo info = infos.get(i); 264cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov services.add(info.getResolveInfo().serviceInfo); 265cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } 266cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov return Collections.unmodifiableList(services); 267cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } 268cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov 269cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov /** 270cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * Returns the {@link AccessibilityServiceInfo}s of the installed accessibility services. 271cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * 272cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * @return An unmodifiable list with {@link AccessibilityServiceInfo}s. 273cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov */ 274cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() { 275cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov List<AccessibilityServiceInfo> services = null; 27675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 277cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov services = mService.getInstalledAccessibilityServiceList(); 278736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov if (DEBUG) { 279736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov Log.i(LOG_TAG, "Installed AccessibilityServices " + services); 280736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 281736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } catch (RemoteException re) { 282736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re); 283736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 284736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov return Collections.unmodifiableList(services); 285736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 286736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 287736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov /** 288cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services 289736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov * for a given feedback type. 290736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov * 29138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @param feedbackTypeFlags The feedback type flags. 292cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov * @return An unmodifiable list with {@link AccessibilityServiceInfo}s. 29338e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * 29438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE 29538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityServiceInfo#FEEDBACK_GENERIC 29638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC 29738e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN 29838e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * @see AccessibilityServiceInfo#FEEDBACK_VISUAL 299736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov */ 30038e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList( 30138e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov int feedbackTypeFlags) { 302cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov List<AccessibilityServiceInfo> services = null; 303736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov try { 30438e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags); 305736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov if (DEBUG) { 30675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.i(LOG_TAG, "Installed AccessibilityServices " + services); 30775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 30875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 30975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re); 31075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 31175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return Collections.unmodifiableList(services); 31275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 3138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 3148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 31538e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * Registers an {@link AccessibilityStateChangeListener} for changes in 31638e8b4e5bc3c93affdffbc064fd9db5aeccc3e8eSvetoslav Ganov * the global accessibility state of the system. 3178643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * 3188643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @param listener The listener. 3198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @return True if successfully registered. 3208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 3218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public boolean addAccessibilityStateChangeListener( 3228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov AccessibilityStateChangeListener listener) { 3238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return mAccessibilityStateChangeListeners.add(listener); 3248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 3268643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 3278643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Unregisters an {@link AccessibilityStateChangeListener}. 3288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * 3298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @param listener The listener. 3308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @return True if successfully unregistered. 3318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 3328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public boolean removeAccessibilityStateChangeListener( 3338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov AccessibilityStateChangeListener listener) { 3348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return mAccessibilityStateChangeListeners.remove(listener); 3358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3368643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 3378643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 33800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov * Sets the current state. 33900aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov * 34000aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov * @param stateFlags The state flags. 34100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov */ 34200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov private void setState(int stateFlags) { 34300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov final boolean accessibilityEnabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0; 34400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov setAccessibilityState(accessibilityEnabled); 34500aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov mIsTouchExplorationEnabled = (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0; 34600aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov } 34700aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov 34800aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov /** 3498643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Sets the enabled state. 3508643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * 3518643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @param isEnabled The accessibility state. 3528643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 3538643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private void setAccessibilityState(boolean isEnabled) { 3548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mHandler) { 3558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (isEnabled != mIsEnabled) { 3568643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mIsEnabled = isEnabled; 3578643aa0179e598e78d938c59035389054535a229Svetoslav Ganov notifyAccessibilityStateChanged(); 3588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3618643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 3628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 3638643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Notifies the registered {@link AccessibilityStateChangeListener}s. 3648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 3658643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private void notifyAccessibilityStateChanged() { 3668643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final int listenerCount = mAccessibilityStateChangeListeners.size(); 3678643aa0179e598e78d938c59035389054535a229Svetoslav Ganov for (int i = 0; i < listenerCount; i++) { 3688643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(mIsEnabled); 3698643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3708643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3718643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 3728643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 3738643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Adds an accessibility interaction connection interface for a given window. 3748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @param windowToken The window token to which a connection is added. 3758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @param connection The connection. 3768643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * 3778643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @hide 3788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 3798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public int addAccessibilityInteractionConnection(IWindow windowToken, 3808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov IAccessibilityInteractionConnection connection) { 3818643aa0179e598e78d938c59035389054535a229Svetoslav Ganov try { 3828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return mService.addAccessibilityInteractionConnection(windowToken, connection); 3838643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } catch (RemoteException re) { 3848643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re); 3858643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3868643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return View.NO_ID; 3878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 3888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 3898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov /** 3908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * Removed an accessibility interaction connection interface for a given window. 3918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @param windowToken The window token to which a connection is removed. 3928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * 3938643aa0179e598e78d938c59035389054535a229Svetoslav Ganov * @hide 3948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov */ 3958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public void removeAccessibilityInteractionConnection(IWindow windowToken) { 3968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov try { 3978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mService.removeAccessibilityInteractionConnection(windowToken); 3988643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } catch (RemoteException re) { 3998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Log.e(LOG_TAG, "Error while removing an accessibility interaction connection. ", re); 4008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 40275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov} 403