175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/* 275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov ** Copyright 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 com.android.server; 1875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor; 2075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport com.android.internal.os.HandlerCaller; 2175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport com.android.internal.os.HandlerCaller.SomeArgs; 2275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.AccessibilityService; 2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.AccessibilityServiceInfo; 2575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.IAccessibilityServiceConnection; 2675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.IEventListener; 27dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.app.PendingIntent; 2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.BroadcastReceiver; 2975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ComponentName; 3075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ContentResolver; 3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context; 3275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Intent; 3375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.IntentFilter; 3475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ServiceConnection; 3575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.PackageManager; 3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.ResolveInfo; 3775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.ServiceInfo; 3875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.database.ContentObserver; 3975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.net.Uri; 4075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Binder; 4175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.DeadObjectException; 4275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Handler; 4375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.IBinder; 4475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Message; 4575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.RemoteException; 4675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.provider.Settings; 4775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.text.TextUtils; 4875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.text.TextUtils.SimpleStringSplitter; 49714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganovimport android.util.Config; 508a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 5175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.SparseArray; 5275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent; 5375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.IAccessibilityManager; 5475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.IAccessibilityManagerClient; 5575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 5675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.ArrayList; 5775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Arrays; 5875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.HashMap; 5975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.HashSet; 6021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport java.util.Iterator; 6175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.List; 6275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Map; 6375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Set; 6475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 6575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/** 6675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * This class is instantiated by the system as a system level service and can be 6775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * accessed only by the system. The task of this service is to be a centralized 6875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * event dispatch for {@link AccessibilityEvent}s generated across all processes 6975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * on the device. Events are dispatched to {@link AccessibilityService}s. 7075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 7175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @hide 7275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 7375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovpublic class AccessibilityManagerService extends IAccessibilityManager.Stub 7475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov implements HandlerCaller.Callback { 7575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 7675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static final String LOG_TAG = "AccessibilityManagerService"; 7775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 7875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static int sIdCounter = 0; 7975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static final int OWN_PROCESS_ID = android.os.Process.myPid(); 8175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static final int DO_SET_SERVICE_INFO = 10; 8375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final HandlerCaller mCaller; 8575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final Context mContext; 8775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final Object mLock = new Object(); 8975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 9075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final List<Service> mServices = new ArrayList<Service>(); 9175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 9275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final List<IAccessibilityManagerClient> mClients = 9375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new ArrayList<IAccessibilityManagerClient>(); 9475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 9575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final Map<ComponentName, Service> mComponentNameToServiceMap = 9675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new HashMap<ComponentName, Service>(); 9775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 9875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private final List<ServiceInfo> mInstalledServices = new ArrayList<ServiceInfo>(); 9975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>(); 10175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(':'); 10375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private PackageManager mPackageManager; 10575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private int mHandledFeedbackTypes = 0; 10775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private boolean mIsEnabled; 10975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 11075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 11175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Handler for delayed event dispatch. 11275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 11375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private Handler mHandler = new Handler() { 11475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 11575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 11675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void handleMessage(Message message) { 11775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = (Service) message.obj; 11875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int eventType = message.arg1; 11975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 12075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 12175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov notifyEventListenerLocked(service, eventType); 12275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov AccessibilityEvent oldEvent = service.mPendingEvents.get(eventType); 12375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mPendingEvents.remove(eventType); 12475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov tryRecycleLocked(oldEvent); 12575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 12675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 12775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov }; 12875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 12975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 13075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Creates a new instance. 13175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 13275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param context A {@link Context} instance. 13375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 13475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov AccessibilityManagerService(Context context) { 13575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mContext = context; 13675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mPackageManager = mContext.getPackageManager(); 13775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mCaller = new HandlerCaller(context, this); 13875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 13975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov registerPackageChangeAndBootCompletedBroadcastReceiver(); 14075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov registerSettingsContentObservers(); 14175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 14275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 14375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 14475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Registers a {@link BroadcastReceiver} for the events of 14575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * adding/changing/removing/restarting a package and boot completion. 14675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 14775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void registerPackageChangeAndBootCompletedBroadcastReceiver() { 14875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Context context = mContext; 14975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn PackageMonitor monitor = new PackageMonitor() { 15175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 15221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void onSomePackagesChanged() { 15375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 15475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov populateAccessibilityServiceListLocked(); 15521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn manageServicesLocked(); 15621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 15721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 15821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 15921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn @Override 16021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean onHandleForceStop(Intent intent, String[] packages, 16121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn int uid, boolean doit) { 16221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (mLock) { 16321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn boolean changed = false; 16421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Iterator<ComponentName> it = mEnabledServices.iterator(); 16521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn while (it.hasNext()) { 16621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName comp = it.next(); 16721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String compPkg = comp.getPackageName(); 16821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String pkg : packages) { 16921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (compPkg.equals(pkg)) { 17021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (!doit) { 17121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 17221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 17321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn it.remove(); 17421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn changed = true; 17521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 17621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 17721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 17821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (changed) { 17921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn it = mEnabledServices.iterator(); 18021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn StringBuilder str = new StringBuilder(); 18121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn while (it.hasNext()) { 18221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (str.length() > 0) { 18321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn str.append(':'); 18421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 18521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn str.append(it.next().flattenToShortString()); 18621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 18721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Settings.Secure.putString(mContext.getContentResolver(), 18821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, 18921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn str.toString()); 19021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn manageServicesLocked(); 19121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 19221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 19321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 19421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 19521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 19621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn @Override 19721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void onReceive(Context context, Intent intent) { 19821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) { 19921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (mLock) { 20021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn populateAccessibilityServiceListLocked(); 20175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 202714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov // get the accessibility enabled setting on boot 20375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(), 20475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; 205714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov 206714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov // if accessibility is enabled inform our clients we are on 207714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov if (mIsEnabled) { 208714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov updateClientsLocked(); 209714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov } 210714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov 21121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn manageServicesLocked(); 21221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 21321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 21421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 21575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 21621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 21721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn super.onReceive(context, intent); 21875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 21975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov }; 22075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 22175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // package changes 22221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn monitor.register(context, true); 22375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 22475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // boot completed 22575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov IntentFilter bootFiler = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); 22621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mContext.registerReceiver(monitor, bootFiler); 22775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 22875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 22975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 23075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link ContentObserver}s for {@link Settings.Secure#ACCESSIBILITY_ENABLED} 23175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * and {@link Settings.Secure#ENABLED_ACCESSIBILITY_SERVICES} settings. 23275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 23375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void registerSettingsContentObservers() { 23475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov ContentResolver contentResolver = mContext.getContentResolver(); 23575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 23675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Uri enabledUri = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED); 23775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov contentResolver.registerContentObserver(enabledUri, false, 23875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new ContentObserver(new Handler()) { 23975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 24075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void onChange(boolean selfChange) { 24175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov super.onChange(selfChange); 24275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 24375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(), 24475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; 24575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 24675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 24775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (mIsEnabled) { 24875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov manageServicesLocked(); 24975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 25075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov unbindAllServicesLocked(); 25175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 25275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov updateClientsLocked(); 25375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 25475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 25575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov }); 25675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 25775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Uri providersUri = 25875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); 25975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov contentResolver.registerContentObserver(providersUri, false, 26075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new ContentObserver(new Handler()) { 26175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 26275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void onChange(boolean selfChange) { 26375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov super.onChange(selfChange); 26475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 26575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 26675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov manageServicesLocked(); 26775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 26875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 26975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov }); 27075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 27175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 27275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void addClient(IAccessibilityManagerClient client) { 27375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 27475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 27575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov client.setEnabled(mIsEnabled); 27675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mClients.add(client); 27775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 2788a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(LOG_TAG, "Dead AccessibilityManagerClient: " + client, re); 27975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 28075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 28175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 28275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 28375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public boolean sendAccessibilityEvent(AccessibilityEvent event) { 28475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 28575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov notifyAccessibilityServicesDelayedLocked(event, false); 28675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov notifyAccessibilityServicesDelayedLocked(event, true); 28775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 28875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // event not scheduled for dispatch => recycle 28975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (mHandledFeedbackTypes == 0) { 29075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov event.recycle(); 29175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 29275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mHandledFeedbackTypes = 0; 29375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 29475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 29575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return (OWN_PROCESS_ID != Binder.getCallingPid()); 29675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 29775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 29875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public List<ServiceInfo> getAccessibilityServiceList() { 29975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 30075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return mInstalledServices; 30175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 30275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 30375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 30475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void interrupt() { 30575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 30675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = mServices.size(); i < count; i++) { 30775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = mServices.get(i); 30875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 30975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mServiceInterface.onInterrupt(); 31075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 31175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (re instanceof DeadObjectException) { 3128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(LOG_TAG, "Dead " + service.mService + ". Cleaning up."); 31375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (removeDeadServiceLocked(service)) { 31475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov count--; 31575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov i--; 31675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 31775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 3188a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(LOG_TAG, "Error during sending interrupt request to " 31975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov + service.mService, re); 32075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 32175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 32275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 32375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 32475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 32575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 32675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void executeMessage(Message message) { 32775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov switch (message.what) { 32875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov case DO_SET_SERVICE_INFO: 32975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov SomeArgs arguments = ((SomeArgs) message.obj); 33075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 33175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov AccessibilityServiceInfo info = (AccessibilityServiceInfo) arguments.arg1; 33275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = (Service) arguments.arg2; 33375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 33475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 33575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mEventTypes = info.eventTypes; 33675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mFeedbackType = info.feedbackType; 33775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov String[] packageNames = info.packageNames; 33875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (packageNames != null) { 33975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mPackageNames.addAll(Arrays.asList(packageNames)); 34075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 34175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mNotificationTimeout = info.notificationTimeout; 34275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mIsDefault = (info.flags & AccessibilityServiceInfo.DEFAULT) != 0; 34375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 34475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return; 34575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov default: 3468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(LOG_TAG, "Unknown message type: " + message.what); 34775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 34875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 34975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 35075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 35175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Populates the cached list of installed {@link AccessibilityService}s. 35275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 35375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void populateAccessibilityServiceListLocked() { 35475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mInstalledServices.clear(); 35575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 35675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov List<ResolveInfo> installedServices = mPackageManager.queryIntentServices( 35775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new Intent(AccessibilityService.SERVICE_INTERFACE), PackageManager.GET_SERVICES); 35875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 35975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = installedServices.size(); i < count; i++) { 36075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mInstalledServices.add(installedServices.get(i).serviceInfo); 36175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 36275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 36375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 36475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 36575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Performs {@link AccessibilityService}s delayed notification. The delay is configurable 36675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * and denotes the period after the last event before notifying the service. 36775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 36875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param event The event. 36975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param isDefault True to notify default listeners, not default services. 37075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 37175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event, 37275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean isDefault) { 37385b598beda98706fafd05c7de9866d83d4a19965Charles Chen try { 37485b598beda98706fafd05c7de9866d83d4a19965Charles Chen for (int i = 0, count = mServices.size(); i < count; i++) { 37585b598beda98706fafd05c7de9866d83d4a19965Charles Chen Service service = mServices.get(i); 37675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 37785b598beda98706fafd05c7de9866d83d4a19965Charles Chen if (service.mIsDefault == isDefault) { 37885b598beda98706fafd05c7de9866d83d4a19965Charles Chen if (canDispathEventLocked(service, event, mHandledFeedbackTypes)) { 37985b598beda98706fafd05c7de9866d83d4a19965Charles Chen mHandledFeedbackTypes |= service.mFeedbackType; 38085b598beda98706fafd05c7de9866d83d4a19965Charles Chen notifyAccessibilityServiceDelayedLocked(service, event); 38185b598beda98706fafd05c7de9866d83d4a19965Charles Chen } 38275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 38375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 38485b598beda98706fafd05c7de9866d83d4a19965Charles Chen } catch (IndexOutOfBoundsException oobe) { 38585b598beda98706fafd05c7de9866d83d4a19965Charles Chen // An out of bounds exception can happen if services are going away 38685b598beda98706fafd05c7de9866d83d4a19965Charles Chen // as the for loop is running. If that happens, just bail because 38785b598beda98706fafd05c7de9866d83d4a19965Charles Chen // there are no more services to notify. 38885b598beda98706fafd05c7de9866d83d4a19965Charles Chen return; 38975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 39075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 39175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 39275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 39375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Performs an {@link AccessibilityService} delayed notification. The delay is configurable 39475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * and denotes the period after the last event before notifying the service. 39575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 39675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param service The service. 39775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param event The event. 39875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 39975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void notifyAccessibilityServiceDelayedLocked(Service service, 40075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov AccessibilityEvent event) { 40175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 40275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int eventType = event.getEventType(); 40375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov AccessibilityEvent oldEvent = service.mPendingEvents.get(eventType); 40475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.mPendingEvents.put(eventType, event); 40575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 40675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int what = eventType | (service.mId << 16); 40775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (oldEvent != null) { 40875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mHandler.removeMessages(what); 40975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov tryRecycleLocked(oldEvent); 41075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 41175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 41275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Message message = mHandler.obtainMessage(what, service); 41375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov message.arg1 = event.getEventType(); 41475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mHandler.sendMessageDelayed(message, service.mNotificationTimeout); 41575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 41675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 41775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 41875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 41975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Recycles an event if it can be safely recycled. The condition is that no 42075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * not notified service is interested in the event. 42175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 42275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param event The event. 42375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 42475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void tryRecycleLocked(AccessibilityEvent event) { 425bbc1934e0e1347b05580ae35b7a62f828f0ac5e7Charles Chen if (event == null) { 426bbc1934e0e1347b05580ae35b7a62f828f0ac5e7Charles Chen return; 427bbc1934e0e1347b05580ae35b7a62f828f0ac5e7Charles Chen } 42875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int eventType = event.getEventType(); 42975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov List<Service> services = mServices; 43075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 43175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // linear in the number of service which is not large 43275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = services.size(); i < count; i++) { 43375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = services.get(i); 43475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (service.mPendingEvents.get(eventType) == event) { 43575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return; 43675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 43775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 43875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov event.recycle(); 43975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 44075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 44175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 44275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Notifies a service for a scheduled event given the event type. 44375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 44475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param service The service. 44575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param eventType The type of the event to dispatch. 44675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 44775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void notifyEventListenerLocked(Service service, int eventType) { 44875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov IEventListener listener = service.mServiceInterface; 44975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov AccessibilityEvent event = service.mPendingEvents.get(eventType); 45075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 45175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 45275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov listener.onAccessibilityEvent(event); 453714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov if (Config.DEBUG) { 4548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(LOG_TAG, "Event " + event + " sent to " + listener); 45575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 45675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 45775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (re instanceof DeadObjectException) { 4588a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(LOG_TAG, "Dead " + service.mService + ". Cleaning up."); 45975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 46075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov removeDeadServiceLocked(service); 46175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 46275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 4638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(LOG_TAG, "Error during sending " + event + " to " + service.mService, re); 46475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 46575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 46675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 46775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 46875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 46975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Removes a dead service. 47075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 47175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param service The service. 47275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @return True if the service was removed, false otherwise. 47375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 47475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private boolean removeDeadServiceLocked(Service service) { 47575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mServices.remove(service); 47675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mHandler.removeMessages(service.mId); 47775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 478714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov if (Config.DEBUG) { 4798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(LOG_TAG, "Dead service " + service.mService + " removed"); 48075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 48175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 48275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (mServices.isEmpty()) { 48375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mIsEnabled = false; 48475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov updateClientsLocked(); 48575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 48675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 48775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return true; 48875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 48975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 49075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 49175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Determines if given event can be dispatched to a service based on the package of the 49275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * event source and already notified services for that event type. Specifically, a 49375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * service is notified if it is interested in events from the package and no other service 49475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * providing the same feedback type has been notified. Exception are services the 49575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * provide generic feedback (feedback type left as a safety net for unforeseen feedback 49675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * types) which are always notified. 49775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 49875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param service The potential receiver. 49975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param event The event. 50075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param handledFeedbackTypes The feedback types for which services have been notified. 50175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @return True if the listener should be notified, false otherwise. 50275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 50375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private boolean canDispathEventLocked(Service service, AccessibilityEvent event, 50475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int handledFeedbackTypes) { 50575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 50675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (!service.isConfigured()) { 50775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 50875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 50975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 51075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (!service.mService.isBinderAlive()) { 51175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov removeDeadServiceLocked(service); 51275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 51375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 51475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 51575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int eventType = event.getEventType(); 51675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if ((service.mEventTypes & eventType) != eventType) { 51775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 51875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 51975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 52075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Set<String> packageNames = service.mPackageNames; 52175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov CharSequence packageName = event.getPackageName(); 52275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 52375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (packageNames.isEmpty() || packageNames.contains(packageName)) { 52475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int feedbackType = service.mFeedbackType; 52575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if ((handledFeedbackTypes & feedbackType) != feedbackType 52675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov || feedbackType == AccessibilityServiceInfo.FEEDBACK_GENERIC) { 52775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return true; 52875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 52975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 53075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 53175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 53275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 53375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 53475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 53575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Manages services by starting enabled ones and stopping disabled ones. 53675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 53775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void manageServicesLocked() { 53875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov populateEnabledServicesLocked(mEnabledServices); 53975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov updateServicesStateLocked(mInstalledServices, mEnabledServices); 54075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 54175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 54275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 54375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Unbinds all bound services. 54475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 54575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void unbindAllServicesLocked() { 54675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov List<Service> services = mServices; 54775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 54875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = services.size(); i < count; i++) { 54975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = services.get(i); 55075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 55175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.unbind(); 55275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mComponentNameToServiceMap.remove(service.mComponentName); 55375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 55475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov services.clear(); 55575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 55675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 55775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 55875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Populates a list with the {@link ComponentName}s of all enabled 55975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * {@link AccessibilityService}s. 56075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 56175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param enabledServices The list. 56275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 56375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void populateEnabledServicesLocked(Set<ComponentName> enabledServices) { 56475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov enabledServices.clear(); 56575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 56675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov String servicesValue = Settings.Secure.getString(mContext.getContentResolver(), 56775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); 56875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 56975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (servicesValue != null) { 57075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; 57175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov splitter.setString(servicesValue); 57275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov while (splitter.hasNext()) { 57321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String str = splitter.next(); 57421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (str == null || str.length() <= 0) { 57521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn continue; 57621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 57721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName enabledService = ComponentName.unflattenFromString(str); 57821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (enabledService != null) { 57921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn enabledServices.add(enabledService); 58021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 58175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 58275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 58375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 58475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 58575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 58675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Updates the state of each service by starting (or keeping running) enabled ones and 58775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * stopping the rest. 58875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 58975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param installedServices All installed {@link AccessibilityService}s. 59075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param enabledServices The {@link ComponentName}s of the enabled services. 59175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 59275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void updateServicesStateLocked(List<ServiceInfo> installedServices, 59375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Set<ComponentName> enabledServices) { 59475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 59575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Map<ComponentName, Service> componentNameToServiceMap = mComponentNameToServiceMap; 59675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov List<Service> services = mServices; 597714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov boolean isEnabled = mIsEnabled; 59875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 59975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = installedServices.size(); i < count; i++) { 60075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov ServiceInfo intalledService = installedServices.get(i); 60175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov ComponentName componentName = new ComponentName(intalledService.packageName, 60275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov intalledService.name); 60375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = componentNameToServiceMap.get(componentName); 60475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 605714cff06939281b27673fbe5edf384af6a72dea6Svetoslav Ganov if (isEnabled && enabledServices.contains(componentName)) { 60675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (service == null) { 60775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new Service(componentName).bind(); 60875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 60975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 61075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (service != null) { 61175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.unbind(); 61275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov componentNameToServiceMap.remove(componentName); 61375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov services.remove(service); 61475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 61575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 61675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 61775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 61875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 61975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 62075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Updates the state of {@link android.view.accessibility.AccessibilityManager} clients. 62175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 62275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void updateClientsLocked() { 62375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = mClients.size(); i < count; i++) { 62475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 62575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mClients.get(i).setEnabled(mIsEnabled); 62675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 62775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mClients.remove(i); 62875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov count--; 629fb606da00cbfc9d2e79a4df6929c3d720f25729fSvetoslav Ganov i--; 63075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 63175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 63275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 63375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 63475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 63575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * This class represents an accessibility service. It stores all per service 63675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * data required for the service management, provides API for starting/stopping the 63775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * service and is responsible for adding/removing the service in the data structures 63875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * for service management. The class also exposes configuration interface that is 63975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * passed to the service it represents as soon it is bound. It also serves as the 64075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * connection for the service. 64175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 64275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov class Service extends IAccessibilityServiceConnection.Stub implements ServiceConnection { 64375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int mId = 0; 64475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 64575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov IBinder mService; 64675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 64775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov IEventListener mServiceInterface; 64875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 64975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int mEventTypes; 65075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 65175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int mFeedbackType; 65275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 65375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Set<String> mPackageNames = new HashSet<String>(); 65475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 65575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean mIsDefault; 65675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 65775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov long mNotificationTimeout; 65875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 65975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean mIsActive; 66075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 66175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov ComponentName mComponentName; 66275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 66375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Intent mIntent; 66475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 66575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // the events pending events to be dispatched to this service 66675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final SparseArray<AccessibilityEvent> mPendingEvents = 66775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new SparseArray<AccessibilityEvent>(); 66875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 66975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service(ComponentName componentName) { 67075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mId = sIdCounter++; 67175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mComponentName = componentName; 67275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mIntent = new Intent().setComponent(mComponentName); 673dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, 674dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn com.android.internal.R.string.accessibility_binding_label); 675dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( 676dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0)); 67775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 67875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 67975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 68075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Binds to the accessibility service. 68175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 68275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void bind() { 68375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (mService == null) { 68475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mContext.bindService(mIntent, this, Context.BIND_AUTO_CREATE); 68575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 68675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 68775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 68875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 68975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Unbinds form the accessibility service and removes it from the data 69075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * structures for service management. 69175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 69275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void unbind() { 69375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (mService != null) { 69475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mContext.unbindService(this); 69575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 69675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 69775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 69875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 69975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Returns if the service is configured i.e. at least event types of interest 70075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * and feedback type must be set. 70175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 70275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @return True if the service is configured, false otherwise. 70375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 70475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public boolean isConfigured() { 70575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return (mEventTypes != 0 && mFeedbackType != 0); 70675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 70775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 70875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void setServiceInfo(AccessibilityServiceInfo info) { 70975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mCaller.obtainMessageOO(DO_SET_SERVICE_INFO, info, this).sendToTarget(); 71075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 71175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 71275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void onServiceConnected(ComponentName componentName, IBinder service) { 71375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mService = service; 71475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mServiceInterface = IEventListener.Stub.asInterface(service); 71575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 71675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 71775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mServiceInterface.setConnection(this); 71875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 71975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (!mServices.contains(this)) { 72075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mServices.add(this); 72175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mComponentNameToServiceMap.put(componentName, this); 72275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 72375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 72475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 7258a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(LOG_TAG, "Error while setting Controller for service: " + service, re); 72675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 72775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 72875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 72975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void onServiceDisconnected(ComponentName componentName) { 73075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 73175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = mComponentNameToServiceMap.remove(componentName); 73275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mServices.remove(service); 73375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 73475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 73575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 73675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov} 737