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