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
176e6cd7a5660af1a4b5a9ad091c41ef1c72ad2000Jeff Brownpackage com.android.server.accessibility;
1875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovimport static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
218643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.Manifest;
2275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.AccessibilityService;
2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.AccessibilityServiceInfo;
244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovimport android.accessibilityservice.IAccessibilityServiceClient;
2575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.IAccessibilityServiceConnection;
26447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganovimport android.app.AlertDialog;
27dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.app.PendingIntent;
285c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganovimport android.app.StatusBarManager;
2975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.BroadcastReceiver;
3075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ComponentName;
3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ContentResolver;
3275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context;
33447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganovimport android.content.DialogInterface;
34447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganovimport android.content.DialogInterface.OnClickListener;
3575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Intent;
3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.IntentFilter;
3775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ServiceConnection;
3875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.PackageManager;
3975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.ResolveInfo;
4053e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganovimport android.content.pm.ServiceInfo;
410425d7f56b5c14484777357075b285d59996e6e9Svetoslavimport android.content.pm.UserInfo;
4275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.database.ContentObserver;
43a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganovimport android.graphics.Point;
447961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganovimport android.graphics.Rect;
459ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslavimport android.graphics.Region;
46a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganovimport android.hardware.display.DisplayManager;
47005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.hardware.input.InputManager;
4875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.net.Uri;
4975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Binder;
504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovimport android.os.Build;
51aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganovimport android.os.Bundle;
5275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Handler;
5375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.IBinder;
541cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganovimport android.os.Looper;
5575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Message;
5658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.Process;
5758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.RemoteCallbackList;
5875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.RemoteException;
590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.ServiceManager;
60005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.os.SystemClock;
6158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.UserHandle;
627befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.os.UserManager;
6375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.provider.Settings;
6475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.text.TextUtils;
6575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.text.TextUtils.SimpleStringSplitter;
66c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslavimport android.util.Pools.Pool;
67c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslavimport android.util.Pools.SimplePool;
688a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
6975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.SparseArray;
70a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganovimport android.view.Display;
718643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.IWindow;
72005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.view.InputDevice;
73c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslavimport android.view.InputEventConsistencyVerifier;
74005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.view.KeyCharacterMap;
75005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.view.KeyEvent;
76152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganovimport android.view.MagnificationSpec;
778e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslavimport android.view.WindowInfo;
78447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganovimport android.view.WindowManager;
798e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslavimport android.view.WindowManagerInternal;
80c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslavimport android.view.WindowManagerPolicy;
8175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent;
82e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport android.view.accessibility.AccessibilityInteractionClient;
8300aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganovimport android.view.accessibility.AccessibilityManager;
848643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
858e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslavimport android.view.accessibility.AccessibilityWindowInfo;
868643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.IAccessibilityInteractionConnection;
878643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.IAccessibilityInteractionConnectionCallback;
8875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.IAccessibilityManager;
8975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.IAccessibilityManagerClient;
9075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
91e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport com.android.internal.R;
928643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport com.android.internal.content.PackageMonitor;
93c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganovimport com.android.internal.statusbar.IStatusBarService;
9416e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslavimport com.android.internal.widget.LockPatternUtils;
958e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslavimport com.android.server.LocalServices;
968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
978643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport org.xmlpull.v1.XmlPullParserException;
988643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
996ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganovimport java.io.FileDescriptor;
100cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganovimport java.io.IOException;
1016ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganovimport java.io.PrintWriter;
10275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.ArrayList;
10375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Arrays;
104319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganovimport java.util.Collections;
10575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.HashMap;
10675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.HashSet;
10721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport java.util.Iterator;
10875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.List;
10975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Map;
11075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Set;
11158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport java.util.concurrent.CopyOnWriteArrayList;
11275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
11375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/**
11475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * This class is instantiated by the system as a system level service and can be
11575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * accessed only by the system. The task of this service is to be a centralized
11675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * event dispatch for {@link AccessibilityEvent}s generated across all processes
11775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * on the device. Events are dispatched to {@link AccessibilityService}s.
11875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */
119e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovpublic class AccessibilityManagerService extends IAccessibilityManager.Stub {
12075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
121736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    private static final boolean DEBUG = false;
122736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
12375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private static final String LOG_TAG = "AccessibilityManagerService";
12475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1257befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    // TODO: This is arbitrary. When there is time implement this by watching
1267befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    //       when that accessibility services are bound.
12759f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov    private static final int WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS = 3000;
1287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
12904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav    private static final int WAIT_WINDOWS_TIMEOUT_MILLIS = 5000;
13004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
1310d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov    private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
1320d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov        "registerUiTestAutomationService";
1338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1347befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private static final String TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED =
1357befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            "temporaryEnableAccessibilityStateUntilKeyguardRemoved";
1367befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
1371376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    private static final String GET_WINDOW_TOKEN = "getWindowToken";
1381376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
13957bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private static final ComponentName sFakeAccessibilityServiceComponentName =
14057bf88508e0491caced22c4c592d33aba6d88129Svetoslav            new ComponentName("foo.bar", "FakeService");
14157bf88508e0491caced22c4c592d33aba6d88129Svetoslav
1426ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov    private static final String FUNCTION_DUMP = "dump";
1436ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov
1449a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov    private static final char COMPONENT_NAME_SEPARATOR = ':';
1459a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov
14675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private static final int OWN_PROCESS_ID = android.os.Process.myPid();
14775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
148c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    private static final int MAX_POOL_SIZE = 10;
149c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
150d5b0842a1ddbfc2ea5335854fe2834b6e9b965deSvet Ganov    private static final int WINDOW_ID_UNKNOWN = -1;
151d5b0842a1ddbfc2ea5335854fe2834b6e9b965deSvet Ganov
152fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov    private static int sIdCounter = 0;
153fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov
1548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    private static int sNextWindowId;
1558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
15658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final Context mContext;
15775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
15858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final Object mLock = new Object();
15975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
160c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    private final Pool<PendingEvent> mPendingEventPool =
161a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new SimplePool<>(MAX_POOL_SIZE);
162c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
16358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final SimpleStringSplitter mStringColonSplitter =
16458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
16575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
16658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final List<AccessibilityServiceInfo> mEnabledServicesForFeedbackTempList =
167a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new ArrayList<>();
16875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1699ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav    private final Region mTempRegion = new Region();
1709ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav
171a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov    private final Rect mTempRect = new Rect();
172a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov
173ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav    private final Rect mTempRect1 = new Rect();
174ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav
175a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov    private final Point mTempPoint = new Point();
176a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov
17758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final PackageManager mPackageManager;
17875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1798e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    private final WindowManagerInternal mWindowManagerService;
1809a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov
18158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final SecurityPolicy mSecurityPolicy;
1828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
18358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final MainHandler mMainHandler;
18475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1851e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private InteractionBridge mInteractionBridge;
18675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
187447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov    private AlertDialog mEnableTouchExplorationDialog;
188447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
1890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private AccessibilityInputFilter mInputFilter;
19075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
19100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov    private boolean mHasInputFilter;
19200aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov
193a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav    private final Set<ComponentName> mTempComponentNameSet = new HashSet<>();
19457bf88508e0491caced22c4c592d33aba6d88129Svetoslav
19557bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList =
196a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new ArrayList<>();
19757bf88508e0491caced22c4c592d33aba6d88129Svetoslav
19858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients =
199a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new RemoteCallbackList<>();
200f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov
20158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final SparseArray<AccessibilityConnectionWrapper> mGlobalInteractionConnections =
202a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new SparseArray<>();
2031cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
204a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav    private final SparseArray<IBinder> mGlobalWindowTokens = new SparseArray<>();
2058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
206a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav    private final SparseArray<UserState> mUserStates = new SparseArray<>();
207e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2080425d7f56b5c14484777357075b285d59996e6e9Svetoslav    private final UserManager mUserManager;
2090425d7f56b5c14484777357075b285d59996e6e9Svetoslav
21016e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav    private final LockPatternUtils mLockPatternUtils;
21116e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav
212a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov    private int mCurrentUserId = UserHandle.USER_OWNER;
2139b666d0faadd26827ca5b7cf6af3aa94af6adcd9Svetoslav Ganov
2143b817aed7dba4405c764784baaf7308196d16481Svetoslav    //TODO: Remove this hack
2153b817aed7dba4405c764784baaf7308196d16481Svetoslav    private boolean mInitialized;
2163b817aed7dba4405c764784baaf7308196d16481Svetoslav
2178e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    private WindowsForAccessibilityCallback mWindowsForAccessibilityCallback;
2188e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
21958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private UserState getCurrentUserStateLocked() {
22058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        return getUserStateLocked(mCurrentUserId);
22158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
22275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
22375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
22475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Creates a new instance.
22575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
22675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param context A {@link Context} instance.
22775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
2286e6cd7a5660af1a4b5a9ad091c41ef1c72ad2000Jeff Brown    public AccessibilityManagerService(Context context) {
22975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        mContext = context;
23075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        mPackageManager = mContext.getPackageManager();
2318e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
2320425d7f56b5c14484777357075b285d59996e6e9Svetoslav        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
2338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        mSecurityPolicy = new SecurityPolicy();
2341cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mMainHandler = new MainHandler(mContext.getMainLooper());
23516e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav        mLockPatternUtils = new LockPatternUtils(context);
23658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        registerBroadcastReceivers();
23758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        new AccessibilityContentObserver(mMainHandler).register(
23858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                context.getContentResolver());
23975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
24075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
2410425d7f56b5c14484777357075b285d59996e6e9Svetoslav    private UserState getUserStateLocked(int userId) {
2420425d7f56b5c14484777357075b285d59996e6e9Svetoslav        UserState state = mUserStates.get(userId);
2430425d7f56b5c14484777357075b285d59996e6e9Svetoslav        if (state == null) {
2440425d7f56b5c14484777357075b285d59996e6e9Svetoslav            state = new UserState(userId);
2450425d7f56b5c14484777357075b285d59996e6e9Svetoslav            mUserStates.put(userId, state);
2460425d7f56b5c14484777357075b285d59996e6e9Svetoslav        }
2470425d7f56b5c14484777357075b285d59996e6e9Svetoslav        return state;
2480425d7f56b5c14484777357075b285d59996e6e9Svetoslav    }
2490425d7f56b5c14484777357075b285d59996e6e9Svetoslav
25058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private void registerBroadcastReceivers() {
25121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        PackageMonitor monitor = new PackageMonitor() {
25275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            @Override
25321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            public void onSomePackagesChanged() {
25475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                synchronized (mLock) {
2550425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    // Only the profile parent can install accessibility services.
2560425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    // Therefore we ignore packages from linked profiles.
25758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    if (getChangingUserId() != mCurrentUserId) {
25858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        return;
25958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
2604074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov                    // We will update when the automation service dies.
26157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    UserState userState = getCurrentUserStateLocked();
2620ecfa017decd230051d5e42d9f49129afd58838bSvetoslav Ganov                    // We have to reload the installed services since some services may
2630ecfa017decd230051d5e42d9f49129afd58838bSvetoslav Ganov                    // have different attributes, resolve info (does not support equals),
2640ecfa017decd230051d5e42d9f49129afd58838bSvetoslav Ganov                    // etc. Remove them then to force reload. Do it even if automation is
2650ecfa017decd230051d5e42d9f49129afd58838bSvetoslav Ganov                    // running since when it goes away, we will have to reload as well.
2660ecfa017decd230051d5e42d9f49129afd58838bSvetoslav Ganov                    userState.mInstalledServices.clear();
26757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    if (userState.mUiAutomationService == null) {
26857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        if (readConfigurationForUserStateLocked(userState)) {
26957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                            onUserStateChangedLocked(userState);
27057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        }
2714074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov                    }
27221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
27321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
27400aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov
27521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            @Override
276d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov            public void onPackageRemoved(String packageName, int uid) {
277d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                synchronized (mLock) {
27858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    final int userId = getChangingUserId();
2790425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    // Only the profile parent can install accessibility services.
2800425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    // Therefore we ignore packages from linked profiles.
28158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    if (userId != mCurrentUserId) {
28258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        return;
28358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
28457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    UserState userState = getUserStateLocked(userId);
28557bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    Iterator<ComponentName> it = userState.mEnabledServices.iterator();
286d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                    while (it.hasNext()) {
287d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                        ComponentName comp = it.next();
288d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                        String compPkg = comp.getPackageName();
289d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                        if (compPkg.equals(packageName)) {
290d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                            it.remove();
2919a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                            // Update the enabled services setting.
2929a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                            persistComponentNamesToSettingLocked(
2939a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
29457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                    userState.mEnabledServices, userId);
295447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                            // Update the touch exploration granted services setting.
29657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                            userState.mTouchExplorationGrantedServices.remove(comp);
297447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                            persistComponentNamesToSettingLocked(
298447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                                    Settings.Secure.
299447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                                    TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
30057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                    userState.mTouchExplorationGrantedServices, userId);
30157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                            // We will update when the automation service dies.
30257bf88508e0491caced22c4c592d33aba6d88129Svetoslav                            if (userState.mUiAutomationService == null) {
30357bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                onUserStateChangedLocked(userState);
30457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                            }
305d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                            return;
306d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                        }
307d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                    }
308d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov                }
309d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov            }
310d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov
311d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov            @Override
31221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            public boolean onHandleForceStop(Intent intent, String[] packages,
31321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    int uid, boolean doit) {
31421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                synchronized (mLock) {
31558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    final int userId = getChangingUserId();
3160425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    // Only the profile parent can install accessibility services.
3170425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    // Therefore we ignore packages from linked profiles.
31858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    if (userId != mCurrentUserId) {
31958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        return false;
32058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
32157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    UserState userState = getUserStateLocked(userId);
32257bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    Iterator<ComponentName> it = userState.mEnabledServices.iterator();
32321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    while (it.hasNext()) {
32421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        ComponentName comp = it.next();
32521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        String compPkg = comp.getPackageName();
32621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        for (String pkg : packages) {
32721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            if (compPkg.equals(pkg)) {
32821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                if (!doit) {
32921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    return true;
33021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                }
33121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                it.remove();
3329a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                                persistComponentNamesToSettingLocked(
3339a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
33457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                        userState.mEnabledServices, userId);
33557bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                // We will update when the automation service dies.
33657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                if (userState.mUiAutomationService == null) {
33757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                    onUserStateChangedLocked(userState);
33857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                                }
33921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            }
34021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        }
34121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    }
34221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    return false;
34321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
34421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
34575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        };
34675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
34775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        // package changes
34858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        monitor.register(mContext, null,  UserHandle.ALL, true);
34975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
3507befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        // user change and unlock
3517befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        IntentFilter intentFilter = new IntentFilter();
3527befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
3537befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        intentFilter.addAction(Intent.ACTION_USER_REMOVED);
3547befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
35575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
3567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        mContext.registerReceiverAsUser(new BroadcastReceiver() {
35758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            @Override
35858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            public void onReceive(Context context, Intent intent) {
35958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                String action = intent.getAction();
36058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
36158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
36258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
36358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
3647befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
36557bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    // We will update when the automation service dies.
36657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    UserState userState = getCurrentUserStateLocked();
36757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    if (userState.mUiAutomationService == null) {
36857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        if (readConfigurationForUserStateLocked(userState)) {
36957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                            onUserStateChangedLocked(userState);
37057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        }
37157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    }
37275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                }
37358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
3747befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }, UserHandle.ALL, intentFilter, null, null);
37575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
37675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
3771376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
37858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public int addClient(IAccessibilityManagerClient client, int userId) {
37975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        synchronized (mLock) {
3800425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
3810425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
3820425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
38358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedUserId = mSecurityPolicy
38458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
38558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // If the client is from a process that runs across users such as
38658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // the system UI or the system we add it to the global state that
38758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // is shared across users.
38858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            UserState userState = getUserStateLocked(resolvedUserId);
38958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
39058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mGlobalClients.register(client);
391a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                if (DEBUG) {
392a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid());
393a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                }
39457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                return userState.getClientState();
39558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } else {
39658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                userState.mClients.register(client);
39758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                // If this client is not for the current user we do not
39858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                // return a state since it is not for the foreground user.
39958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                // We will send the state to the client on a user switch.
400a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                if (DEBUG) {
401a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid()
402a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                            + " and userId:" + mCurrentUserId);
403a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                }
40457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                return (resolvedUserId == mCurrentUserId) ? userState.getClientState() : 0;
40558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
40675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
40775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
40875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
4091376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
41058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public boolean sendAccessibilityEvent(AccessibilityEvent event, int userId) {
41175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        synchronized (mLock) {
4120425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
4130425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
4140425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution..
41558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedUserId = mSecurityPolicy
41658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
41758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // This method does nothing for a background user.
41858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (resolvedUserId != mCurrentUserId) {
41958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                return true; // yes, recycle the event
42058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
4218e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (mSecurityPolicy.canDispatchAccessibilityEventLocked(event)) {
4221e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                mSecurityPolicy.updateActiveAndAccessibilityFocusedWindowLocked(event.getWindowId(),
4231e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        event.getSourceNodeId(), event.getEventType());
424a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                mSecurityPolicy.updateEventSourceLocked(event);
425eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                notifyAccessibilityServicesDelayedLocked(event, false);
426eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                notifyAccessibilityServicesDelayedLocked(event, true);
427eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov            }
42886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov            if (mHasInputFilter && mInputFilter != null) {
42958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mMainHandler.obtainMessage(MainHandler.MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER,
430e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov                        AccessibilityEvent.obtain(event)).sendToTarget();
43186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov            }
432cd94caf2bb94f07522ea5bbf0e37dea960b38220Svetoslav Ganov            event.recycle();
43358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            getUserStateLocked(resolvedUserId).mHandledFeedbackTypes = 0;
43475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
43575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        return (OWN_PROCESS_ID != Binder.getCallingPid());
43675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
43775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
4381376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
43958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) {
44075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        synchronized (mLock) {
4410425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
4420425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
4430425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
44458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedUserId = mSecurityPolicy
44558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
446319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            // The automation service is a fake one and should not be reported
447319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            // to clients as being installed - it really is not.
448319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            UserState userState = getUserStateLocked(resolvedUserId);
449319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            if (userState.mUiAutomationService != null) {
450a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                List<AccessibilityServiceInfo> installedServices = new ArrayList<>();
451319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov                installedServices.addAll(userState.mInstalledServices);
452a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                installedServices.remove(userState.mUiAutomationService.mAccessibilityServiceInfo);
453319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov                return installedServices;
454319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            }
455319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            return userState.mInstalledServices;
45675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
45775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
45875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
4591376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
46058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType,
46158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            int userId) {
46258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        List<AccessibilityServiceInfo> result = null;
463736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        synchronized (mLock) {
4640425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
4650425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
4660425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
46758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedUserId = mSecurityPolicy
46858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
469319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov
470319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            // The automation service is a fake one and should not be reported
471319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            // to clients as being enabled. The automation service is always the
472319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            // only active one, if it exists.
473319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            UserState userState = getUserStateLocked(resolvedUserId);
474319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            if (userState.mUiAutomationService != null) {
475319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov                return Collections.emptyList();
476319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            }
477319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov
47858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            result = mEnabledServicesForFeedbackTempList;
47958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            result.clear();
480319d55bd15721982db7563711c876bb000490b7dSvetoslav Ganov            List<Service> services = userState.mBoundServices;
481cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            while (feedbackType != 0) {
482cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackType));
483cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                feedbackType &= ~feedbackTypeBit;
484f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov                final int serviceCount = services.size();
485f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov                for (int i = 0; i < serviceCount; i++) {
486f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov                    Service service = services.get(i);
487c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov                    if ((service.mFeedbackType & feedbackTypeBit) != 0) {
488f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov                        result.add(service.mAccessibilityServiceInfo);
489f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov                    }
490cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                }
491736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            }
492736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        }
493f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov        return result;
494736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
495736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
4961376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
49758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public void interrupt(int userId) {
49858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        CopyOnWriteArrayList<Service> services;
49975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        synchronized (mLock) {
5000425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
5010425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
5020425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
50358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedUserId = mSecurityPolicy
50458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
50558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // This method does nothing for a background user.
50658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (resolvedUserId != mCurrentUserId) {
50758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                return;
50858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
50957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            services = getUserStateLocked(resolvedUserId).mBoundServices;
51058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
51158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        for (int i = 0, count = services.size(); i < count; i++) {
51258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            Service service = services.get(i);
51358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            try {
51458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                service.mServiceInterface.onInterrupt();
51558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } catch (RemoteException re) {
51658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Slog.e(LOG_TAG, "Error during sending interrupt request to "
51758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    + service.mService, re);
51875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
51975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
52075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
52175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
5221376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
5238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    public int addAccessibilityInteractionConnection(IWindow windowToken,
52458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            IAccessibilityInteractionConnection connection, int userId) throws RemoteException {
5258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        synchronized (mLock) {
5260425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
5270425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
5280425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
52958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedUserId = mSecurityPolicy
53058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    .resolveCallingUserIdEnforcingPermissionsLocked(userId);
5318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            final int windowId = sNextWindowId++;
53258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // If the window is from a process that runs across users such as
53358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // the system UI or the system we add it to the global state that
53458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // is shared across users.
53558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
53658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
53758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        windowId, connection, UserHandle.USER_ALL);
53858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                wrapper.linkToDeath();
53958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mGlobalInteractionConnections.put(windowId, wrapper);
54058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mGlobalWindowTokens.put(windowId, windowToken.asBinder());
541a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                if (DEBUG) {
542a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    Slog.i(LOG_TAG, "Added global connection for pid:" + Binder.getCallingPid()
543cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav                            + " with windowId: " + windowId + " and  token: " + windowToken.asBinder());
544a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                }
54558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } else {
54658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
54758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        windowId, connection, resolvedUserId);
54858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                wrapper.linkToDeath();
54958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                UserState userState = getUserStateLocked(resolvedUserId);
55058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                userState.mInteractionConnections.put(windowId, wrapper);
55158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                userState.mWindowTokens.put(windowId, windowToken.asBinder());
552a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                if (DEBUG) {
553a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    Slog.i(LOG_TAG, "Added user connection for pid:" + Binder.getCallingPid()
554cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav                            + " with windowId: " + windowId + " and userId:" + mCurrentUserId
555cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav                            + " and  token: " + windowToken.asBinder());
556a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                }
55758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
5588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            return windowId;
5598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
5608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
5618643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
5621376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
56358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    public void removeAccessibilityInteractionConnection(IWindow window) {
5648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        synchronized (mLock) {
5650425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
5660425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
5670425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
56858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
56958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    UserHandle.getCallingUserId());
57058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            IBinder token = window.asBinder();
571a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov            final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
57258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    token, mGlobalWindowTokens, mGlobalInteractionConnections);
573a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov            if (removedWindowId >= 0) {
574a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                if (DEBUG) {
575a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
576cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav                            + " with windowId: " + removedWindowId + " and token: " + window.asBinder());
577a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                }
57858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                return;
57958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
58058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int userCount = mUserStates.size();
58158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            for (int i = 0; i < userCount; i++) {
58258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                UserState userState = mUserStates.valueAt(i);
583a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                final int removedWindowIdForUser =
58458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        removeAccessibilityInteractionConnectionInternalLocked(
58558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        token, userState.mWindowTokens, userState.mInteractionConnections);
586a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                if (removedWindowIdForUser >= 0) {
587a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    if (DEBUG) {
588a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                        Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
589a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                                + " with windowId: " + removedWindowIdForUser + " and userId:"
590cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav                                + mUserStates.keyAt(i) + " and token: " + window.asBinder());
591a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                    }
5928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                    return;
5938643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
5948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
5958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
5968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
5978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
598a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov    private int removeAccessibilityInteractionConnectionInternalLocked(IBinder windowToken,
59958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            SparseArray<IBinder> windowTokens,
60058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            SparseArray<AccessibilityConnectionWrapper> interactionConnections) {
60158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        final int count = windowTokens.size();
60258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        for (int i = 0; i < count; i++) {
60358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (windowTokens.valueAt(i) == windowToken) {
60458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int windowId = windowTokens.keyAt(i);
60558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                windowTokens.removeAt(i);
60658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId);
60758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                wrapper.unlinkToDeath();
60858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                interactionConnections.remove(windowId);
609a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                return windowId;
61058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
61158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
612a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov        return -1;
61358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
61458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
6151376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
616db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav    public void registerUiTestAutomationService(IBinder owner,
617db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav            IAccessibilityServiceClient serviceClient,
61879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            AccessibilityServiceInfo accessibilityServiceInfo) {
6198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
6200d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov                FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE);
62157bf88508e0491caced22c4c592d33aba6d88129Svetoslav
62257bf88508e0491caced22c4c592d33aba6d88129Svetoslav        accessibilityServiceInfo.setComponentName(sFakeAccessibilityServiceComponentName);
62357bf88508e0491caced22c4c592d33aba6d88129Svetoslav
6248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        synchronized (mLock) {
62557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            UserState userState = getCurrentUserStateLocked();
62657bf88508e0491caced22c4c592d33aba6d88129Svetoslav
62757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (userState.mUiAutomationService != null) {
62880943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                throw new IllegalStateException("UiAutomationService " + serviceClient
62980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                        + "already registered!");
63080943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov            }
631b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov
6323c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            try {
6333c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                owner.linkToDeath(userState.mUiAutomationSerivceOnwerDeathRecipient, 0);
6343c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            } catch (RemoteException re) {
6353c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                Slog.e(LOG_TAG, "Couldn't register for the death of a"
6363c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                        + " UiTestAutomationService!", re);
6373c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                return;
6383c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            }
6393c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav
6403c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            userState.mUiAutomationServiceOwner = owner;
64157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mUiAutomationServiceClient = serviceClient;
642657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov
64357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            // Set the temporary state.
64457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mIsAccessibilityEnabled = true;
64557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mIsTouchExplorationEnabled = false;
6463822896e226567c6cd3ef84518d318abd33a7624Svetoslav            userState.mIsEnhancedWebAccessibilityEnabled = false;
64757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mIsDisplayMagnificationEnabled = false;
64857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mInstalledServices.add(accessibilityServiceInfo);
64957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mEnabledServices.clear();
65057bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mEnabledServices.add(sFakeAccessibilityServiceComponentName);
65157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mTouchExplorationGrantedServices.add(sFakeAccessibilityServiceComponentName);
6523822896e226567c6cd3ef84518d318abd33a7624Svetoslav
65357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            // Use the new state instead of settings.
65457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            onUserStateChangedLocked(userState);
65557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        }
65657bf88508e0491caced22c4c592d33aba6d88129Svetoslav    }
657657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov
6581376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
65957bf88508e0491caced22c4c592d33aba6d88129Svetoslav    public void unregisterUiTestAutomationService(IAccessibilityServiceClient serviceClient) {
66057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        synchronized (mLock) {
66157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            UserState userState = getCurrentUserStateLocked();
66257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            // Automation service is not bound, so pretend it died to perform clean up.
66357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (userState.mUiAutomationService != null
66457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    && serviceClient != null
6650726843ea088e7c6754fe6ac410749a852316aacSvetoslav                    && userState.mUiAutomationService.mServiceInterface != null
66657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    && userState.mUiAutomationService.mServiceInterface.asBinder()
66757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    == serviceClient.asBinder()) {
66857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                userState.mUiAutomationService.binderDied();
66957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            } else {
67057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                throw new IllegalStateException("UiAutomationService " + serviceClient
67157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        + " not registered!");
67257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
6738643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
674d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    }
675d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
6761376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
6777befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    public void temporaryEnableAccessibilityStateUntilKeyguardRemoved(
6787befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            ComponentName service, boolean touchExplorationEnabled) {
6797befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        mSecurityPolicy.enforceCallingPermission(
6807befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                Manifest.permission.TEMPORARY_ENABLE_ACCESSIBILITY,
6817befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED);
6828e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        if (!mWindowManagerService.isKeyguardLocked()) {
6837befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return;
6847befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
6857befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        synchronized (mLock) {
6867befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // Set the temporary state.
68757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            UserState userState = getCurrentUserStateLocked();
68857bf88508e0491caced22c4c592d33aba6d88129Svetoslav
68957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            // This is a nop if UI automation is enabled.
69057bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (userState.mUiAutomationService != null) {
69157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                return;
69257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
69357bf88508e0491caced22c4c592d33aba6d88129Svetoslav
6947befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            userState.mIsAccessibilityEnabled = true;
6953822896e226567c6cd3ef84518d318abd33a7624Svetoslav            userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
6963822896e226567c6cd3ef84518d318abd33a7624Svetoslav            userState.mIsEnhancedWebAccessibilityEnabled = false;
6977befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            userState.mIsDisplayMagnificationEnabled = false;
6987befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            userState.mEnabledServices.clear();
6997befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            userState.mEnabledServices.add(service);
70057bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mBindingServices.clear();
701447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            userState.mTouchExplorationGrantedServices.clear();
702447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            userState.mTouchExplorationGrantedServices.add(service);
7037befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
70457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            // User the current state instead settings.
70557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            onUserStateChangedLocked(userState);
70679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        }
70779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov    }
70879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
7091376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    @Override
7101376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    public IBinder getWindowToken(int windowId) {
7111376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        mSecurityPolicy.enforceCallingPermission(
7121376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                Manifest.permission.RETRIEVE_WINDOW_TOKEN,
7131376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                GET_WINDOW_TOKEN);
7141376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        synchronized (mLock) {
7150425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // We treat calls from a profile as if made by its parent as profiles
7160425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // share the accessibility state of the parent. The call below
7170425d7f56b5c14484777357075b285d59996e6e9Svetoslav            // performs the current profile parent resolution.
7181376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            final int resolvedUserId = mSecurityPolicy
7191376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                    .resolveCallingUserIdEnforcingPermissionsLocked(
7201376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                            UserHandle.getCallingUserId());
7211376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            if (resolvedUserId != mCurrentUserId) {
7221376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                return null;
7231376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            }
7241376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            if (mSecurityPolicy.findWindowById(windowId) == null) {
7251376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                return null;
7261376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            }
7271376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            IBinder token = mGlobalWindowTokens.get(windowId);
7281376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            if (token != null) {
7291376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav                return token;
7301376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            }
7311376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav            return getCurrentUserStateLocked().mWindowTokens.get(windowId);
7321376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav        }
7331376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    }
7341376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav
735e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    boolean onGesture(int gestureId) {
7364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        synchronized (mLock) {
737fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov            boolean handled = notifyGestureLocked(gestureId, false);
738fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov            if (!handled) {
739fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov                handled = notifyGestureLocked(gestureId, true);
7404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
741fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov            return handled;
742fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        }
743fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov    }
744fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov
745c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    boolean notifyKeyEvent(KeyEvent event, int policyFlags) {
746c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        synchronized (mLock) {
747c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            KeyEvent localClone = KeyEvent.obtain(event);
748c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            boolean handled = notifyKeyEventLocked(localClone, policyFlags, false);
749c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            if (!handled) {
750c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                handled = notifyKeyEventLocked(localClone, policyFlags, true);
751c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
752c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            return handled;
753c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
754c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    }
755c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
756e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    /**
7577498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov     * Gets a point within the accessibility focused node where we can send down
7587498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov     * and up events to perform a click.
759e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov     *
7607498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov     * @param outPoint The click point to populate.
7617498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov     * @return Whether accessibility a click point was found and set.
762e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov     */
7631376d600d8e0eefdbc0aa11d398cf7517fc77129Svetoslav    // TODO: (multi-display) Make sure this works for multiple displays.
7647498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov    boolean getAccessibilityFocusClickPointInScreen(Point outPoint) {
7657498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov        return getInteractionBridgeLocked()
7667498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                .getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
767e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    }
768e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
76976716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov    /**
77010a053e474e2a566b49a1e4c9e2ec4c8cc0013bdSvetoslav     * Gets the bounds of a window.
77176716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov     *
77276716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov     * @param outBounds The output to which to write the bounds.
77376716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov     */
77410a053e474e2a566b49a1e4c9e2ec4c8cc0013bdSvetoslav    boolean getWindowBounds(int windowId, Rect outBounds) {
77576716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        IBinder token;
77676716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        synchronized (mLock) {
77776716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov            token = mGlobalWindowTokens.get(windowId);
77876716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov            if (token == null) {
77976716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov                token = getCurrentUserStateLocked().mWindowTokens.get(windowId);
78076716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov            }
78176716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        }
78276716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        mWindowManagerService.getWindowFrame(token, outBounds);
78376716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        if (!outBounds.isEmpty()) {
78476716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov            return true;
78576716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        }
78676716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov        return false;
78776716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov    }
78876716c5a180aa471c6973ca7aa03c7f2da677823Svetoslav Ganov
78947b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav    boolean accessibilityFocusOnlyInActiveWindow() {
79047b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav        synchronized (mLock) {
79147b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav            return mWindowsForAccessibilityCallback == null;
79247b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav        }
79347b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav    }
79447b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav
79558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    int getActiveWindowId() {
7963f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav        return mSecurityPolicy.getActiveWindowId();
797385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov    }
798385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov
7996ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov    void onTouchInteractionStart() {
8006ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov        mSecurityPolicy.onTouchInteractionStart();
8016ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov    }
8026ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov
803f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov    void onTouchInteractionEnd() {
804f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov        mSecurityPolicy.onTouchInteractionEnd();
805f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov    }
806f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov
807152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    void onMagnificationStateChanged() {
8088e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        notifyClearAccessibilityCacheLocked();
809152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
810152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
81158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private void switchUser(int userId) {
81258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        synchronized (mLock) {
8133b817aed7dba4405c764784baaf7308196d16481Svetoslav            if (mCurrentUserId == userId && mInitialized) {
8143b817aed7dba4405c764784baaf7308196d16481Svetoslav                return;
8153b817aed7dba4405c764784baaf7308196d16481Svetoslav            }
8163b817aed7dba4405c764784baaf7308196d16481Svetoslav
81758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // Disconnect from services for the old user.
8180425d7f56b5c14484777357075b285d59996e6e9Svetoslav            UserState oldUserState = getCurrentUserStateLocked();
8195fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            oldUserState.onSwitchToAnotherUser();
82058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
82158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // Disable the local managers for the old user.
82258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (oldUserState.mClients.getRegisteredCallbackCount() > 0) {
82358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
82458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        oldUserState.mUserId, 0).sendToTarget();
82558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
82658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
82759f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov            // Announce user changes only if more that one exist.
82859f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov            UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
82959f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov            final boolean announceNewUser = userManager.getUsers().size() > 1;
83059f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov
83158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            // The user changed.
83258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mCurrentUserId = userId;
83358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
83457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            UserState userState = getCurrentUserStateLocked();
83557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (userState.mUiAutomationService != null) {
83657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                // Switching users disables the UI automation service.
83757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                userState.mUiAutomationService.binderDied();
83857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
8397befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
8405fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            readConfigurationForUserStateLocked(userState);
8415fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // Even if reading did not yield change, we have to update
8425fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // the state since the context in which the current user
8435fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // state was used has changed since it was inactive.
8445fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            onUserStateChangedLocked(userState);
8455fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
84659f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov            if (announceNewUser) {
84759f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov                // Schedule announcement of the current user if needed.
84859f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov                mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
84959f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov                        WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
85059f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov            }
85158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
85258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
85358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
85458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private void removeUser(int userId) {
85558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        synchronized (mLock) {
85658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mUserStates.remove(userId);
85758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
85858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
85958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
8601e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private InteractionBridge getInteractionBridgeLocked() {
8611e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        if (mInteractionBridge == null) {
8621e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            mInteractionBridge = new InteractionBridge();
863e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
8641e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        return mInteractionBridge;
865e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    }
866e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
8674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    private boolean notifyGestureLocked(int gestureId, boolean isDefault) {
868fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        // TODO: Now we are giving the gestures to the last enabled
869fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        //       service that can handle them which is the last one
870fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        //       in our list since we write the last enabled as the
871fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        //       last record in the enabled services setting. Ideally,
872fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        //       the user should make the call which service handles
873fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        //       gestures. However, only one service should handle
874e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov        //       gestures to avoid user frustration when different
875e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov        //       behavior is observed from different combinations of
876fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov        //       enabled accessibility services.
87758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        UserState state = getCurrentUserStateLocked();
87857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
87957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            Service service = state.mBoundServices.get(i);
880a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov            if (service.mRequestTouchExplorationMode && service.mIsDefault == isDefault) {
881e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                service.notifyGesture(gestureId);
882fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov                return true;
8834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
8844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
8854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        return false;
8864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
8874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
888c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    private boolean notifyKeyEventLocked(KeyEvent event, int policyFlags, boolean isDefault) {
889c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        // TODO: Now we are giving the key events to the last enabled
890688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        //       service that can handle them Ideally, the user should
891688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        //       make the call which service handles key events. However,
892688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        //       only one service should handle key events to avoid user
893688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        //       frustration when different behavior is observed from
894688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        //       different combinations of enabled accessibility services.
895c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        UserState state = getCurrentUserStateLocked();
896c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
897c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            Service service = state.mBoundServices.get(i);
898688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            // Key events are handled only by services that declared
899688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            // this capability and requested to filter key events.
900688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            if (!service.mRequestFilterKeyEvents ||
901688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav                    (service.mAccessibilityServiceInfo.getCapabilities() & AccessibilityServiceInfo
902688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav                            .CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) == 0) {
903688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav                continue;
904688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            }
905c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            if (service.mIsDefault == isDefault) {
906c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                service.notifyKeyEvent(event, policyFlags);
907c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                return true;
908c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
909c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
910c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        return false;
911c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    }
912c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
9138e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    private void notifyClearAccessibilityCacheLocked() {
914152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        UserState state = getCurrentUserStateLocked();
91557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
91657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            Service service = state.mBoundServices.get(i);
917152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            service.notifyClearAccessibilityNodeInfoCache();
918152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
919152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
920152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
921d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    /**
922d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov     * Removes an AccessibilityInteractionConnection.
923d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov     *
924d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov     * @param windowId The id of the window to which the connection is targeted.
92558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param userId The id of the user owning the connection. UserHandle.USER_ALL
92658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     *     if global.
927d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov     */
92858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private void removeAccessibilityInteractionConnectionLocked(int windowId, int userId) {
92958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        if (userId == UserHandle.USER_ALL) {
93058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mGlobalWindowTokens.remove(windowId);
93158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mGlobalInteractionConnections.remove(windowId);
93258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        } else {
93358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            UserState userState = getCurrentUserStateLocked();
93458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            userState.mWindowTokens.remove(windowId);
93558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            userState.mInteractionConnections.remove(windowId);
93658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
937d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        if (DEBUG) {
938d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
939d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        }
9408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
9418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
94257bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readInstalledAccessibilityServiceLocked(UserState userState) {
94357bf88508e0491caced22c4c592d33aba6d88129Svetoslav        mTempAccessibilityServiceInfoList.clear();
94475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
94558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        List<ResolveInfo> installedServices = mPackageManager.queryIntentServicesAsUser(
946cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                new Intent(AccessibilityService.SERVICE_INTERFACE),
94758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
94858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mCurrentUserId);
94975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
95075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        for (int i = 0, count = installedServices.size(); i < count; i++) {
951cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            ResolveInfo resolveInfo = installedServices.get(i);
95253e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
95358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (!android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE.equals(
95458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    serviceInfo.permission)) {
95553e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov                Slog.w(LOG_TAG, "Skipping accessibilty service " + new ComponentName(
95653e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov                        serviceInfo.packageName, serviceInfo.name).flattenToShortString()
95753e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov                        + ": it does not require the permission "
95853e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov                        + android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE);
95953e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov                continue;
96053e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov            }
961cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            AccessibilityServiceInfo accessibilityServiceInfo;
962cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            try {
963cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
96457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo);
965a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            } catch (XmlPullParserException | IOException xppe) {
966cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe);
967cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            }
96875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
96957bf88508e0491caced22c4c592d33aba6d88129Svetoslav
97057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (!mTempAccessibilityServiceInfoList.equals(userState.mInstalledServices)) {
97157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mInstalledServices.clear();
97257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mInstalledServices.addAll(mTempAccessibilityServiceInfoList);
97357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            mTempAccessibilityServiceInfoList.clear();
97457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
97557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        }
97657bf88508e0491caced22c4c592d33aba6d88129Svetoslav
97757bf88508e0491caced22c4c592d33aba6d88129Svetoslav        mTempAccessibilityServiceInfoList.clear();
97857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
97975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
98075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
98157bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readEnabledAccessibilityServicesLocked(UserState userState) {
98257bf88508e0491caced22c4c592d33aba6d88129Svetoslav        mTempComponentNameSet.clear();
98357bf88508e0491caced22c4c592d33aba6d88129Svetoslav        readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
98457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                userState.mUserId, mTempComponentNameSet);
98557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (!mTempComponentNameSet.equals(userState.mEnabledServices)) {
98657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mEnabledServices.clear();
98757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mEnabledServices.addAll(mTempComponentNameSet);
98857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            mTempComponentNameSet.clear();
98957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
99057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        }
99157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        mTempComponentNameSet.clear();
99257bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
9939a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov    }
9949a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov
99557bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readTouchExplorationGrantedAccessibilityServicesLocked(
99657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            UserState userState) {
99757bf88508e0491caced22c4c592d33aba6d88129Svetoslav        mTempComponentNameSet.clear();
99857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        readComponentNamesFromSettingLocked(
999447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
100057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                userState.mUserId, mTempComponentNameSet);
100157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (!mTempComponentNameSet.equals(userState.mTouchExplorationGrantedServices)) {
100257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mTouchExplorationGrantedServices.clear();
100357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mTouchExplorationGrantedServices.addAll(mTempComponentNameSet);
100457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            mTempComponentNameSet.clear();
100557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
100657bf88508e0491caced22c4c592d33aba6d88129Svetoslav        }
100757bf88508e0491caced22c4c592d33aba6d88129Svetoslav        mTempComponentNameSet.clear();
100857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
1009447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov    }
1010447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
101175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
101275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Performs {@link AccessibilityService}s delayed notification. The delay is configurable
101375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * and denotes the period after the last event before notifying the service.
101475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
101575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param event The event.
101675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param isDefault True to notify default listeners, not default services.
101775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
101875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event,
101975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            boolean isDefault) {
102085b598beda98706fafd05c7de9866d83d4a19965Charles Chen        try {
102158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            UserState state = getCurrentUserStateLocked();
102257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            for (int i = 0, count = state.mBoundServices.size(); i < count; i++) {
102357bf88508e0491caced22c4c592d33aba6d88129Svetoslav                Service service = state.mBoundServices.get(i);
102475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
102585b598beda98706fafd05c7de9866d83d4a19965Charles Chen                if (service.mIsDefault == isDefault) {
10268e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    if (canDispatchEventToServiceLocked(service, event,
10278e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            state.mHandledFeedbackTypes)) {
102858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        state.mHandledFeedbackTypes |= service.mFeedbackType;
1029e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                        service.notifyAccessibilityEvent(event);
103085b598beda98706fafd05c7de9866d83d4a19965Charles Chen                    }
103175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                }
103275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
103385b598beda98706fafd05c7de9866d83d4a19965Charles Chen        } catch (IndexOutOfBoundsException oobe) {
103485b598beda98706fafd05c7de9866d83d4a19965Charles Chen            // An out of bounds exception can happen if services are going away
103585b598beda98706fafd05c7de9866d83d4a19965Charles Chen            // as the for loop is running. If that happens, just bail because
103685b598beda98706fafd05c7de9866d83d4a19965Charles Chen            // there are no more services to notify.
103775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
103875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
103975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
104057bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void addServiceLocked(Service service, UserState userState) {
1041f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov        try {
10423a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            service.onAdded();
104357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mBoundServices.add(service);
104458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            userState.mComponentNameToServiceMap.put(service.mComponentName, service);
104557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        } catch (RemoteException re) {
1046f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov            /* do nothing */
104775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
104875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
104975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
105075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
1051f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov     * Removes a service.
105275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
105375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param service The service.
105475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
10556f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav    private void removeServiceLocked(Service service, UserState userState) {
105657bf88508e0491caced22c4c592d33aba6d88129Svetoslav        userState.mBoundServices.remove(service);
105758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        userState.mComponentNameToServiceMap.remove(service.mComponentName);
10583a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav        service.onRemoved();
105975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
106075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
106175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
106275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * Determines if given event can be dispatched to a service based on the package of the
106375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * event source and already notified services for that event type. Specifically, a
106475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * service is notified if it is interested in events from the package and no other service
106575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * providing the same feedback type has been notified. Exception are services the
106675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * provide generic feedback (feedback type left as a safety net for unforeseen feedback
106775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * types) which are always notified.
106875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
106975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param service The potential receiver.
107075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param event The event.
107175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @param handledFeedbackTypes The feedback types for which services have been notified.
107275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * @return True if the listener should be notified, false otherwise.
107375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
10748e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    private boolean canDispatchEventToServiceLocked(Service service, AccessibilityEvent event,
107575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            int handledFeedbackTypes) {
107675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
10773822896e226567c6cd3ef84518d318abd33a7624Svetoslav        if (!service.canReceiveEventsLocked()) {
107875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            return false;
107975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
108075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1081d5b0842a1ddbfc2ea5335854fe2834b6e9b965deSvet Ganov        if (event.getWindowId() != WINDOW_ID_UNKNOWN && !event.isImportantForAccessibility()
108280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                && (service.mFetchFlags
108380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                        & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) == 0) {
10844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            return false;
10854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
10864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
108775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        int eventType = event.getEventType();
108875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        if ((service.mEventTypes & eventType) != eventType) {
108975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            return false;
109075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
109175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
109275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        Set<String> packageNames = service.mPackageNames;
1093a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        String packageName = (event.getPackageName() != null)
1094a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                ? event.getPackageName().toString() : null;
109575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
109675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        if (packageNames.isEmpty() || packageNames.contains(packageName)) {
109775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            int feedbackType = service.mFeedbackType;
109875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            if ((handledFeedbackTypes & feedbackType) != feedbackType
109975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    || feedbackType == AccessibilityServiceInfo.FEEDBACK_GENERIC) {
110075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                return true;
110175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
110275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
110375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
110475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        return false;
110575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
110675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
110758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private void unbindAllServicesLocked(UserState userState) {
110857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        List<Service> services = userState.mBoundServices;
110975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        for (int i = 0, count = services.size(); i < count; i++) {
111075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Service service = services.get(i);
111157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (service.unbindLocked()) {
11126ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov                i--;
11136ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov                count--;
11146ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov            }
111575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
111675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
111775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
111875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
11199a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * Populates a set with the {@link ComponentName}s stored in a colon
112058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * separated value setting for a given user.
112175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     *
11229a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * @param settingName The setting to parse.
112358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov     * @param userId The user id.
11249a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * @param outComponentNames The output component names.
112575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
112657bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void readComponentNamesFromSettingLocked(String settingName, int userId,
11279a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov            Set<ComponentName> outComponentNames) {
112858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
112958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                settingName, userId);
11309a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov        outComponentNames.clear();
11319a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov        if (settingValue != null) {
113275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
11339a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov            splitter.setString(settingValue);
113475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            while (splitter.hasNext()) {
113521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                String str = splitter.next();
113621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (str == null || str.length() <= 0) {
113721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    continue;
113821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
113921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                ComponentName enabledService = ComponentName.unflattenFromString(str);
114021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (enabledService != null) {
11419a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                    outComponentNames.add(enabledService);
114221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
114375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
114475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
114575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
114675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
114775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    /**
11489a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * Persists the component names in the specified setting in a
11499a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * colon separated fashion.
11509a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     *
11519a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * @param settingName The setting name.
11529a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     * @param componentNames The component names.
11539a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov     */
11549a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov    private void persistComponentNamesToSettingLocked(String settingName,
115558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            Set<ComponentName> componentNames, int userId) {
11569a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov        StringBuilder builder = new StringBuilder();
11579a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov        for (ComponentName componentName : componentNames) {
11589a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov            if (builder.length() > 0) {
11599a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov                builder.append(COMPONENT_NAME_SEPARATOR);
11609a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov            }
11619a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov            builder.append(componentName.flattenToShortString());
11629a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov        }
116358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        Settings.Secure.putStringForUser(mContext.getContentResolver(),
116458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                settingName, builder.toString(), userId);
11659a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov    }
11669a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov
116757bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void manageServicesLocked(UserState userState) {
116858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        Map<ComponentName, Service> componentNameToServiceMap =
116958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                userState.mComponentNameToServiceMap;
117058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        boolean isEnabled = userState.mIsAccessibilityEnabled;
117175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
117258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) {
117358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i);
1174cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            ComponentName componentName = ComponentName.unflattenFromString(
1175cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                    installedService.getId());
117675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            Service service = componentNameToServiceMap.get(componentName);
117775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1178f2245aa5d7f5d6f0ea6d55fb2acc66624b2ef13fSvetoslav Ganov            if (isEnabled) {
117957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                // Wait for the binding if it is in process.
118057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                if (userState.mBindingServices.contains(componentName)) {
118157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    continue;
118257bf88508e0491caced22c4c592d33aba6d88129Svetoslav                }
118358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (userState.mEnabledServices.contains(componentName)) {
1184563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov                    if (service == null) {
118557bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        service = new Service(userState.mUserId, componentName, installedService);
118657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    } else if (userState.mBoundServices.contains(service)) {
118757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        continue;
1188563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov                    }
118957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    service.bindLocked();
119035bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov                } else {
1191563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov                    if (service != null) {
119257bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        service.unbindLocked();
1193563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov                    }
119475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                }
119575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } else {
119675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                if (service != null) {
119757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    service.unbindLocked();
119857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                } else {
119957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    userState.mBindingServices.remove(componentName);
120075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                }
120175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
120275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
1203cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav
1204cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav        // No enabled installed services => disable accessibility to avoid
1205cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav        // sending accessibility events with no recipient across processes.
12068aeb0912945ae103223b76d81579073e51579efeSvetoslav        if (isEnabled && userState.mBoundServices.isEmpty()
12078aeb0912945ae103223b76d81579073e51579efeSvetoslav                && userState.mBindingServices.isEmpty()) {
1208cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav            userState.mIsAccessibilityEnabled = false;
1209cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav            Settings.Secure.putIntForUser(mContext.getContentResolver(),
1210cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav                    Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
1211cefac5acc845bc0fd36cb2c7e9e0992ecda33230Svetoslav        }
121237fedf8b78dea969b97188fd3079fea5e71704beSvetoslav Ganov    }
121337fedf8b78dea969b97188fd3079fea5e71704beSvetoslav Ganov
121457bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void scheduleUpdateClientsIfNeededLocked(UserState userState) {
121557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        final int clientState = userState.getClientState();
121657bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (userState.mLastSentClientState != clientState
121757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                && (mGlobalClients.getRegisteredCallbackCount() > 0
121857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                        || userState.mClients.getRegisteredCallbackCount() > 0)) {
121957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mLastSentClientState = clientState;
122058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
122158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    clientState, userState.mUserId) .sendToTarget();
122258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
122358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
122458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
1225545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov    private void scheduleUpdateInputFilter(UserState userState) {
1226545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov        mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_INPUT_FILTER, userState).sendToTarget();
1227545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov    }
1228545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov
1229545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov    private void updateInputFilter(UserState userState) {
123058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        boolean setInputFilter = false;
123158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        AccessibilityInputFilter inputFilter = null;
123258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        synchronized (mLock) {
1233ca523d6e95061f99455589512100839118044d43Svetoslav            int flags = 0;
1234ca523d6e95061f99455589512100839118044d43Svetoslav            if (userState.mIsDisplayMagnificationEnabled) {
1235ca523d6e95061f99455589512100839118044d43Svetoslav                flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
1236ca523d6e95061f99455589512100839118044d43Svetoslav            }
1237ca523d6e95061f99455589512100839118044d43Svetoslav            // Touch exploration without accessibility makes no sense.
1238ca523d6e95061f99455589512100839118044d43Svetoslav            if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) {
1239ca523d6e95061f99455589512100839118044d43Svetoslav                flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
1240ca523d6e95061f99455589512100839118044d43Svetoslav            }
1241ca523d6e95061f99455589512100839118044d43Svetoslav            if (userState.mIsFilterKeyEventsEnabled) {
1242ca523d6e95061f99455589512100839118044d43Svetoslav                flags |= AccessibilityInputFilter.FLAG_FEATURE_FILTER_KEY_EVENTS;
1243ca523d6e95061f99455589512100839118044d43Svetoslav            }
1244ca523d6e95061f99455589512100839118044d43Svetoslav            if (flags != 0) {
124558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (!mHasInputFilter) {
124658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    mHasInputFilter = true;
124758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    if (mInputFilter == null) {
124858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        mInputFilter = new AccessibilityInputFilter(mContext,
124958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                                AccessibilityManagerService.this);
125058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
125158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    inputFilter = mInputFilter;
125258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    setInputFilter = true;
125358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
125458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                mInputFilter.setEnabledFeatures(flags);
125558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } else {
125658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (mHasInputFilter) {
125758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    mHasInputFilter = false;
1258ca523d6e95061f99455589512100839118044d43Svetoslav                    mInputFilter.disableFeatures();
125958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    inputFilter = null;
126058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    setInputFilter = true;
126158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
126258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
126358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
126458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        if (setInputFilter) {
12658e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            mWindowManagerService.setInputFilter(inputFilter);
126675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
126775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
126875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1269447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov    private void showEnableTouchExplorationDialog(final Service service) {
1270447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        synchronized (mLock) {
127157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            String label = service.mResolveInfo.loadLabel(
127257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            mContext.getPackageManager()).toString();
127357bf88508e0491caced22c4c592d33aba6d88129Svetoslav
1274447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            final UserState state = getCurrentUserStateLocked();
1275447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            if (state.mIsTouchExplorationEnabled) {
1276447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                return;
1277447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            }
1278447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            if (mEnableTouchExplorationDialog != null
1279447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    && mEnableTouchExplorationDialog.isShowing()) {
1280447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                return;
1281447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            }
1282447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
1283447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                .setIconAttribute(android.R.attr.alertDialogIcon)
1284447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                .setPositiveButton(android.R.string.ok, new OnClickListener() {
1285447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     @Override
1286447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     public void onClick(DialogInterface dialog, int which) {
1287447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         // The user allowed the service to toggle touch exploration.
1288447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         state.mTouchExplorationGrantedServices.add(service.mComponentName);
1289447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         persistComponentNamesToSettingLocked(
1290447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                                 Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
1291447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                                 state.mTouchExplorationGrantedServices, state.mUserId);
1292447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         // Enable touch exploration.
129357bf88508e0491caced22c4c592d33aba6d88129Svetoslav                         UserState userState = getUserStateLocked(service.mUserId);
129457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                         userState.mIsTouchExplorationEnabled = true;
1295447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
1296447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                                 Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
1297447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                                 service.mUserId);
129857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                         onUserStateChangedLocked(userState);
1299447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     }
1300447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                 })
1301447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                 .setNegativeButton(android.R.string.cancel, new OnClickListener() {
1302447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     @Override
1303447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     public void onClick(DialogInterface dialog, int which) {
1304447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         dialog.dismiss();
1305447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     }
1306447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                 })
1307447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                 .setTitle(R.string.enable_explore_by_touch_warning_title)
1308447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                 .setMessage(mContext.getString(
1309447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                         R.string.enable_explore_by_touch_warning_message, label))
1310447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                 .create();
1311447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov             mEnableTouchExplorationDialog.getWindow().setType(
1312447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
1313447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov             mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags
1314447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                     |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
1315447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov             mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
1316447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov             mEnableTouchExplorationDialog.show();
1317447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        }
1318447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov    }
1319447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
132057bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void onUserStateChangedLocked(UserState userState) {
13213b817aed7dba4405c764784baaf7308196d16481Svetoslav        // TODO: Remove this hack
13223b817aed7dba4405c764784baaf7308196d16481Svetoslav        mInitialized = true;
13231e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        updateLegacyCapabilitiesLocked(userState);
132457bf88508e0491caced22c4c592d33aba6d88129Svetoslav        updateServicesLocked(userState);
13251e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        updateWindowsForAccessibilityCallbackLocked(userState);
13261e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        updateAccessibilityFocusBehaviorLocked(userState);
1327ca523d6e95061f99455589512100839118044d43Svetoslav        updateFilterKeyEventsLocked(userState);
132857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        updateTouchExplorationLocked(userState);
132957bf88508e0491caced22c4c592d33aba6d88129Svetoslav        updateEnhancedWebAccessibilityLocked(userState);
1330410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        updateDisplayColorAdjustmentSettingsLocked(userState);
133157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        scheduleUpdateInputFilter(userState);
133257bf88508e0491caced22c4c592d33aba6d88129Svetoslav        scheduleUpdateClientsIfNeededLocked(userState);
133357bf88508e0491caced22c4c592d33aba6d88129Svetoslav    }
133457bf88508e0491caced22c4c592d33aba6d88129Svetoslav
13351e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private void updateAccessibilityFocusBehaviorLocked(UserState userState) {
13361e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // If there is no service that can operate with interactive windows
13371e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // then we keep the old behavior where a window loses accessibility
13381e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // focus if it is no longer active. This still changes the behavior
13391e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // for services that do not operate with interactive windows and run
13401e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // at the same time as the one(s) which does. In practice however,
13411e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // there is only one service that uses accessibility focus and it
13421e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // is typically the one that operates with interactive windows, So,
13431e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // this is fine. Note that to allow a service to work across windows
13441e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        // we have to allow accessibility focus stay in any of them. Sigh...
13451e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        List<Service> boundServices = userState.mBoundServices;
13461e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        final int boundServiceCount = boundServices.size();
13471e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        for (int i = 0; i < boundServiceCount; i++) {
13481e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            Service boundService = boundServices.get(i);
13491e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            if (boundService.canRetrieveInteractiveWindowsLocked()) {
13501e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                userState.mAccessibilityFocusOnlyInActiveWindow = false;
13511e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                return;
13521e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            }
13531e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
13541e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        userState.mAccessibilityFocusOnlyInActiveWindow = true;
13551e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    }
13561e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
13571e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private void updateWindowsForAccessibilityCallbackLocked(UserState userState) {
13588e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        if (userState.mIsAccessibilityEnabled) {
13598e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // We observe windows for accessibility only if there is at least
13608e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // one bound service that can retrieve window content that specified
13618e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // it is interested in accessing such windows. For services that are
13628e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // binding we do an update pass after each bind event, so we run this
13638e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // code and register the callback if needed.
13648e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            boolean boundServiceCanRetrieveInteractiveWindows = false;
13658e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
13668e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            List<Service> boundServices = userState.mBoundServices;
13678e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final int boundServiceCount = boundServices.size();
13688e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            for (int i = 0; i < boundServiceCount; i++) {
13698e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                Service boundService = boundServices.get(i);
13701e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                if (boundService.canRetrieveInteractiveWindowsLocked()) {
13718e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    boundServiceCanRetrieveInteractiveWindows = true;
13728e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    break;
13738e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
13748e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
13758e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
13768e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (boundServiceCanRetrieveInteractiveWindows) {
13778e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (mWindowsForAccessibilityCallback == null) {
13788e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    mWindowsForAccessibilityCallback = new WindowsForAccessibilityCallback();
13798e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    mWindowManagerService.setWindowsForAccessibilityCallback(
13808e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            mWindowsForAccessibilityCallback);
13818e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
13828e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                return;
13838e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
13848e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
13858e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
13868e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        if (mWindowsForAccessibilityCallback != null) {
13878e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            mWindowsForAccessibilityCallback = null;
1388a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            mWindowManagerService.setWindowsForAccessibilityCallback(null);
138904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            // Drop all windows we know about.
139004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            mSecurityPolicy.clearWindowsLocked();
13918e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
13928e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    }
13938e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
13941e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private void updateLegacyCapabilitiesLocked(UserState userState) {
139511adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        // Up to JB-MR1 we had a white list with services that can enable touch
139611adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        // exploration. When a service is first started we show a dialog to the
139711adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        // use to get a permission to white list the service.
139811adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        final int installedServiceCount = userState.mInstalledServices.size();
139911adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        for (int i = 0; i < installedServiceCount; i++) {
140011adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav            AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i);
140111adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav            ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
140211adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav            if ((serviceInfo.getCapabilities()
140311adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                        & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) == 0
140411adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                    && resolveInfo.serviceInfo.applicationInfo.targetSdkVersion
140511adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                        <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
140611adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                ComponentName componentName = new ComponentName(
140711adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                        resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
140811adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                if (userState.mTouchExplorationGrantedServices.contains(componentName)) {
140911adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                    serviceInfo.setCapabilities(serviceInfo.getCapabilities()
141011adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                            | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION);
141111adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                }
141211adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav            }
141311adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav        }
141411adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav    }
141511adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav
1416ca523d6e95061f99455589512100839118044d43Svetoslav    private void updateFilterKeyEventsLocked(UserState userState) {
1417ca523d6e95061f99455589512100839118044d43Svetoslav        final int serviceCount = userState.mBoundServices.size();
1418ca523d6e95061f99455589512100839118044d43Svetoslav        for (int i = 0; i < serviceCount; i++) {
1419ca523d6e95061f99455589512100839118044d43Svetoslav            Service service = userState.mBoundServices.get(i);
1420ca523d6e95061f99455589512100839118044d43Svetoslav            if (service.mRequestFilterKeyEvents
1421ca523d6e95061f99455589512100839118044d43Svetoslav                    && (service.mAccessibilityServiceInfo.getCapabilities()
1422ca523d6e95061f99455589512100839118044d43Svetoslav                            & AccessibilityServiceInfo
1423ca523d6e95061f99455589512100839118044d43Svetoslav                            .CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) != 0) {
1424ca523d6e95061f99455589512100839118044d43Svetoslav                userState.mIsFilterKeyEventsEnabled = true;
1425ca523d6e95061f99455589512100839118044d43Svetoslav                return;
1426ca523d6e95061f99455589512100839118044d43Svetoslav            }
1427ca523d6e95061f99455589512100839118044d43Svetoslav        }
1428ca523d6e95061f99455589512100839118044d43Svetoslav        userState.mIsFilterKeyEventsEnabled = false;
1429ca523d6e95061f99455589512100839118044d43Svetoslav    }
1430ca523d6e95061f99455589512100839118044d43Svetoslav
143157bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void updateServicesLocked(UserState userState) {
143258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        if (userState.mIsAccessibilityEnabled) {
143357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            manageServicesLocked(userState);
143457bf88508e0491caced22c4c592d33aba6d88129Svetoslav        } else {
143557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            unbindAllServicesLocked(userState);
143658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
14371cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
14381cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
143957bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readConfigurationForUserStateLocked(UserState userState) {
1440a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        boolean somthingChanged = readAccessibilityEnabledSettingLocked(userState);
144157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        somthingChanged |= readInstalledAccessibilityServiceLocked(userState);
144257bf88508e0491caced22c4c592d33aba6d88129Svetoslav        somthingChanged |= readEnabledAccessibilityServicesLocked(userState);
144357bf88508e0491caced22c4c592d33aba6d88129Svetoslav        somthingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
144457bf88508e0491caced22c4c592d33aba6d88129Svetoslav        somthingChanged |= readTouchExplorationEnabledSettingLocked(userState);
1445cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        somthingChanged |= readHighTextContrastEnabledSettingLocked(userState);
144657bf88508e0491caced22c4c592d33aba6d88129Svetoslav        somthingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
144757bf88508e0491caced22c4c592d33aba6d88129Svetoslav        somthingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
1448410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        somthingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
144957bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return somthingChanged;
14500029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
14510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
145257bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readAccessibilityEnabledSettingLocked(UserState userState) {
145357bf88508e0491caced22c4c592d33aba6d88129Svetoslav        final boolean accessibilityEnabled = Settings.Secure.getIntForUser(
145458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov               mContext.getContentResolver(),
145558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov               Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId) == 1;
145657bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (accessibilityEnabled != userState.mIsAccessibilityEnabled) {
145757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mIsAccessibilityEnabled = accessibilityEnabled;
145857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
1459b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov        }
146057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
14610d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov    }
14620d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov
146357bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readTouchExplorationEnabledSettingLocked(UserState userState) {
146457bf88508e0491caced22c4c592d33aba6d88129Svetoslav        final boolean touchExplorationEnabled = Settings.Secure.getIntForUser(
14650d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov                mContext.getContentResolver(),
146658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId) == 1;
146757bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (touchExplorationEnabled != userState.mIsTouchExplorationEnabled) {
146857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
146957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
147057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        }
147157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
1472b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov    }
1473b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov
147457bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readDisplayMagnificationEnabledSettingLocked(UserState userState) {
147557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        final boolean displayMagnificationEnabled = Settings.Secure.getIntForUser(
14761cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov                mContext.getContentResolver(),
147758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
147858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                0, userState.mUserId) == 1;
147957bf88508e0491caced22c4c592d33aba6d88129Svetoslav        if (displayMagnificationEnabled != userState.mIsDisplayMagnificationEnabled) {
148057bf88508e0491caced22c4c592d33aba6d88129Svetoslav            userState.mIsDisplayMagnificationEnabled = displayMagnificationEnabled;
148157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
1482447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        }
148357bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
1484447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov    }
1485447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
148657bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private boolean readEnhancedWebAccessibilityEnabledChangedLocked(UserState userState) {
148757bf88508e0491caced22c4c592d33aba6d88129Svetoslav         final boolean enhancedWeAccessibilityEnabled = Settings.Secure.getIntForUser(
1488447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
1489447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                0, userState.mUserId) == 1;
149057bf88508e0491caced22c4c592d33aba6d88129Svetoslav         if (enhancedWeAccessibilityEnabled != userState.mIsEnhancedWebAccessibilityEnabled) {
149157bf88508e0491caced22c4c592d33aba6d88129Svetoslav             userState.mIsEnhancedWebAccessibilityEnabled = enhancedWeAccessibilityEnabled;
149257bf88508e0491caced22c4c592d33aba6d88129Svetoslav             return true;
149357bf88508e0491caced22c4c592d33aba6d88129Svetoslav         }
149457bf88508e0491caced22c4c592d33aba6d88129Svetoslav         return false;
149557bf88508e0491caced22c4c592d33aba6d88129Svetoslav    }
149657bf88508e0491caced22c4c592d33aba6d88129Svetoslav
1497410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette    private boolean readDisplayColorAdjustmentSettingsLocked(UserState userState) {
1498f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette        final boolean displayAdjustmentsEnabled = DisplayAdjustmentUtils.hasAdjustments(mContext,
1499f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette                userState.mUserId);
1500f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette        if (displayAdjustmentsEnabled != userState.mHasDisplayColorAdjustment) {
1501f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette            userState.mHasDisplayColorAdjustment = displayAdjustmentsEnabled;
1502410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette            return true;
1503410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        }
1504f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette        // If display adjustment is enabled, always assume there was a change in
1505f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette        // the adjustment settings.
1506f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette        return displayAdjustmentsEnabled;
1507410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette    }
1508410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette
1509cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    private boolean readHighTextContrastEnabledSettingLocked(UserState userState) {
1510cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        final boolean highTextContrastEnabled = Settings.Secure.getIntForUser(
1511cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                mContext.getContentResolver(),
1512cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0,
1513cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                userState.mUserId) == 1;
1514cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        if (highTextContrastEnabled != userState.mIsTextHighContrastEnabled) {
1515cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            userState.mIsTextHighContrastEnabled = highTextContrastEnabled;
1516cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            return true;
1517cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        }
1518cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        return false;
1519cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik    }
1520cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
152157bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void updateTouchExplorationLocked(UserState userState) {
1522042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        boolean enabled = false;
152357bf88508e0491caced22c4c592d33aba6d88129Svetoslav        final int serviceCount = userState.mBoundServices.size();
152457bf88508e0491caced22c4c592d33aba6d88129Svetoslav        for (int i = 0; i < serviceCount; i++) {
152557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            Service service = userState.mBoundServices.get(i);
1526042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            if (canRequestAndRequestsTouchExplorationLocked(service)) {
1527042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                enabled = true;
152857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                break;
152957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
153057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        }
1531042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        if (enabled != userState.mIsTouchExplorationEnabled) {
1532042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            userState.mIsTouchExplorationEnabled = enabled;
1533042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            Settings.Secure.putIntForUser(mContext.getContentResolver(),
1534042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0,
1535042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                    userState.mUserId);
1536042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        }
1537447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov    }
1538447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
1539042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav    private boolean canRequestAndRequestsTouchExplorationLocked(Service service) {
1540042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        // Service not ready or cannot request the feature - well nothing to do.
1541447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) {
154257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return false;
1543a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov        }
1544447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        // UI test automation service can always enable it.
1545447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        if (service.mIsAutomation) {
154657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
1547447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        }
1548447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion
1549447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
1550447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            // Up to JB-MR1 we had a white list with services that can enable touch
1551447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            // exploration. When a service is first started we show a dialog to the
1552447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            // use to get a permission to white list the service.
1553042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            UserState userState = getUserStateLocked(service.mUserId);
1554042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            if (userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) {
155557bf88508e0491caced22c4c592d33aba6d88129Svetoslav                return true;
1556042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            } else if (mEnableTouchExplorationDialog == null
1557042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                    || !mEnableTouchExplorationDialog.isShowing()) {
1558042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                mMainHandler.obtainMessage(
1559042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                        MainHandler.MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG,
1560042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                        service).sendToTarget();
1561447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            }
1562447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        } else {
1563688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            // Starting in JB-MR2 we request an accessibility service to declare
1564688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            // certain capabilities in its meta-data to allow it to enable the
1565688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav            // corresponding features.
1566042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            if ((service.mAccessibilityServiceInfo.getCapabilities()
1567688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav                    & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) != 0) {
156857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                return true;
1569447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            }
15703822896e226567c6cd3ef84518d318abd33a7624Svetoslav        }
157157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
15723822896e226567c6cd3ef84518d318abd33a7624Svetoslav    }
15733822896e226567c6cd3ef84518d318abd33a7624Svetoslav
157457bf88508e0491caced22c4c592d33aba6d88129Svetoslav    private void updateEnhancedWebAccessibilityLocked(UserState userState) {
1575042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        boolean enabled = false;
157657bf88508e0491caced22c4c592d33aba6d88129Svetoslav        final int serviceCount = userState.mBoundServices.size();
1577447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        for (int i = 0; i < serviceCount; i++) {
157857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            Service service = userState.mBoundServices.get(i);
1579042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            if (canRequestAndRequestsEnhancedWebAccessibilityLocked(service)) {
1580042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                enabled = true;
1581042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                break;
15823822896e226567c6cd3ef84518d318abd33a7624Svetoslav            }
1583a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov        }
1584042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        if (enabled != userState.mIsEnhancedWebAccessibilityEnabled) {
1585042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            userState.mIsEnhancedWebAccessibilityEnabled = enabled;
1586042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav            Settings.Secure.putIntForUser(mContext.getContentResolver(),
1587042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                    Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0,
1588042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav                    userState.mUserId);
1589042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav        }
1590a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov    }
1591a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov
1592042ccec5a0921b749b38fed021b82b224ce5a70aSvetoslav    private boolean canRequestAndRequestsEnhancedWebAccessibilityLocked(Service service) {
1593447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) {
159457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return false;
15953822896e226567c6cd3ef84518d318abd33a7624Svetoslav        }
1596688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        if (service.mIsAutomation || (service.mAccessibilityServiceInfo.getCapabilities()
1597688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav               & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0) {
159857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
1599e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
160057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        return false;
1601e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    }
1602e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1603f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette    private void updateDisplayColorAdjustmentSettingsLocked(UserState userState) {
1604f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette        DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId);
1605f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette    }
1606f242659afc6539f9f1104833a88e37b5f9203417Alan Viverette
160716e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav    private boolean hasRunningServicesLocked(UserState userState) {
160816e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav        return !userState.mBoundServices.isEmpty() || !userState.mBindingServices.isEmpty();
160916e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav    }
161016e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav
16111e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
16121e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        IBinder windowToken = mGlobalWindowTokens.get(windowId);
16131e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        if (windowToken == null) {
16141e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            windowToken = getCurrentUserStateLocked().mWindowTokens.get(windowId);
16151e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
16161e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        if (windowToken != null) {
16171e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            return mWindowManagerService.getCompatibleMagnificationSpecForWindow(
16181e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    windowToken);
16191e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
16201e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        return null;
16211e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    }
16221e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
16236ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov    @Override
16246ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov    public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
16256ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
16266ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        synchronized (mLock) {
16276ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            pw.println("ACCESSIBILITY MANAGER (dumpsys accessibility)");
16286ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            pw.println();
16296ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            final int userCount = mUserStates.size();
16306ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            for (int i = 0; i < userCount; i++) {
16316ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                UserState userState = mUserStates.valueAt(i);
16326ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append("User state[attributes:{id=" + userState.mUserId);
16336ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", currentUser=" + (userState.mUserId == mCurrentUserId));
16346ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", accessibilityEnabled=" + userState.mIsAccessibilityEnabled);
16356ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", touchExplorationEnabled=" + userState.mIsTouchExplorationEnabled);
16366ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", displayMagnificationEnabled="
16376ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        + userState.mIsDisplayMagnificationEnabled);
163857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                if (userState.mUiAutomationService != null) {
163957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    pw.append(", ");
164057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    userState.mUiAutomationService.dump(fd, pw, args);
164157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    pw.println();
164257bf88508e0491caced22c4c592d33aba6d88129Svetoslav                }
16436ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append("}");
16446ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.println();
16456ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append("           services:{");
164657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                final int serviceCount = userState.mBoundServices.size();
16476ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                for (int j = 0; j < serviceCount; j++) {
16486ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                    if (j > 0) {
16496ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        pw.append(", ");
16506ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        pw.println();
16516ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        pw.append("                     ");
16526ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                    }
165357bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    Service service = userState.mBoundServices.get(j);
16546ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                    service.dump(fd, pw, args);
16556ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                }
16566ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.println("}]");
16576ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.println();
16586ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            }
165904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mSecurityPolicy.mWindows != null) {
166004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                final int windowCount = mSecurityPolicy.mWindows.size();
166104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                for (int j = 0; j < windowCount; j++) {
166204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    if (j > 0) {
166304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        pw.append(',');
166404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        pw.println();
166504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    }
166604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    pw.append("Window[");
166704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(j);
166804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    pw.append(window.toString());
166904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    pw.append(']');
16704604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                }
16714604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav            }
16726ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        }
16736ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov    }
16746ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov
1675d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    private class AccessibilityConnectionWrapper implements DeathRecipient {
1676d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        private final int mWindowId;
167758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private final int mUserId;
1678d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        private final IAccessibilityInteractionConnection mConnection;
1679d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
1680d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        public AccessibilityConnectionWrapper(int windowId,
168158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                IAccessibilityInteractionConnection connection, int userId) {
1682d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            mWindowId = windowId;
168358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mUserId = userId;
1684d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            mConnection = connection;
1685d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        }
1686d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
1687d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        public void linkToDeath() throws RemoteException {
1688d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            mConnection.asBinder().linkToDeath(this, 0);
1689d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        }
1690d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
1691d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        public void unlinkToDeath() {
1692d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            mConnection.asBinder().unlinkToDeath(this, 0);
1693d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        }
1694d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
1695d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        @Override
1696d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        public void binderDied() {
1697d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            unlinkToDeath();
1698d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            synchronized (mLock) {
169958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                removeAccessibilityInteractionConnectionLocked(mWindowId, mUserId);
1700d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            }
1701d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        }
1702d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov    }
1703d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
170458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final class MainHandler extends Handler {
170558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public static final int MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER = 1;
170658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public static final int MSG_SEND_STATE_TO_CLIENTS = 2;
170758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3;
170857bf88508e0491caced22c4c592d33aba6d88129Svetoslav        public static final int MSG_ANNOUNCE_NEW_USER_IF_NEEDED = 5;
170957bf88508e0491caced22c4c592d33aba6d88129Svetoslav        public static final int MSG_UPDATE_INPUT_FILTER = 6;
171057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        public static final int MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG = 7;
1711c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public static final int MSG_SEND_KEY_EVENT_TO_INPUT_FILTER = 8;
17121e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public static final int MSG_CLEAR_ACCESSIBILITY_FOCUS = 9;
17131cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
17141cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        public MainHandler(Looper looper) {
17151cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            super(looper);
17161cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
17171cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1718e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        @Override
1719e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        public void handleMessage(Message msg) {
1720e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            final int type = msg.what;
1721e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            switch (type) {
1722e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov                case MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER: {
1723e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov                    AccessibilityEvent event = (AccessibilityEvent) msg.obj;
172458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    synchronized (mLock) {
172558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        if (mHasInputFilter && mInputFilter != null) {
172658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                            mInputFilter.notifyAccessibilityEvent(event);
172758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        }
1728e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov                    }
1729e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov                    event.recycle();
1730e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov                } break;
17318e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
1732c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                case MSG_SEND_KEY_EVENT_TO_INPUT_FILTER: {
1733c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    KeyEvent event = (KeyEvent) msg.obj;
1734c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    final int policyFlags = msg.arg1;
1735c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    synchronized (mLock) {
1736c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        if (mHasInputFilter && mInputFilter != null) {
1737c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            mInputFilter.sendInputEvent(event, policyFlags);
1738c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        }
1739c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    }
1740c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    event.recycle();
1741c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } break;
17428e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
174358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                case MSG_SEND_STATE_TO_CLIENTS: {
174458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    final int clientState = msg.arg1;
174558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    final int userId = msg.arg2;
174658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    sendStateToClients(clientState, mGlobalClients);
174758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    sendStateToClientsForUser(clientState, userId);
174858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                } break;
17498e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
175058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
175158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    final int userId = msg.arg1;
175258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    sendStateToClientsForUser(0, userId);
175358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                } break;
17548e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
17557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
17567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    announceNewUserIfNeeded();
17577befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                } break;
17588e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
1759545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov                case MSG_UPDATE_INPUT_FILTER: {
1760545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov                    UserState userState = (UserState) msg.obj;
1761447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    updateInputFilter(userState);
1762545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov                } break;
17638e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
176457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                case MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG: {
176557bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    Service service = (Service) msg.obj;
176657bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    showEnableTouchExplorationDialog(service);
176757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                } break;
17681e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
17691e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                case MSG_CLEAR_ACCESSIBILITY_FOCUS: {
17701e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    final int windowId = msg.arg1;
17711e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    InteractionBridge bridge;
17721e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    synchronized (mLock) {
17731e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        bridge = getInteractionBridgeLocked();
17741e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    }
17751e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    bridge.clearAccessibilityFocusNotLocked(windowId);
17761e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                } break;
17777befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
17787befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
17797befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
17807befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private void announceNewUserIfNeeded() {
17817befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            synchronized (mLock) {
17827befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                UserState userState = getCurrentUserStateLocked();
17837befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                if (userState.mIsAccessibilityEnabled) {
17847befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    UserManager userManager = (UserManager) mContext.getSystemService(
17857befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            Context.USER_SERVICE);
17867befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    String message = mContext.getString(R.string.user_switched,
17877befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            userManager.getUserInfo(mCurrentUserId).name);
17887befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    AccessibilityEvent event = AccessibilityEvent.obtain(
17897befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            AccessibilityEvent.TYPE_ANNOUNCEMENT);
17907befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    event.getText().add(message);
17917befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    sendAccessibilityEvent(event, mCurrentUserId);
17927befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                }
1793e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            }
1794e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
179558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
179658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private void sendStateToClientsForUser(int clientState, int userId) {
179758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final UserState userState;
179858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            synchronized (mLock) {
179958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                userState = getUserStateLocked(userId);
180058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
180158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            sendStateToClients(clientState, userState.mClients);
180258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
180358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
180458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private void sendStateToClients(int clientState,
180558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                RemoteCallbackList<IAccessibilityManagerClient> clients) {
180658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            try {
180758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int userClientCount = clients.beginBroadcast();
180858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                for (int i = 0; i < userClientCount; i++) {
180958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    IAccessibilityManagerClient client = clients.getBroadcastItem(i);
181058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    try {
181158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        client.setState(clientState);
181258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    } catch (RemoteException re) {
181358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        /* ignore */
181458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
181558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
181658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } finally {
181758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                clients.finishBroadcast();
181858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
181958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
1820e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    }
1821e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1822c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    private PendingEvent obtainPendingEventLocked(KeyEvent event, int policyFlags, int sequence) {
1823c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        PendingEvent pendingEvent = mPendingEventPool.acquire();
1824c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        if (pendingEvent == null) {
1825c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            pendingEvent = new PendingEvent();
1826c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
1827c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        pendingEvent.event = event;
1828c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        pendingEvent.policyFlags = policyFlags;
1829c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        pendingEvent.sequence = sequence;
1830c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        return pendingEvent;
1831c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    }
1832c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
1833c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    private void recyclePendingEventLocked(PendingEvent pendingEvent) {
1834c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        pendingEvent.clear();
1835c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        mPendingEventPool.release(pendingEvent);
1836c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    }
1837c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
18388e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    private int findWindowIdLocked(IBinder token) {
18398e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        final int globalIndex = mGlobalWindowTokens.indexOfValue(token);
18408e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        if (globalIndex >= 0) {
18418e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return mGlobalWindowTokens.keyAt(globalIndex);
18428e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
18438e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        UserState userState = getCurrentUserStateLocked();
18448e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        final int userIndex = userState.mWindowTokens.indexOfValue(token);
18458e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        if (userIndex >= 0) {
18468e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return userState.mWindowTokens.keyAt(userIndex);
18478e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
18488e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        return -1;
18498e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    }
18508e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
185104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav    private void ensureWindowsAvailableTimed() {
185204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        synchronized (mLock) {
185304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mSecurityPolicy.mWindows != null) {
185404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                return;
185504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            }
185604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            // If we have no registered callback, update the state we
185704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            // we may have to register one but it didn't happen yet.
185804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mWindowsForAccessibilityCallback == null) {
185904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                UserState userState = getCurrentUserStateLocked();
186004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                onUserStateChangedLocked(userState);
186104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            }
186204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            // We have no windows but do not care about them, done.
186304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mWindowsForAccessibilityCallback == null) {
186404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                return;
186504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            }
186604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
186704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            // Wait for the windows with a timeout.
186804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            final long startMillis = SystemClock.uptimeMillis();
186904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            while (mSecurityPolicy.mWindows == null) {
187004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
187104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
187204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                if (remainMillis <= 0) {
187304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    return;
187404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                }
187504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                try {
187604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    mLock.wait(remainMillis);
187704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                } catch (InterruptedException ie) {
187804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    /* ignore */
187904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                }
188004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            }
188104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        }
188204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav    }
188304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
1884b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov    /**
188575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * This class represents an accessibility service. It stores all per service
188675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * data required for the service management, provides API for starting/stopping the
188775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * service and is responsible for adding/removing the service in the data structures
188875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * for service management. The class also exposes configuration interface that is
188975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * passed to the service it represents as soon it is bound. It also serves as the
189075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     * connection for the service.
189175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov     */
1892f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov    class Service extends IAccessibilityServiceConnection.Stub
1893c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            implements ServiceConnection, DeathRecipient {;
1894e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
189558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        final int mUserId;
189658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
189775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        int mId = 0;
189875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1899cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        AccessibilityServiceInfo mAccessibilityServiceInfo;
1900736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
190175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        IBinder mService;
190275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
19034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        IAccessibilityServiceClient mServiceInterface;
190475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
190575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        int mEventTypes;
190675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
190775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        int mFeedbackType;
190875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1909a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        Set<String> mPackageNames = new HashSet<>();
191075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
191175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        boolean mIsDefault;
191275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1913e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        boolean mRequestTouchExplorationMode;
1914e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
19153822896e226567c6cd3ef84518d318abd33a7624Svetoslav        boolean mRequestEnhancedWebAccessibility;
19163822896e226567c6cd3ef84518d318abd33a7624Svetoslav
1917688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav        boolean mRequestFilterKeyEvents;
1918688a6977cf7673ed0542ab3d839053c4e38a4dbdSvetoslav
19198e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        boolean mRetrieveInteractiveWindows;
19208e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
192180943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        int mFetchFlags;
19224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
192375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        long mNotificationTimeout;
192475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
192575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        ComponentName mComponentName;
192675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
192775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        Intent mIntent;
192875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1929e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov        boolean mIsAutomation;
19308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
1931e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        final ResolveInfo mResolveInfo;
1932e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
19333a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav        final IBinder mOverlayWindowToken = new Binder();
19343a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav
193575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        // the events pending events to be dispatched to this service
193675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        final SparseArray<AccessibilityEvent> mPendingEvents =
1937a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new SparseArray<>();
193875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
1939c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        final KeyEventDispatcher mKeyEventDispatcher = new KeyEventDispatcher();
1940c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
1941bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov        boolean mWasConnectedAndDied;
1942bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov
1943c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        // Handler only for dispatching accessibility events since we use event
1944c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        // types as message types allowing us to remove messages per event type.
1945c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public Handler mEventDispatchHandler = new Handler(mMainHandler.getLooper()) {
1946e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            @Override
1947e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            public void handleMessage(Message message) {
1948c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                final int eventType =  message.what;
1949c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                notifyAccessibilityEventInternal(eventType);
1950e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            }
1951e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        };
1952e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1953c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        // Handler for scheduling method invocations on the main thread.
1954c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public InvocationHandler mInvocationHandler = new InvocationHandler(
1955c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                mMainHandler.getLooper());
1956c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
195758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public Service(int userId, ComponentName componentName,
195857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                AccessibilityServiceInfo accessibilityServiceInfo) {
195958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mUserId = userId;
1960e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            mResolveInfo = accessibilityServiceInfo.getResolveInfo();
196175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            mId = sIdCounter++;
19628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            mComponentName = componentName;
19638643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            mAccessibilityServiceInfo = accessibilityServiceInfo;
196457bf88508e0491caced22c4c592d33aba6d88129Svetoslav            mIsAutomation = (sFakeAccessibilityServiceComponentName.equals(componentName));
196557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (!mIsAutomation) {
19668643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                mIntent = new Intent().setComponent(mComponentName);
19678643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
19688643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                        com.android.internal.R.string.accessibility_binding_label);
19698643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
19708643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                        mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
19718643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
19728643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            setDynamicallyConfigurableProperties(accessibilityServiceInfo);
19738643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
19748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
19758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        public void setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) {
1976cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            mEventTypes = info.eventTypes;
1977cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            mFeedbackType = info.feedbackType;
1978cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            String[] packageNames = info.packageNames;
1979cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            if (packageNames != null) {
1980cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov                mPackageNames.addAll(Arrays.asList(packageNames));
1981cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            }
1982cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov            mNotificationTimeout = info.notificationTimeout;
19834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            mIsDefault = (info.flags & DEFAULT) != 0;
19844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1985df549f83810c6fa76be1845363ef69809a30e569Guang Zhu            if (mIsAutomation || info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion
19865a48f9758b990fe6c46359927a40aecb6a02b64cSvetoslav Ganov                    >= Build.VERSION_CODES.JELLY_BEAN) {
19879e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                if ((info.flags & AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0) {
19889e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                    mFetchFlags |= AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
19899e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                } else {
19909e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                    mFetchFlags &= ~AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
19919e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                }
19924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
1993c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov
19949e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav            if ((info.flags & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0) {
19959e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                mFetchFlags |= AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
19969e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav            } else {
19979e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav                mFetchFlags &= ~AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
19989e065121fa4cd7443c648f29c2f4c3a276041be8Svetoslav            }
199980943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov
2000db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav            mRequestTouchExplorationMode = (info.flags
2001db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav                    & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
2002db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav            mRequestEnhancedWebAccessibility = (info.flags
2003db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav                    & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
2004db7da0eb8b7d515c168d5b410764e24c9a0f9431Svetoslav            mRequestFilterKeyEvents = (info.flags
20058e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
20068e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            mRetrieveInteractiveWindows = (info.flags
20078e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    & AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
2008cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov        }
2009cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov
201075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        /**
201175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov         * Binds to the accessibility service.
20126ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov         *
20136ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov         * @return True if binding is successful.
201475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov         */
201557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        public boolean bindLocked() {
201657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            UserState userState = getUserStateLocked(mUserId);
201757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (!mIsAutomation) {
20186f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav                if (mService == null && mContext.bindServiceAsUser(
20196f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav                        mIntent, this, Context.BIND_AUTO_CREATE, new UserHandle(mUserId))) {
20206f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav                    userState.mBindingServices.add(mComponentName);
202157bf88508e0491caced22c4c592d33aba6d88129Svetoslav                }
202257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            } else {
202357bf88508e0491caced22c4c592d33aba6d88129Svetoslav                userState.mBindingServices.add(mComponentName);
202457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                mService = userState.mUiAutomationServiceClient.asBinder();
2025419036b560e79c11705e376ad171688ac496bb7dSvetoslav                mMainHandler.post(new Runnable() {
2026419036b560e79c11705e376ad171688ac496bb7dSvetoslav                    @Override
2027419036b560e79c11705e376ad171688ac496bb7dSvetoslav                    public void run() {
2028419036b560e79c11705e376ad171688ac496bb7dSvetoslav                        // Simulate asynchronous connection since in onServiceConnected
2029419036b560e79c11705e376ad171688ac496bb7dSvetoslav                        // we may modify the state data in case of an error but bind is
2030419036b560e79c11705e376ad171688ac496bb7dSvetoslav                        // called while iterating over the data and bad things can happen.
2031419036b560e79c11705e376ad171688ac496bb7dSvetoslav                        onServiceConnected(mComponentName, mService);
2032419036b560e79c11705e376ad171688ac496bb7dSvetoslav                    }
2033419036b560e79c11705e376ad171688ac496bb7dSvetoslav                });
203457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                userState.mUiAutomationService = this;
203575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
20366ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov            return false;
203775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
203875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
203975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        /**
204075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov         * Unbinds form the accessibility service and removes it from the data
204175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov         * structures for service management.
20426ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov         *
20436ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov         * @return True if unbinding is successful.
204475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov         */
204557bf88508e0491caced22c4c592d33aba6d88129Svetoslav        public boolean unbindLocked() {
204657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (mService == null) {
204757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                return false;
204875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
20496f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav            UserState userState = getUserStateLocked(mUserId);
2050c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mKeyEventDispatcher.flush();
205157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (!mIsAutomation) {
205257bf88508e0491caced22c4c592d33aba6d88129Svetoslav                mContext.unbindService(this);
205357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            } else {
20543c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                userState.destroyUiAutomationService();
205557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
20566f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav            removeServiceLocked(this, userState);
20572602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav            resetLocked();
205857bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return true;
205975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
206075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
20613822896e226567c6cd3ef84518d318abd33a7624Svetoslav        public boolean canReceiveEventsLocked() {
2062c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov            return (mEventTypes != 0 && mFeedbackType != 0 && mService != null);
206375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
206475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
20654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
2066c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public void setOnKeyEventResult(boolean handled, int sequence) {
2067c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mKeyEventDispatcher.setOnKeyEventResult(handled, sequence);
2068c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
2069c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2070c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        @Override
20714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public AccessibilityServiceInfo getServiceInfo() {
20724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            synchronized (mLock) {
20734213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return mAccessibilityServiceInfo;
20744213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
20754213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
20764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
20771e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public boolean canRetrieveInteractiveWindowsLocked() {
20781e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            return mSecurityPolicy.canRetrieveWindowContentLocked(this)
20791e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    && mRetrieveInteractiveWindows;
20801e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
20811e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
20824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
208375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void setServiceInfo(AccessibilityServiceInfo info) {
208458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final long identity = Binder.clearCallingIdentity();
208558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            try {
208658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                synchronized (mLock) {
208758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    // If the XML manifest had data to configure the service its info
208858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    // should be already set. In such a case update only the dynamically
208958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    // configurable properties.
209058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    AccessibilityServiceInfo oldInfo = mAccessibilityServiceInfo;
209158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    if (oldInfo != null) {
209258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        oldInfo.updateDynamicallyConfigurableProperties(info);
209358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        setDynamicallyConfigurableProperties(oldInfo);
209458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    } else {
209558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        setDynamicallyConfigurableProperties(info);
209658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
209757bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    UserState userState = getUserStateLocked(mUserId);
209857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    onUserStateChangedLocked(userState);
20994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
210058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } finally {
210158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Binder.restoreCallingIdentity(identity);
21024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
210375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
210475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
21054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
210675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void onServiceConnected(ComponentName componentName, IBinder service) {
210757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            synchronized (mLock) {
210857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                mService = service;
210957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                mServiceInterface = IAccessibilityServiceClient.Stub.asInterface(service);
211057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                UserState userState = getUserStateLocked(mUserId);
21116f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav                addServiceLocked(this, userState);
2112bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov                if (userState.mBindingServices.contains(mComponentName) || mWasConnectedAndDied) {
211357bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    userState.mBindingServices.remove(mComponentName);
2114bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov                    mWasConnectedAndDied = false;
2115a60fdfac9432972e520e8c53b3b0717b4c3a2973Svetoslav                    try {
21163a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                       mServiceInterface.init(this, mId, mOverlayWindowToken);
2117072906eef827cd8d92b48f79975d4f2e21d1c958Svetoslav                       onUserStateChangedLocked(userState);
2118a60fdfac9432972e520e8c53b3b0717b4c3a2973Svetoslav                    } catch (RemoteException re) {
2119072906eef827cd8d92b48f79975d4f2e21d1c958Svetoslav                        Slog.w(LOG_TAG, "Error while setting connection for service: "
2120072906eef827cd8d92b48f79975d4f2e21d1c958Svetoslav                                + service, re);
2121072906eef827cd8d92b48f79975d4f2e21d1c958Svetoslav                        binderDied();
2122a60fdfac9432972e520e8c53b3b0717b4c3a2973Svetoslav                    }
2123a60fdfac9432972e520e8c53b3b0717b4c3a2973Svetoslav                } else {
2124a60fdfac9432972e520e8c53b3b0717b4c3a2973Svetoslav                    binderDied();
212575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                }
212657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
212775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
212875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
21294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
21308e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        public List<AccessibilityWindowInfo> getWindows() {
213104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            ensureWindowsAvailableTimed();
21328e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
21330425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its perent as profiles
21340425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
21350425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
21368e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final int resolvedUserId = mSecurityPolicy
21378e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        .resolveCallingUserIdEnforcingPermissionsLocked(
2138ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
21398e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (resolvedUserId != mCurrentUserId) {
21408e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return null;
21418e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
21428e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final boolean permissionGranted =
21438e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        mSecurityPolicy.canRetrieveWindowsLocked(this);
21448e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (!permissionGranted) {
21458e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return null;
21468e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
214709687064f4cf681d2aa299c393e32f22fc013c96Svet Ganov                if (mSecurityPolicy.mWindows == null) {
214809687064f4cf681d2aa299c393e32f22fc013c96Svet Ganov                    return null;
214909687064f4cf681d2aa299c393e32f22fc013c96Svet Ganov                }
2150a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                List<AccessibilityWindowInfo> windows = new ArrayList<>();
21518e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final int windowCount = mSecurityPolicy.mWindows.size();
21528e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                for (int i = 0; i < windowCount; i++) {
21538e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(i);
21548e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    AccessibilityWindowInfo windowClone =
21558e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            AccessibilityWindowInfo.obtain(window);
21568e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    windowClone.setConnectionId(mId);
21578e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    windows.add(windowClone);
21588e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
21598e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                return windows;
21608e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
21618e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
21628e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
21638e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        @Override
21648e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        public AccessibilityWindowInfo getWindow(int windowId) {
216504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            ensureWindowsAvailableTimed();
21668e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
21670425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
21680425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
21690425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
21708e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final int resolvedUserId = mSecurityPolicy
21718e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        .resolveCallingUserIdEnforcingPermissionsLocked(
2172ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
21738e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (resolvedUserId != mCurrentUserId) {
21748e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return null;
21758e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
21768e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final boolean permissionGranted =
21778e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        mSecurityPolicy.canRetrieveWindowsLocked(this);
21788e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (!permissionGranted) {
21798e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return null;
21808e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
21818e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                AccessibilityWindowInfo window = mSecurityPolicy.findWindowById(windowId);
21828e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (window != null) {
21838e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window);
21848e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    windowClone.setConnectionId(mId);
21858e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return windowClone;
21868e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
21878e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                return null;
21888e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
21898e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
21908e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
21918e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        @Override
219280943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov        public boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
219380943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                long accessibilityNodeId, String viewIdResName, int interactionId,
219479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
21954a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov                throws RemoteException {
219658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedWindowId;
21978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            IAccessibilityInteractionConnection connection = null;
21989ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            Region partialInteractiveRegion = mTempRegion;
21998643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            synchronized (mLock) {
22000425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
22010425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
22020425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
220358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
220458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2205ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
220658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
2207152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
220858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
22098e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
22108e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final boolean permissionGranted =
22118e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
2212e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                if (!permissionGranted) {
2213152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
2214e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                } else {
221579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    connection = getConnectionLocked(resolvedWindowId);
2216e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    if (connection == null) {
2217152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                        return false;
2218e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    }
22198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
22209ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
22219ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        resolvedWindowId, partialInteractiveRegion)) {
22229ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    partialInteractiveRegion = null;
22239ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                }
22248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
22258bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov            final int interrogatingPid = Binder.getCallingPid();
22268643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            final long identityToken = Binder.clearCallingIdentity();
22271e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
22288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            try {
22299ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName,
22307498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        partialInteractiveRegion, interactionId, callback, mFetchFlags,
22317498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        interrogatingPid, interrogatingTid, spec);
2232152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return true;
22338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } catch (RemoteException re) {
22348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                if (DEBUG) {
223579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId().");
22368643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
22378643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } finally {
22388643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                Binder.restoreCallingIdentity(identityToken);
22398643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
2240152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            return false;
2241eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        }
2242eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov
22434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
2244152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        public boolean findAccessibilityNodeInfosByText(int accessibilityWindowId,
224579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                long accessibilityNodeId, String text, int interactionId,
22468bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov                IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
22478bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov                throws RemoteException {
224858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedWindowId;
22498643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            IAccessibilityInteractionConnection connection = null;
22509ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            Region partialInteractiveRegion = mTempRegion;
22518643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            synchronized (mLock) {
22520425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
22530425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
22540425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
225558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
225658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2257ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
225858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
2259152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
226058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
226158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
2262eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov                final boolean permissionGranted =
226379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
2264e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                if (!permissionGranted) {
2265152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
2266e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                } else {
226779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    connection = getConnectionLocked(resolvedWindowId);
2268e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    if (connection == null) {
2269152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                        return false;
2270e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    }
22718643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
22729ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
22739ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        resolvedWindowId, partialInteractiveRegion)) {
22749ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    partialInteractiveRegion = null;
22759ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                }
22768643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
22778bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov            final int interrogatingPid = Binder.getCallingPid();
22788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            final long identityToken = Binder.clearCallingIdentity();
22791e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
22808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            try {
2281c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov                connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
22827498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        partialInteractiveRegion, interactionId, callback, mFetchFlags,
22837498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        interrogatingPid, interrogatingTid, spec);
2284152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return true;
22858643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } catch (RemoteException re) {
22868643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                if (DEBUG) {
228779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()");
22888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
22898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } finally {
22908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                Binder.restoreCallingIdentity(identityToken);
22918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
2292152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            return false;
22938643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
22948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
22954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
2296152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        public boolean findAccessibilityNodeInfoByAccessibilityId(
2297152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                int accessibilityWindowId, long accessibilityNodeId, int interactionId,
22984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                IAccessibilityInteractionConnectionCallback callback, int flags,
22994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                long interrogatingTid) throws RemoteException {
230058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedWindowId;
23018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            IAccessibilityInteractionConnection connection = null;
23029ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            Region partialInteractiveRegion = mTempRegion;
23038643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            synchronized (mLock) {
23040425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
23050425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
23060425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
230758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
230858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2309ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
231058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
2311152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
231258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
231358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
23148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                final boolean permissionGranted =
231579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
2316e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                if (!permissionGranted) {
2317152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
2318e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                } else {
231979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    connection = getConnectionLocked(resolvedWindowId);
232079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    if (connection == null) {
2321152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                        return false;
2322e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    }
23238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
23249ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
23259ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        resolvedWindowId, partialInteractiveRegion)) {
23269ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    partialInteractiveRegion = null;
23279ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                }
23288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
23298bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov            final int interrogatingPid = Binder.getCallingPid();
23308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            final long identityToken = Binder.clearCallingIdentity();
23311e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
23328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            try {
2333021078554b902179442a345a9d080a165c3b5139Svetoslav Ganov                connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
23349ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        partialInteractiveRegion, interactionId, callback, mFetchFlags | flags,
23359ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        interrogatingPid, interrogatingTid, spec);
2336152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return true;
23378643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } catch (RemoteException re) {
23388643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                if (DEBUG) {
233979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
23408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
23418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } finally {
23428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                Binder.restoreCallingIdentity(identityToken);
23438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
2344152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            return false;
23458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
23468643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
23474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
2348152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        public boolean findFocus(int accessibilityWindowId, long accessibilityNodeId,
23494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                int focusType, int interactionId,
23504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
23514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                throws RemoteException {
235258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedWindowId;
23534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            IAccessibilityInteractionConnection connection = null;
23549ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            Region partialInteractiveRegion = mTempRegion;
23554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            synchronized (mLock) {
23560425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
23570425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
23580425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
235958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
236058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2361ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
236258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
2363152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
236458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
23651e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                resolvedWindowId = resolveAccessibilityWindowIdForFindFocusLocked(
23661e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        accessibilityWindowId, focusType);
23674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                final boolean permissionGranted =
23684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
23694213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                if (!permissionGranted) {
2370152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
23714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                } else {
23724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    connection = getConnectionLocked(resolvedWindowId);
23734213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    if (connection == null) {
2374152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                        return false;
23754213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    }
23764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
23779ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
23789ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        resolvedWindowId, partialInteractiveRegion)) {
23799ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    partialInteractiveRegion = null;
23809ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                }
23814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
23824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int interrogatingPid = Binder.getCallingPid();
23834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final long identityToken = Binder.clearCallingIdentity();
23841e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
23854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            try {
23867498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion,
23877498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
23887498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        spec);
2389152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return true;
23904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            } catch (RemoteException re) {
23914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                if (DEBUG) {
23921e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    Slog.e(LOG_TAG, "Error calling findFocus()");
23934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
23944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            } finally {
23954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                Binder.restoreCallingIdentity(identityToken);
23964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
2397152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            return false;
23984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
23994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
24004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
2401152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        public boolean focusSearch(int accessibilityWindowId, long accessibilityNodeId,
24024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                int direction, int interactionId,
24034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
24044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                throws RemoteException {
240558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedWindowId;
24064213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            IAccessibilityInteractionConnection connection = null;
24079ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            Region partialInteractiveRegion = mTempRegion;
24084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            synchronized (mLock) {
24090425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
24100425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
24110425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
241258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
241358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2414ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
241558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
2416152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
241758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
241858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
24194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                final boolean permissionGranted =
24204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
24214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                if (!permissionGranted) {
2422152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    return false;
24234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                } else {
24244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    connection = getConnectionLocked(resolvedWindowId);
24254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    if (connection == null) {
2426152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                        return false;
24274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    }
24284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
24299ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
24309ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        resolvedWindowId, partialInteractiveRegion)) {
24319ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    partialInteractiveRegion = null;
24329ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                }
24334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
24344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int interrogatingPid = Binder.getCallingPid();
24354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final long identityToken = Binder.clearCallingIdentity();
24361e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
24374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            try {
24387498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion,
24397498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
24407498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                        spec);
2441152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return true;
24424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            } catch (RemoteException re) {
24434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                if (DEBUG) {
24444213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()");
24454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
24464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            } finally {
24474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                Binder.restoreCallingIdentity(identityToken);
24484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
2449152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            return false;
24504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
24514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
24524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
24538643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        public boolean performAccessibilityAction(int accessibilityWindowId,
2454aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganov                long accessibilityNodeId, int action, Bundle arguments, int interactionId,
245558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
245658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                throws RemoteException {
245758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int resolvedWindowId;
24588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            IAccessibilityInteractionConnection connection = null;
24598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            synchronized (mLock) {
24600425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
24610425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
24620425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
246358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
246458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2465ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
246658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
246758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    return false;
246858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
246958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
24705c4cd189f298b3ddb9a5e8afc5f68546a9f96726Svetoslav                final boolean permissionGranted = mSecurityPolicy.canGetAccessibilityNodeInfoLocked(
24715c4cd189f298b3ddb9a5e8afc5f68546a9f96726Svetoslav                        this, resolvedWindowId);
2472e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                if (!permissionGranted) {
2473e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    return false;
2474e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                } else {
247579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    connection = getConnectionLocked(resolvedWindowId);
247679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    if (connection == null) {
2477e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                        return false;
2478e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov                    }
24798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
24808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
24819bf21873c900e7bf82d864172ab40527a48dae3eSvetoslav Ganov            final int interrogatingPid = Binder.getCallingPid();
24828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            final long identityToken = Binder.clearCallingIdentity();
24838643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            try {
2484aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganov                connection.performAccessibilityAction(accessibilityNodeId, action, arguments,
248580943d8daa6ab31ab5c486d57aea406aa0730d58Svetoslav Ganov                        interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid);
24868643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } catch (RemoteException re) {
24878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                if (DEBUG) {
248879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                    Slog.e(LOG_TAG, "Error calling performAccessibilityAction()");
24898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                }
24908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            } finally {
24918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                Binder.restoreCallingIdentity(identityToken);
24928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
24938bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov            return true;
24948643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
24958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
24967498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov        @Override
2497e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov        public boolean performGlobalAction(int action) {
249858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            synchronized (mLock) {
24990425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // We treat calls from a profile as if made by its parent as profiles
25000425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // share the accessibility state of the parent. The call below
25010425d7f56b5c14484777357075b285d59996e6e9Svetoslav                // performs the current profile parent resolution.
250258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                final int resolvedUserId = mSecurityPolicy
250358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        .resolveCallingUserIdEnforcingPermissionsLocked(
2504ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                                UserHandle.USER_CURRENT);
250558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                if (resolvedUserId != mCurrentUserId) {
250658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    return false;
250758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
250858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
250958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final long identity = Binder.clearCallingIdentity();
251058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            try {
251158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                switch (action) {
251258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    case AccessibilityService.GLOBAL_ACTION_BACK: {
251358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK);
251458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    } return true;
251558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    case AccessibilityService.GLOBAL_ACTION_HOME: {
251658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME);
251758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    } return true;
251858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    case AccessibilityService.GLOBAL_ACTION_RECENTS: {
251958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        openRecents();
252058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    } return true;
252158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: {
2522e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov                        expandNotifications();
2523e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov                    } return true;
2524e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov                    case AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS: {
2525e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov                        expandQuickSettings();
252658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    } return true;
2527e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette                    case AccessibilityService.GLOBAL_ACTION_POWER_DIALOG: {
2528e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette                        showGlobalActions();
2529e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette                    } return true;
253058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
253158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                return false;
253258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            } finally {
253358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Binder.restoreCallingIdentity(identity);
2534005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            }
2535005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        }
2536005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
25376ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        @Override
25386ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
25396ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
25406ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            synchronized (mLock) {
25416ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append("Service[label=" + mAccessibilityServiceInfo.getResolveInfo()
25426ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        .loadLabel(mContext.getPackageManager()));
25436ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", feedbackType"
25446ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        + AccessibilityServiceInfo.feedbackTypeToString(mFeedbackType));
254511adf6dc2438260c3e0d79cc189bcb4f6f15e9f4Svetoslav                pw.append(", capabilities=" + mAccessibilityServiceInfo.getCapabilities());
25466ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", eventTypes="
25476ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        + AccessibilityEvent.eventTypeToString(mEventTypes));
25486ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append(", notificationTimeout=" + mNotificationTimeout);
25496ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                pw.append("]");
25506ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov            }
25516ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        }
25526ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov
25536ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov        @Override
255475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        public void onServiceDisconnected(ComponentName componentName) {
2555f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov            /* do nothing - #binderDied takes care */
2556f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov        }
2557f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov
25583a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav        public void onAdded() throws RemoteException {
25593a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            linkToOwnDeathLocked();
25603a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            final long identity = Binder.clearCallingIdentity();
25613a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            try {
25623a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                mWindowManagerService.addWindowToken(mOverlayWindowToken,
25633a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                        WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
25643a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            } finally {
25653a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                Binder.restoreCallingIdentity(identity);
25663a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            }
25673a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav        }
25683a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav
25693a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav        public void onRemoved() {
25703a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            final long identity = Binder.clearCallingIdentity();
25713a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            try {
25723a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                mWindowManagerService.removeWindowToken(mOverlayWindowToken, true);
25733a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            } finally {
25743a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                Binder.restoreCallingIdentity(identity);
25753a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            }
25763a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav            unlinkToOwnDeathLocked();
25773a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav        }
25783a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav
25792602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav        public void linkToOwnDeathLocked() throws RemoteException {
2580f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov            mService.linkToDeath(this, 0);
2581f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov        }
2582f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov
25832602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav        public void unlinkToOwnDeathLocked() {
2584f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov            mService.unlinkToDeath(this, 0);
2585f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov        }
2586f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov
25872602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav        public void resetLocked() {
2588d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            try {
2589d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                // Clear the proxy in the other process so this
2590d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                // IAccessibilityServiceConnection can be garbage collected.
25913a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                mServiceInterface.init(null, mId, null);
2592d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            } catch (RemoteException re) {
2593d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov                /* ignore */
2594d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            }
2595d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            mService = null;
2596d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov            mServiceInterface = null;
2597d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov        }
2598d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov
2599bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov        public boolean isConnectedLocked() {
26002602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav            return (mService != null);
26012602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav        }
26022602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav
2603f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov        public void binderDied() {
260475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            synchronized (mLock) {
26052602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                // It is possible that this service's package was force stopped during
26062602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                // whose handling the death recipient is unlinked and still get a call
26072602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                // on binderDied since the call was made before we unlink but was
26082602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                // waiting on the lock we held during the force stop handling.
2609bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov                if (!isConnectedLocked()) {
26102602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                    return;
26112602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                }
2612bfa1bf020859a03668f1af1d59f035c53a97c7e8Svetoslav Ganov                mWasConnectedAndDied = true;
2613c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                mKeyEventDispatcher.flush();
261457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                UserState userState = getUserStateLocked(mUserId);
26156f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav                // The death recipient is unregistered in removeServiceLocked
26166f8218a442a8de50ef33d20263a59cd47c513e62Svetoslav                removeServiceLocked(this, userState);
26172602a3974aafc9e9be968e7bfcf5b1e61dd3d8feSvetoslav                resetLocked();
2618b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov                if (mIsAutomation) {
261957bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    // We no longer have an automation service, so restore
262057bf88508e0491caced22c4c592d33aba6d88129Svetoslav                    // the state based on values in the settings database.
26217379a95a0bb6bf430eaf3b84ddb94e4172dd0eeaSvetoslav                    userState.mInstalledServices.remove(mAccessibilityServiceInfo);
26227379a95a0bb6bf430eaf3b84ddb94e4172dd0eeaSvetoslav                    userState.mEnabledServices.remove(mComponentName);
26233c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                    userState.destroyUiAutomationService();
2624dd81183bbea34109e1ae2d75667fe4784be6132fSvetoslav                    if (readConfigurationForUserStateLocked(userState)) {
2625dd81183bbea34109e1ae2d75667fe4784be6132fSvetoslav                        onUserStateChangedLocked(userState);
2626dd81183bbea34109e1ae2d75667fe4784be6132fSvetoslav                    }
2627b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov                }
262875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
262975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
26308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
2631e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        /**
2632e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         * Performs a notification for an {@link AccessibilityEvent}.
2633e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         *
2634e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         * @param event The event.
2635e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         */
2636e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        public void notifyAccessibilityEvent(AccessibilityEvent event) {
2637e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            synchronized (mLock) {
2638e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                final int eventType = event.getEventType();
2639e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // Make a copy since during dispatch it is possible the event to
2640e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // be modified to remove its source if the receiving service does
2641e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // not have permission to access the window content.
2642e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                AccessibilityEvent newEvent = AccessibilityEvent.obtain(event);
2643e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                AccessibilityEvent oldEvent = mPendingEvents.get(eventType);
2644e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                mPendingEvents.put(eventType, newEvent);
2645e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2646e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                final int what = eventType;
2647e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                if (oldEvent != null) {
2648c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    mEventDispatchHandler.removeMessages(what);
2649e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    oldEvent.recycle();
2650e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                }
2651e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2652c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                Message message = mEventDispatchHandler.obtainMessage(what);
2653c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                mEventDispatchHandler.sendMessageDelayed(message, mNotificationTimeout);
2654e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            }
2655e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
2656e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2657e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        /**
2658e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         * Notifies an accessibility service client for a scheduled event given the event type.
2659e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         *
2660e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         * @param eventType The type of the event to dispatch.
2661e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov         */
2662e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        private void notifyAccessibilityEventInternal(int eventType) {
2663e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            IAccessibilityServiceClient listener;
2664e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            AccessibilityEvent event;
2665e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2666e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            synchronized (mLock) {
2667e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                listener = mServiceInterface;
2668e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2669e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // If the service died/was disabled while the message for dispatching
2670e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // the accessibility event was propagating the listener may be null.
2671e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                if (listener == null) {
2672e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    return;
2673e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                }
2674e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2675e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                event = mPendingEvents.get(eventType);
2676e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2677e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // Check for null here because there is a concurrent scenario in which this
2678e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // happens: 1) A binder thread calls notifyAccessibilityServiceDelayedLocked
2679e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // which posts a message for dispatching an event. 2) The message is pulled
2680e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // from the queue by the handler on the service thread and the latter is
2681e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // just about to acquire the lock and call this method. 3) Now another binder
2682e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // thread acquires the lock calling notifyAccessibilityServiceDelayedLocked
2683e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // so the service thread waits for the lock; 4) The binder thread replaces
2684e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // the event with a more recent one (assume the same event type) and posts a
2685e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // dispatch request releasing the lock. 5) Now the main thread is unblocked and
2686e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // dispatches the event which is removed from the pending ones. 6) And ... now
2687e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // the service thread handles the last message posted by the last binder call
2688e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // but the event is already dispatched and hence looking it up in the pending
2689e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // ones yields null. This check is much simpler that keeping count for each
2690e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // event type of each service to catch such a scenario since only one message
2691e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                // is processed at a time.
2692e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                if (event == null) {
2693e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    return;
2694e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                }
2695e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2696e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                mPendingEvents.remove(eventType);
26978e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (mSecurityPolicy.canRetrieveWindowContentLocked(this)) {
2698e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    event.setConnectionId(mId);
2699e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                } else {
2700e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    event.setSource(null);
2701e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                }
2702e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                event.setSealed(true);
2703e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            }
2704e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2705e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            try {
2706e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                listener.onAccessibilityEvent(event);
2707e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                if (DEBUG) {
2708e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    Slog.i(LOG_TAG, "Event " + event + " sent to " + listener);
2709e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                }
2710e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            } catch (RemoteException re) {
2711e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                Slog.e(LOG_TAG, "Error during sending " + event + " to " + listener, re);
2712e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            } finally {
2713e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                event.recycle();
2714e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            }
2715e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
2716e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2717e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        public void notifyGesture(int gestureId) {
2718c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_GESTURE,
2719c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    gestureId, 0).sendToTarget();
2720c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
2721c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2722c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public void notifyKeyEvent(KeyEvent event, int policyFlags) {
2723c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_KEY_EVENT,
2724c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    policyFlags, 0, event).sendToTarget();
2725e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
2726e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2727152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        public void notifyClearAccessibilityNodeInfoCache() {
2728c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mInvocationHandler.sendEmptyMessage(
27298e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    InvocationHandler.MSG_CLEAR_ACCESSIBILITY_CACHE);
27308e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
27318e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
2732e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        private void notifyGestureInternal(int gestureId) {
27338e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final IAccessibilityServiceClient listener;
27348e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
27358e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                listener = mServiceInterface;
27368e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
2737e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            if (listener != null) {
2738e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                try {
2739e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    listener.onGesture(gestureId);
2740e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                } catch (RemoteException re) {
2741e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    Slog.e(LOG_TAG, "Error during sending gesture " + gestureId
2742e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                            + " to " + mService, re);
2743e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                }
2744e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            }
2745e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
2746e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
2747c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        private void notifyKeyEventInternal(KeyEvent event, int policyFlags) {
2748c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            mKeyEventDispatcher.notifyKeyEvent(event, policyFlags);
2749c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
2750c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
27518e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        private void notifyClearAccessibilityCacheInternal() {
27528e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final IAccessibilityServiceClient listener;
27538e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
27548e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                listener = mServiceInterface;
27558e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
2756152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            if (listener != null) {
2757152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                try {
27588e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    listener.clearAccessibilityCache();
2759152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                } catch (RemoteException re) {
2760152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                    Slog.e(LOG_TAG, "Error during requesting accessibility info cache"
2761152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                            + " to be cleared.", re);
2762152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                }
2763152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
2764152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
2765152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
2766005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        private void sendDownAndUpKeyEvents(int keyCode) {
2767005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            final long token = Binder.clearCallingIdentity();
2768005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
2769005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            // Inject down.
2770005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            final long downTime = SystemClock.uptimeMillis();
2771005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            KeyEvent down = KeyEvent.obtain(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
2772005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
2773005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                    InputDevice.SOURCE_KEYBOARD, null);
2774005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            InputManager.getInstance().injectInputEvent(down,
2775005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                    InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
2776005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            down.recycle();
2777005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
2778005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            // Inject up.
2779005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            final long upTime = SystemClock.uptimeMillis();
2780005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            KeyEvent up = KeyEvent.obtain(downTime, upTime, KeyEvent.ACTION_UP, keyCode, 0, 0,
2781005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
2782005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                    InputDevice.SOURCE_KEYBOARD, null);
2783005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            InputManager.getInstance().injectInputEvent(up,
2784005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov                    InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
2785005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            up.recycle();
2786005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
2787005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            Binder.restoreCallingIdentity(token);
2788005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov        }
2789005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov
2790e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov        private void expandNotifications() {
2791e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov            final long token = Binder.clearCallingIdentity();
2792e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov
2793e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov            StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService(
2794e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov                    android.app.Service.STATUS_BAR_SERVICE);
279511cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler            statusBarManager.expandNotificationsPanel();
2796e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov
2797e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov            Binder.restoreCallingIdentity(token);
2798e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov        }
2799e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov
2800e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov        private void expandQuickSettings() {
28015c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov            final long token = Binder.clearCallingIdentity();
28025c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov
28035c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov            StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService(
28045c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov                    android.app.Service.STATUS_BAR_SERVICE);
280511cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler            statusBarManager.expandSettingsPanel();
28065c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov
28075c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov            Binder.restoreCallingIdentity(token);
28085c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov        }
28095c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov
2810c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov        private void openRecents() {
2811c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov            final long token = Binder.clearCallingIdentity();
2812c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov
2813c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov            IStatusBarService statusBarService = IStatusBarService.Stub.asInterface(
2814c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov                    ServiceManager.getService("statusbar"));
2815c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov            try {
2816c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov                statusBarService.toggleRecentApps();
2817c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov            } catch (RemoteException e) {
2818c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov                Slog.e(LOG_TAG, "Error toggling recent apps.");
2819c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov            }
2820c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov
2821c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov            Binder.restoreCallingIdentity(token);
2822c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov        }
2823c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov
2824e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette        private void showGlobalActions() {
2825e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette            mWindowManagerService.showGlobalActions();
2826e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette        }
2827e34560b21989eea54a139a0586d156ba573cc2eaAlan Viverette
282879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        private IAccessibilityInteractionConnection getConnectionLocked(int windowId) {
28298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            if (DEBUG) {
28308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId);
28318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
283258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            AccessibilityConnectionWrapper wrapper = mGlobalInteractionConnections.get(windowId);
283358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (wrapper == null) {
283458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                wrapper = getCurrentUserStateLocked().mInteractionConnections.get(windowId);
283558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
283679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            if (wrapper != null && wrapper.mConnection != null) {
283779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                return wrapper.mConnection;
283879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
283979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            if (DEBUG) {
284079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov                Slog.e(LOG_TAG, "No interaction connection to window: " + windowId);
284179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
284279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            return null;
284379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov        }
284479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov
284558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) {
28460d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov            if (accessibilityWindowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
28473f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav                return mSecurityPolicy.getActiveWindowId();
284879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            }
284979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov            return accessibilityWindowId;
28508643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
28517961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganov
28521e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        private int resolveAccessibilityWindowIdForFindFocusLocked(int windowId, int focusType) {
28531e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            if (windowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
28541e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                return mSecurityPolicy.mActiveWindowId;
28558e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
28561e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            if (windowId == AccessibilityNodeInfo.ANY_WINDOW_ID) {
28571e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                if (focusType == AccessibilityNodeInfo.FOCUS_INPUT) {
28581e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    return mSecurityPolicy.mFocusedWindowId;
28591e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                } else if (focusType == AccessibilityNodeInfo.FOCUS_ACCESSIBILITY) {
28601e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    return mSecurityPolicy.mAccessibilityFocusedWindowId;
28611e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                }
2862c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov            }
28631e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            return windowId;
28647961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganov        }
2865c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2866c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        private final class InvocationHandler extends Handler {
2867c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public static final int MSG_ON_GESTURE = 1;
2868c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public static final int MSG_ON_KEY_EVENT = 2;
28698e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            public static final int MSG_CLEAR_ACCESSIBILITY_CACHE = 3;
2870c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public static final int MSG_ON_KEY_EVENT_TIMEOUT = 4;
2871c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2872c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public InvocationHandler(Looper looper) {
2873c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                super(looper, null, true);
2874c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2875c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2876c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            @Override
2877c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public void handleMessage(Message message) {
2878c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                final int type = message.what;
2879c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                switch (type) {
2880c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    case MSG_ON_GESTURE: {
2881c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        final int gestureId = message.arg1;
2882c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        notifyGestureInternal(gestureId);
2883c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    } break;
28848e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
2885c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    case MSG_ON_KEY_EVENT: {
2886c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        KeyEvent event = (KeyEvent) message.obj;
2887c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        final int policyFlags = message.arg1;
2888c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        notifyKeyEventInternal(event, policyFlags);
2889c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    } break;
28908e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
28918e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    case MSG_CLEAR_ACCESSIBILITY_CACHE: {
28928e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        notifyClearAccessibilityCacheInternal();
2893c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    } break;
28948e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
2895c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    case MSG_ON_KEY_EVENT_TIMEOUT: {
2896c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        PendingEvent eventState = (PendingEvent) message.obj;
2897c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        setOnKeyEventResult(false, eventState.sequence);
2898c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    } break;
28998e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
2900c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    default: {
2901c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        throw new IllegalArgumentException("Unknown message: " + type);
2902c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    }
2903c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2904c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2905c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
2906c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2907c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        private final class KeyEventDispatcher {
2908c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2909c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private static final long ON_KEY_EVENT_TIMEOUT_MILLIS = 500;
2910c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2911c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private PendingEvent mPendingEvents;
2912c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2913c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private final InputEventConsistencyVerifier mSentEventsVerifier =
2914c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    InputEventConsistencyVerifier.isInstrumentationEnabled()
2915c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            ? new InputEventConsistencyVerifier(
2916c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                                    this, 0, KeyEventDispatcher.class.getSimpleName()) : null;
2917c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2918c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public void notifyKeyEvent(KeyEvent event, int policyFlags) {
2919c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                final PendingEvent pendingEvent;
2920c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2921c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                synchronized (mLock) {
2922c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    pendingEvent = addPendingEventLocked(event, policyFlags);
2923c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2924c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2925c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                Message message = mInvocationHandler.obtainMessage(
2926c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        InvocationHandler.MSG_ON_KEY_EVENT_TIMEOUT, pendingEvent);
2927c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                mInvocationHandler.sendMessageDelayed(message, ON_KEY_EVENT_TIMEOUT_MILLIS);
2928c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2929c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                try {
2930c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    // Accessibility services are exclusively not in the system
2931c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    // process, therefore no need to clone the motion event to
2932c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    // prevent tampering. It will be cloned in the IPC call.
2933c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    mServiceInterface.onKeyEvent(pendingEvent.event, pendingEvent.sequence);
2934c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                } catch (RemoteException re) {
2935c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    setOnKeyEventResult(false, pendingEvent.sequence);
2936c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2937c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2938c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2939c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public void setOnKeyEventResult(boolean handled, int sequence) {
2940c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                synchronized (mLock) {
2941c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    PendingEvent pendingEvent = removePendingEventLocked(sequence);
2942c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    if (pendingEvent != null) {
2943c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        mInvocationHandler.removeMessages(
2944c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                                InvocationHandler.MSG_ON_KEY_EVENT_TIMEOUT,
2945c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                                pendingEvent);
2946c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        pendingEvent.handled = handled;
2947c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        finishPendingEventLocked(pendingEvent);
2948c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    }
2949c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2950c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2951c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2952c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            public void flush() {
2953c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                synchronized (mLock) {
2954c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    cancelAllPendingEventsLocked();
29551487cd5afc23c4c8f0a069bbcf9cdb3f40692449Svetoslav                    if (mSentEventsVerifier != null) {
29561487cd5afc23c4c8f0a069bbcf9cdb3f40692449Svetoslav                        mSentEventsVerifier.reset();
29571487cd5afc23c4c8f0a069bbcf9cdb3f40692449Svetoslav                    }
2958c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2959c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2960c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2961c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private PendingEvent addPendingEventLocked(KeyEvent event, int policyFlags) {
2962c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                final int sequence = event.getSequenceNumber();
2963c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                PendingEvent pendingEvent = obtainPendingEventLocked(event, policyFlags, sequence);
2964c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                pendingEvent.next = mPendingEvents;
2965c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                mPendingEvents = pendingEvent;
2966c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                return pendingEvent;
2967c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2968c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2969c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private PendingEvent removePendingEventLocked(int sequence) {
2970c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                PendingEvent previous = null;
2971c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                PendingEvent current = mPendingEvents;
2972c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2973c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                while (current != null) {
2974c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    if (current.sequence == sequence) {
2975c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        if (previous != null) {
2976c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            previous.next = current.next;
2977c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        } else {
2978c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            mPendingEvents = current.next;
2979c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        }
2980c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        current.next = null;
2981c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        return current;
2982c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    }
2983c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    previous = current;
2984c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    current = current.next;
2985c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2986c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                return null;
2987c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2988c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2989c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private void finishPendingEventLocked(PendingEvent pendingEvent) {
2990c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                if (!pendingEvent.handled) {
2991c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    sendKeyEventToInputFilter(pendingEvent.event, pendingEvent.policyFlags);
2992c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
2993c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                // Nullify the event since we do not want it to be
2994c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                // recycled yet. It will be sent to the input filter.
2995c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                pendingEvent.event = null;
2996c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                recyclePendingEventLocked(pendingEvent);
2997c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
2998c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
2999c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private void sendKeyEventToInputFilter(KeyEvent event, int policyFlags) {
3000c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                if (DEBUG) {
3001c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    Slog.i(LOG_TAG, "Injecting event: " + event);
3002c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
3003c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                if (mSentEventsVerifier != null) {
3004c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    mSentEventsVerifier.onKeyEvent(event, 0);
3005c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
3006c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
3007c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                mMainHandler.obtainMessage(MainHandler.MSG_SEND_KEY_EVENT_TO_INPUT_FILTER,
3008c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                        policyFlags, 0, event).sendToTarget();
3009c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
3010c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
3011c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            private void cancelAllPendingEventsLocked() {
3012c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                while (mPendingEvents != null) {
3013c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    PendingEvent pendingEvent = removePendingEventLocked(mPendingEvents.sequence);
3014c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    pendingEvent.handled = false;
3015c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    mInvocationHandler.removeMessages(InvocationHandler.MSG_ON_KEY_EVENT_TIMEOUT,
3016c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                            pendingEvent);
3017c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                    finishPendingEventLocked(pendingEvent);
3018c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                }
3019c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
3020c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
3021c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    }
3022c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
3023c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav    private static final class PendingEvent {
3024c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        PendingEvent next;
3025c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
3026c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        KeyEvent event;
3027c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        int policyFlags;
3028c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        int sequence;
3029c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        boolean handled;
3030c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav
3031c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        public void clear() {
3032c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            if (event != null) {
3033c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                event.recycle();
3034c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav                event = null;
3035c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            }
3036c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            next = null;
3037c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            policyFlags = 0;
3038c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            sequence = 0;
3039c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav            handled = false;
3040c4fccd183f1bb47a027bb303af5e65bec2f68b1bSvetoslav        }
30418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
30428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
30438e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    final class WindowsForAccessibilityCallback implements
30448e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            WindowManagerInternal.WindowsForAccessibilityCallback {
30458e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30468e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        @Override
30478e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        public void onWindowsForAccessibilityChanged(List<WindowInfo> windows) {
30488e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
30498e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // Populate the windows to report.
3050a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                List<AccessibilityWindowInfo> reportedWindows = new ArrayList<>();
3051a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                final int receivedWindowCount = windows.size();
30528e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                for (int i = 0; i < receivedWindowCount; i++) {
3053a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                    WindowInfo receivedWindow = windows.get(i);
30548e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    AccessibilityWindowInfo reportedWindow = populateReportedWindow(
30558e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            receivedWindow);
30568e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    if (reportedWindow != null) {
30578e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        reportedWindows.add(reportedWindow);
30588e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    }
30598e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
30608e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30618e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (DEBUG) {
30628e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    Slog.i(LOG_TAG, "Windows changed: " + reportedWindows);
30638e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
30648e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30658e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // Let the policy update the focused and active windows.
30668e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                mSecurityPolicy.updateWindowsLocked(reportedWindows);
306704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
306804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                // Someone may be waiting for the windows - advertise it.
306904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                mLock.notifyAll();
30708e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
30718e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
30728e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30738e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        private AccessibilityWindowInfo populateReportedWindow(WindowInfo window) {
30748e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final int windowId = findWindowIdLocked(window.token);
30758e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (windowId < 0) {
30768e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                return null;
30778e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
30788e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30798e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
30808e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30818e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            reportedWindow.setId(windowId);
30828e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            reportedWindow.setType(getTypeForWindowManagerWindowType(window.type));
30838e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            reportedWindow.setLayer(window.layer);
30848e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            reportedWindow.setFocused(window.focused);
30858e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            reportedWindow.setBoundsInScreen(window.boundsInScreen);
30868e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30878e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final int parentId = findWindowIdLocked(window.parentToken);
30888e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (parentId >= 0) {
30898e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                reportedWindow.setParentId(parentId);
30908e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
30918e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
30928e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (window.childTokens != null) {
30938e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                final int childCount = window.childTokens.size();
30948e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                for (int i = 0; i < childCount; i++) {
30958e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    IBinder childToken = window.childTokens.get(i);
30968e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    final int childId = findWindowIdLocked(childToken);
30978e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    if (childId >= 0) {
30988e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        reportedWindow.addChild(childId);
30998e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    }
31008e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
31018e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
31028e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
31038e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return reportedWindow;
31048e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
31058e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
31068e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        private int getTypeForWindowManagerWindowType(int windowType) {
31078e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            switch (windowType) {
31088e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_APPLICATION:
31098e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
31108e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
31118e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_APPLICATION_STARTING:
31128e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
31138e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_BASE_APPLICATION:
31148e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_PHONE:
31158e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
31168e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_TOAST:
31178e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG: {
31188e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return AccessibilityWindowInfo.TYPE_APPLICATION;
31198e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
31208e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
31218e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_INPUT_METHOD:
31228e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: {
31238e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return AccessibilityWindowInfo.TYPE_INPUT_METHOD;
31248e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
31258e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
31268e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
31278e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR:
31288e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
31298e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
31308e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_STATUS_BAR:
31318e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL:
31328e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL:
31338e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
31348e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
31358e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
31368e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
31378e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY: {
31388e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return AccessibilityWindowInfo.TYPE_SYSTEM;
31398e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
31408e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
31413a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                case WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY: {
31423a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                    return AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY;
31433a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav                }
31443a5c721072c60c7ed9c8a95d0a65d0e3cb4eb9bbSvetoslav
31458e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                default: {
31468e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return -1;
31478e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
31488e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
31498e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
31508e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav    }
31518e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
31521e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    private final class InteractionBridge {
31531e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        private final Display mDefaultDisplay;
31541e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        private final int mConnectionId;
31551e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        private final AccessibilityInteractionClient mClient;
31561e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31571e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public InteractionBridge() {
31581e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            AccessibilityServiceInfo info = new AccessibilityServiceInfo();
31591e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
31601e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
31611e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
31621e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            Service service = new Service(UserHandle.USER_NULL,
31631e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    sFakeAccessibilityServiceComponentName, info);
31641e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31651e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            mConnectionId = service.mId;
31661e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31671e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            mClient = AccessibilityInteractionClient.getInstance();
31681e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            mClient.addConnection(mConnectionId, service);
31691e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31701e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            //TODO: (multi-display) We need to support multiple displays.
31711e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            DisplayManager displayManager = (DisplayManager)
31721e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    mContext.getSystemService(Context.DISPLAY_SERVICE);
31731e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
31741e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
31751e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31761e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public void clearAccessibilityFocusNotLocked(int windowId) {
31771e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked(windowId);
31781e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            if (focus != null) {
31791e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                focus.performAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
31801e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            }
31811e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
31821e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31837498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov        public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) {
31841e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked();
31851e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            if (focus == null) {
31861e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                return false;
31871e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            }
31881e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
31891e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            synchronized (mLock) {
3190ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                Rect boundsInScreen = mTempRect;
3191ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                focus.getBoundsInScreen(boundsInScreen);
31927498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov
3193ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                // Clip to the window bounds.
3194ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                Rect windowBounds = mTempRect1;
3195ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                getWindowBounds(focus.getWindowId(), windowBounds);
3196ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                boundsInScreen.intersect(windowBounds);
3197ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                if (boundsInScreen.isEmpty()) {
31987498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                    return false;
31997498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                }
32001e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
3201ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                // Apply magnification if needed.
32021e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId());
32031e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                if (spec != null && !spec.isNop()) {
3204ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                    boundsInScreen.offset((int) -spec.offsetX, (int) -spec.offsetY);
3205ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                    boundsInScreen.scale(1 / spec.scale);
32061e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                }
32071e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
3208ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                // Clip to the screen bounds.
32097498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                Point screenSize = mTempPoint;
32107498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                mDefaultDisplay.getRealSize(screenSize);
3211ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                boundsInScreen.intersect(0, 0, screenSize.x, screenSize.y);
3212ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                if (boundsInScreen.isEmpty()) {
32137498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                    return false;
32147498efdc5e163d6b4a11db941c7d13c169d37284Svet Ganov                }
32151e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
3216ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav                outPoint.set(boundsInScreen.centerX(), boundsInScreen.centerY());
32171e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            }
3218ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav
3219ded133c446fa9d0d23e6bde19a66fb2ce3980491Svetoslav            return true;
32201e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
32211e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
32221e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        private AccessibilityNodeInfo getAccessibilityFocusNotLocked() {
32231e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            final int focusedWindowId;
32241e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            synchronized (mLock) {
32251e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                focusedWindowId = mSecurityPolicy.mAccessibilityFocusedWindowId;
32261e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                if (focusedWindowId == SecurityPolicy.INVALID_WINDOW_ID) {
32271e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    return null;
32281e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                }
32291e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            }
32301e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            return getAccessibilityFocusNotLocked(focusedWindowId);
32311e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
32321e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
32331e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        private AccessibilityNodeInfo getAccessibilityFocusNotLocked(int windowId) {
32341e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            return mClient.findFocus(mConnectionId,
32351e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    windowId, AccessibilityNodeInfo.ROOT_NODE_ID,
32361e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
32371e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        }
32381e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav    }
32391e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
32408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    final class SecurityPolicy {
32411e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public static final int INVALID_WINDOW_ID = -1;
32421e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
32438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
32444213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            AccessibilityEvent.TYPE_VIEW_CLICKED
32454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_FOCUSED
32464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
32474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
32484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
32494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
32504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
32514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_SELECTED
3252a0156177cdc809795dd8bc5a19943dd2b6f82b66Svetoslav Ganov            | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
3253a0156177cdc809795dd8bc5a19943dd2b6f82b66Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
32544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_SCROLLED
32554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
32568e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
32578e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
32588e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
325904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        public List<AccessibilityWindowInfo> mWindows;
32608e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
32611e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public int mActiveWindowId = INVALID_WINDOW_ID;
32621e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public int mFocusedWindowId = INVALID_WINDOW_ID;
32631e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public int mAccessibilityFocusedWindowId = INVALID_WINDOW_ID;
32641e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public long mAccessibilityFocusNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
32651e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
32666ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov        private boolean mTouchInteractionInProgress;
32678643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
32688e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        private boolean canDispatchAccessibilityEventLocked(AccessibilityEvent event) {
326958fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov            final int eventType = event.getEventType();
327058fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov            switch (eventType) {
327158fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                // All events that are for changes in a global window
327258fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                // state should *always* be dispatched.
327358fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
327458fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
3275ba3787d849610a7c71fc6f0d9468855c3d369807Kristian Monsen                case AccessibilityEvent.TYPE_ANNOUNCEMENT:
327658fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                // All events generated by the user touching the
327758fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                // screen should *always* be dispatched.
327858fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
327958fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
328058fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
328158fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
328258fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START:
328358fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
328458fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
3285a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
3286a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                // Also windows changing should always be anounced.
3287a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                case AccessibilityEvent.TYPE_WINDOWS_CHANGED: {
328858fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                    return true;
328958fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                }
329058fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov                // All events for changes in window content should be
32918e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // dispatched *only* if this window is one of the windows
32928e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // the accessibility layer reports which are windows
32938e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // that a sighted user can touch.
32948e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                default: {
32958e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    return isRetrievalAllowingWindow(event.getWindowId());
32968e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
32978e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
32988e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
32998e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
330004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        public void clearWindowsLocked() {
330104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            List<AccessibilityWindowInfo> windows = Collections.emptyList();
33023f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav            final int activeWindowId = mActiveWindowId;
330304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            updateWindowsLocked(windows);
33043f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav            mActiveWindowId = activeWindowId;
330504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            mWindows = null;
330604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        }
330704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
33088e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        public void updateWindowsLocked(List<AccessibilityWindowInfo> windows) {
330904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mWindows == null) {
331004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                mWindows = new ArrayList<>();
331104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            }
331204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
33138e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final int oldWindowCount = mWindows.size();
33148e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            for (int i = oldWindowCount - 1; i >= 0; i--) {
33158e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                mWindows.remove(i).recycle();
33168e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
33178e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
33181e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav            mFocusedWindowId = INVALID_WINDOW_ID;
33198e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (!mTouchInteractionInProgress) {
33201e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                mActiveWindowId = INVALID_WINDOW_ID;
33218e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
33228e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
33238e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // If the active window goes away while the user is touch exploring we
33248e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // reset the active window id and wait for the next hover event from
33258e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // under the user's finger to determine which one is the new one. It
33268e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // is possible that the finger is not moving and the input system
33278e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // filters out such events.
33288e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            boolean activeWindowGone = true;
33298e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
33308e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            final int windowCount = windows.size();
33318e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (windowCount > 0) {
33328e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                for (int i = 0; i < windowCount; i++) {
33338e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    AccessibilityWindowInfo window = windows.get(i);
33348e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    final int windowId = window.getId();
33358e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    if (window.isFocused()) {
33368e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        mFocusedWindowId = windowId;
33378e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        if (!mTouchInteractionInProgress) {
33388e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            mActiveWindowId = windowId;
33398e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            window.setActive(true);
33408e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        } else if (windowId == mActiveWindowId) {
33418e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            activeWindowGone = false;
33428e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        }
33438e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    }
33448e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    mWindows.add(window);
33458e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
33468e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
33478e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                if (mTouchInteractionInProgress && activeWindowGone) {
33484604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                    mActiveWindowId = mFocusedWindowId;
33498e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
33508e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
33518e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // Focused window may change the active one, so set the
33528e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // active window once we decided which it is.
33538e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                for (int i = 0; i < windowCount; i++) {
33548e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    AccessibilityWindowInfo window = mWindows.get(i);
33558e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    if (window.getId() == mActiveWindowId) {
3356f7174e87b6007000777b0124de9cef70d8618788Svetoslav                        window.setActive(true);
33578e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    }
335804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    if (window.getId() == mAccessibilityFocusedWindowId) {
335904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        window.setAccessibilityFocused(true);
336004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    }
33618e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
33628e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
33638e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
3364a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            notifyWindowsChanged();
3365eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov        }
3366eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov
33679ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav        public boolean computePartialInteractiveRegionForWindowLocked(int windowId,
33689ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                Region outRegion) {
33699ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            if (mWindows == null) {
33709ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                return false;
33719ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            }
33729ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav
337312b7328c0b7f83a233d9387eaa66d1a0ed403724Svet Ganov            // Windows are ordered in z order so start from the bottom and find
33749ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            // the window of interest. After that all windows that cover it should
33759ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            // be subtracted from the resulting region. Note that for accessibility
33769ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            // we are returning only interactive windows.
33779ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            Region windowInteractiveRegion = null;
33789ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            boolean windowInteractiveRegionChanged = false;
33799ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav
33809ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            final int windowCount = mWindows.size();
33819ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            for (int i = windowCount - 1; i >= 0; i--) {
33829ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                AccessibilityWindowInfo currentWindow = mWindows.get(i);
33839ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                if (windowInteractiveRegion == null) {
33849ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    if (currentWindow.getId() == windowId) {
33859ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        Rect currentWindowBounds = mTempRect;
33869ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        currentWindow.getBoundsInScreen(currentWindowBounds);
33879ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        outRegion.set(currentWindowBounds);
33889ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        windowInteractiveRegion = outRegion;
33899ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        continue;
33909ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    }
339112b7328c0b7f83a233d9387eaa66d1a0ed403724Svet Ganov                } else if (currentWindow.getType()
339212b7328c0b7f83a233d9387eaa66d1a0ed403724Svet Ganov                        != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
33939ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    Rect currentWindowBounds = mTempRect;
33949ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    currentWindow.getBoundsInScreen(currentWindowBounds);
33959ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
33969ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                        windowInteractiveRegionChanged = true;
33979ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                    }
33989ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav                }
33999ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            }
34009ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav
34019ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav            return windowInteractiveRegionChanged;
34029ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav        }
34039ae9ed24aa252acbc2e6288068b991dd5291967bSvetoslav
3404a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov        public void updateEventSourceLocked(AccessibilityEvent event) {
3405a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov            if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) {
3406a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov                event.setSource(null);
3407a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov            }
3408a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov        }
3409a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov
34101e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public void updateActiveAndAccessibilityFocusedWindowLocked(int windowId, long nodeId,
34111e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                int eventType) {
3412e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            // The active window is either the window that has input focus or
3413e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            // the window that the user is currently touching. If the user is
3414e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            // touching a window that does not have input focus as soon as the
3415e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            // the user stops touching that window the focused window becomes
34168e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // the active one. Here we detect the touched window and make it
34178e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // active. In updateWindowsLocked() we update the focused window
34188e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // and if the user is not touching the screen, we make the focused
34198e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            // window the active one.
3420e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov            switch (eventType) {
3421e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
34228e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    // If no service has the capability to introspect screen,
34238e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    // we do not register callback in the window manager for
34248e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    // window changes, so we have to ask the window manager
34258e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    // what the focused window is to update the active one.
34268e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    // The active window also determined events from which
34278e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    // windows are delivered.
34288e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    synchronized (mLock) {
34294604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                        if (mWindowsForAccessibilityCallback == null) {
34304604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                            mFocusedWindowId = getFocusedWindowId();
34314604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                            if (windowId == mFocusedWindowId) {
34324604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                                mActiveWindowId = windowId;
34334604abc97d7dd757bb76ff9b7fcf343dc4a15212Svetoslav                            }
34348e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        }
3435e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                    }
3436e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                } break;
34378e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
3438f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov                case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: {
34396ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov                    // Do not allow delayed hover events to confuse us
34406ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov                    // which the active window is.
34418e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    synchronized (mLock) {
34428e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        if (mTouchInteractionInProgress && mActiveWindowId != windowId) {
34438e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                            setActiveWindowLocked(windowId);
34448e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                        }
34456ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov                    }
3446e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov                } break;
34471e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
34481e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
34491e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    synchronized (mLock) {
34501e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        if (mAccessibilityFocusedWindowId != windowId) {
34511e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                            mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
34521e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                                    mAccessibilityFocusedWindowId, 0).sendToTarget();
345304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                            mSecurityPolicy.setAccessibilityFocusedWindowLocked(windowId);
34541e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                            mAccessibilityFocusNodeId = nodeId;
34551e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        }
34561e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    }
34571e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                } break;
34581e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
34591e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
34601e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    synchronized (mLock) {
34611e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        if (mAccessibilityFocusNodeId == nodeId) {
34621e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                            mAccessibilityFocusNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
34631e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        }
34641e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        if (mAccessibilityFocusNodeId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID
34651e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                                && mAccessibilityFocusedWindowId == windowId) {
34661e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                            mAccessibilityFocusedWindowId = INVALID_WINDOW_ID;
34671e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        }
34681e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    }
34691e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                } break;
34704e2a762eae1f6981d32e6098a95498865ad7f795Svetoslav Ganov            }
34718643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
34728643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
34736ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov        public void onTouchInteractionStart() {
34748e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
34758e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                mTouchInteractionInProgress = true;
34768e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
34776ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov        }
34786ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov
3479f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov        public void onTouchInteractionEnd() {
34808e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            synchronized (mLock) {
34818e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                mTouchInteractionInProgress = false;
34828e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // We want to set the active window to be current immediately
34838e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // after the user has stopped touching the screen since if the
34848e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // user types with the IME he should get a feedback for the
34858e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // letter typed in the text view which is in the input focused
34868e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // window. Note that we always deliver hover accessibility events
34878e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // (they are a result of user touching the screen) so change of
34888e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // the active window before all hover accessibility events from
34898e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                // the touched window are delivered is fine.
34901e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                final int oldActiveWindow = mSecurityPolicy.mActiveWindowId;
34918e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                setActiveWindowLocked(mFocusedWindowId);
34921e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav
34931e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                // If there is no service that can operate with active windows
34941e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                // we keep accessibility focus behavior to constrain it only in
34951e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                // the active window. Look at updateAccessibilityFocusBehaviorLocked
34961e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                // for details.
34971e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                if (oldActiveWindow != mSecurityPolicy.mActiveWindowId
34981e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        && mAccessibilityFocusedWindowId == oldActiveWindow
34991e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                        && getCurrentUserStateLocked().mAccessibilityFocusOnlyInActiveWindow) {
35001e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                    mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
35011e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                            oldActiveWindow, 0).sendToTarget();
35021e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav                }
35038e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
3504f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov        }
3505f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov
35063f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav        public int getActiveWindowId() {
35073f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav            if (mActiveWindowId == INVALID_WINDOW_ID && !mTouchInteractionInProgress) {
35083f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav                mActiveWindowId = getFocusedWindowId();
35093f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav            }
35103f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav            return mActiveWindowId;
35113f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav        }
35123f92ffc369c31c98620e22b66366adb93c60a5f8Svetoslav
35138e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        private void setActiveWindowLocked(int windowId) {
35148e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (mActiveWindowId != windowId) {
35158e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                mActiveWindowId = windowId;
351604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                if (mWindows != null) {
351704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    final int windowCount = mWindows.size();
351804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    for (int i = 0; i < windowCount; i++) {
351904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        AccessibilityWindowInfo window = mWindows.get(i);
352004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        window.setActive(window.getId() == windowId);
352104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    }
352204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                }
352304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                notifyWindowsChanged();
352404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            }
352504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        }
352604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
352704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav        private void setAccessibilityFocusedWindowLocked(int windowId) {
352804cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mAccessibilityFocusedWindowId != windowId) {
352904cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                mAccessibilityFocusedWindowId = windowId;
353004cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                if (mWindows != null) {
353104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    final int windowCount = mWindows.size();
353204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    for (int i = 0; i < windowCount; i++) {
353304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        AccessibilityWindowInfo window = mWindows.get(i);
353404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        window.setAccessibilityFocused(window.getId() == windowId);
353504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    }
35368e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
353704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav
3538a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                notifyWindowsChanged();
35398e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
35408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
35418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
3542a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        private void notifyWindowsChanged() {
354347b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav            if (mWindowsForAccessibilityCallback == null) {
354447b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav                return;
354547b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav            }
35469bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav            final long identity = Binder.clearCallingIdentity();
35479bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav            try {
35489bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav                // Let the client know the windows changed.
35499bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav                AccessibilityEvent event = AccessibilityEvent.obtain(
35509bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav                        AccessibilityEvent.TYPE_WINDOWS_CHANGED);
35519bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav                event.setEventTime(SystemClock.uptimeMillis());
35529bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav                sendAccessibilityEvent(event, mCurrentUserId);
35539bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav            } finally {
35549bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav                Binder.restoreCallingIdentity(identity);
35559bf08c7bc1844ec8130b47d0ec3783f374b21c46Svetoslav            }
3556a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        }
3557a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav
35588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        public boolean canGetAccessibilityNodeInfoLocked(Service service, int windowId) {
35598e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return canRetrieveWindowContentLocked(service) && isRetrievalAllowingWindow(windowId);
35608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
35618643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
35628e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        public boolean canRetrieveWindowsLocked(Service service) {
35638e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return canRetrieveWindowContentLocked(service) && service.mRetrieveInteractiveWindows;
35648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
35658643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
35668e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        public boolean canRetrieveWindowContentLocked(Service service) {
35678e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return (service.mAccessibilityServiceInfo.getCapabilities()
35688e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                    & AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
35694a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov        }
35704a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov
35710425d7f56b5c14484777357075b285d59996e6e9Svetoslav        private int resolveProfileParentLocked(int userId) {
35720425d7f56b5c14484777357075b285d59996e6e9Svetoslav            if (userId != mCurrentUserId) {
35730425d7f56b5c14484777357075b285d59996e6e9Svetoslav                final long identity = Binder.clearCallingIdentity();
35740425d7f56b5c14484777357075b285d59996e6e9Svetoslav                try {
35750425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    UserInfo parent = mUserManager.getProfileParent(userId);
35760425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    if (parent != null) {
35770425d7f56b5c14484777357075b285d59996e6e9Svetoslav                        return parent.getUserHandle().getIdentifier();
35780425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    }
35790425d7f56b5c14484777357075b285d59996e6e9Svetoslav                } finally {
35800425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    Binder.restoreCallingIdentity(identity);
35810425d7f56b5c14484777357075b285d59996e6e9Svetoslav                }
35820425d7f56b5c14484777357075b285d59996e6e9Svetoslav            }
35830425d7f56b5c14484777357075b285d59996e6e9Svetoslav            return userId;
35840425d7f56b5c14484777357075b285d59996e6e9Svetoslav        }
35850425d7f56b5c14484777357075b285d59996e6e9Svetoslav
358658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public int resolveCallingUserIdEnforcingPermissionsLocked(int userId) {
358758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int callingUid = Binder.getCallingUid();
3588d08d7ee4e9ce8c388e5dba392e2a6b156180dabcSvetoslav            if (callingUid == 0
3589d08d7ee4e9ce8c388e5dba392e2a6b156180dabcSvetoslav                    || callingUid == Process.SYSTEM_UID
359058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    || callingUid == Process.SHELL_UID) {
35910425d7f56b5c14484777357075b285d59996e6e9Svetoslav                if (userId == UserHandle.USER_CURRENT
35920425d7f56b5c14484777357075b285d59996e6e9Svetoslav                        || userId == UserHandle.USER_CURRENT_OR_SELF) {
35930425d7f56b5c14484777357075b285d59996e6e9Svetoslav                    return mCurrentUserId;
35940425d7f56b5c14484777357075b285d59996e6e9Svetoslav                }
35950425d7f56b5c14484777357075b285d59996e6e9Svetoslav                return resolveProfileParentLocked(userId);
359658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
359758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int callingUserId = UserHandle.getUserId(callingUid);
359858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (callingUserId == userId) {
35990425d7f56b5c14484777357075b285d59996e6e9Svetoslav                return resolveProfileParentLocked(userId);
360058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
3601ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav            final int callingUserParentId = resolveProfileParentLocked(callingUserId);
3602ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav            if (callingUserParentId == mCurrentUserId &&
3603ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                    (userId == UserHandle.USER_CURRENT
3604ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                            || userId == UserHandle.USER_CURRENT_OR_SELF)) {
3605ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav                return mCurrentUserId;
3606ceac51deddb873956c647d1b2dc7b2cc251d404bSvetoslav            }
360758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (!hasPermission(Manifest.permission.INTERACT_ACROSS_USERS)
360858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    && !hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)) {
360958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                throw new SecurityException("Call from user " + callingUserId + " as user "
361058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        + userId + " without permission INTERACT_ACROSS_USERS or "
361158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                        + "INTERACT_ACROSS_USERS_FULL not allowed.");
361258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
361358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            if (userId == UserHandle.USER_CURRENT
361458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
361558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                return mCurrentUserId;
361658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
361758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            throw new IllegalArgumentException("Calling user can be changed to only "
361858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
361958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
362058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
362158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public boolean isCallerInteractingAcrossUsers(int userId) {
362258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            final int callingUid = Binder.getCallingUid();
3623a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov            return (Binder.getCallingPid() == android.os.Process.myPid()
362458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    || callingUid == Process.SHELL_UID
362558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    || userId == UserHandle.USER_CURRENT
362658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    || userId == UserHandle.USER_CURRENT_OR_SELF);
362758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
362858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
36298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        private boolean isRetrievalAllowingWindow(int windowId) {
363047b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav            // The system gets to interact with any window it wants.
363147b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav            if (Binder.getCallingUid() == Process.SYSTEM_UID) {
363247b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav                return true;
363347b9c1524fe20b9ae2b210acdcad64f764df68e0Svetoslav            }
36348e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            if (windowId == mActiveWindowId) {
36358e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                return true;
36368e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
36378e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return findWindowById(windowId) != null;
36388e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        }
36398e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav
36408e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav        private AccessibilityWindowInfo findWindowById(int windowId) {
364104cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav            if (mWindows != null) {
364204cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                final int windowCount = mWindows.size();
364304cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                for (int i = 0; i < windowCount; i++) {
364404cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    AccessibilityWindowInfo window = mWindows.get(i);
364504cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    if (window.getId() == windowId) {
364604cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                        return window;
364704cab1bcc46b05cbb72632c53ad83943f705b494Svetoslav                    }
36488e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav                }
36498e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            }
36508e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            return null;
36518643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
36528643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
36538643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        private void enforceCallingPermission(String permission, String function) {
36548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            if (OWN_PROCESS_ID == Binder.getCallingPid()) {
36558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                return;
36568643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
36579371a0a0c0cdf9be0e0a32e4c3037cc2e216cfa0Svetoslav Ganov            if (!hasPermission(permission)) {
36588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov                throw new SecurityException("You do not have " + permission
36596ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        + " required to call " + function + " from pid="
36606ce77cdd6aff7193c746cd1eb87d5babf9158bacSvetoslav Ganov                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
36618643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
36628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
3663e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
366458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private boolean hasPermission(String permission) {
366558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
366658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
366758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
3668e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        private int getFocusedWindowId() {
36698e3feb15c5aec2c72b0ef120a1da325e1e8f0ddaSvetoslav            IBinder token = mWindowManagerService.getFocusedWindowToken();
3670cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav            synchronized (mLock) {
3671cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav                return findWindowIdLocked(token);
3672cbcc9695f0a701d620f48de75eaee05c4fef6f22Svetoslav            }
3673e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        }
36748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
367558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
367658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private class UserState {
367758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public final int mUserId;
367858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
36795fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        // Non-transient state.
368058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
368158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public final RemoteCallbackList<IAccessibilityManagerClient> mClients =
3682a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav            new RemoteCallbackList<>();
368358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
36845fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections =
3685a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                new SparseArray<>();
36865fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
3687a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        public final SparseArray<IBinder> mWindowTokens = new SparseArray<>();
36885fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
36895fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        // Transient state.
36905fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
36915fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        public final CopyOnWriteArrayList<Service> mBoundServices =
3692a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                new CopyOnWriteArrayList<>();
36935fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
369458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public final Map<ComponentName, Service> mComponentNameToServiceMap =
3695a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                new HashMap<>();
369658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
369758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public final List<AccessibilityServiceInfo> mInstalledServices =
3698a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                new ArrayList<>();
369958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
3700a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        public final Set<ComponentName> mBindingServices = new HashSet<>();
370157bf88508e0491caced22c4c592d33aba6d88129Svetoslav
3702a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav        public final Set<ComponentName> mEnabledServices = new HashSet<>();
370358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
3704447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        public final Set<ComponentName> mTouchExplorationGrantedServices =
3705a4725efd0bfa52cbddf6ca587d37fc4ebcbfaf72Svetoslav                new HashSet<>();
3706447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
370758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public int mHandledFeedbackTypes = 0;
370858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
37095fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        public int mLastSentClientState = -1;
371057bf88508e0491caced22c4c592d33aba6d88129Svetoslav
371158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public boolean mIsAccessibilityEnabled;
371258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public boolean mIsTouchExplorationEnabled;
3713cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        public boolean mIsTextHighContrastEnabled;
37143822896e226567c6cd3ef84518d318abd33a7624Svetoslav        public boolean mIsEnhancedWebAccessibilityEnabled;
371558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public boolean mIsDisplayMagnificationEnabled;
3716ca523d6e95061f99455589512100839118044d43Svetoslav        public boolean mIsFilterKeyEventsEnabled;
3717410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        public boolean mHasDisplayColorAdjustment;
37181e0d4af9986c8c2a658769a63bf8b385d25e0435Svetoslav        public boolean mAccessibilityFocusOnlyInActiveWindow;
371958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
372057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        private Service mUiAutomationService;
372157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        private IAccessibilityServiceClient mUiAutomationServiceClient;
372257bf88508e0491caced22c4c592d33aba6d88129Svetoslav
37233c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav        private IBinder mUiAutomationServiceOwner;
37243c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav        private final DeathRecipient mUiAutomationSerivceOnwerDeathRecipient =
37253c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                new DeathRecipient() {
37263c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            @Override
37273c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            public void binderDied() {
37283c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                mUiAutomationServiceOwner.unlinkToDeath(
37293c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                        mUiAutomationSerivceOnwerDeathRecipient, 0);
37303c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                mUiAutomationServiceOwner = null;
37313c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                if (mUiAutomationService != null) {
37323c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                    mUiAutomationService.binderDied();
37333c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                }
37343c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            }
37353c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav        };
37363c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav
373758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public UserState(int userId) {
373858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            mUserId = userId;
373958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
37407befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
374157bf88508e0491caced22c4c592d33aba6d88129Svetoslav        public int getClientState() {
374257bf88508e0491caced22c4c592d33aba6d88129Svetoslav            int clientState = 0;
374357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (mIsAccessibilityEnabled) {
374457bf88508e0491caced22c4c592d33aba6d88129Svetoslav                clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
374557bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
374657bf88508e0491caced22c4c592d33aba6d88129Svetoslav            // Touch exploration relies on enabled accessibility.
374757bf88508e0491caced22c4c592d33aba6d88129Svetoslav            if (mIsAccessibilityEnabled && mIsTouchExplorationEnabled) {
374857bf88508e0491caced22c4c592d33aba6d88129Svetoslav                clientState |= AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED;
374957bf88508e0491caced22c4c592d33aba6d88129Svetoslav            }
3750cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            if (mIsTextHighContrastEnabled) {
3751cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                clientState |= AccessibilityManager.STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED;
3752cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            }
375357bf88508e0491caced22c4c592d33aba6d88129Svetoslav            return clientState;
37547befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
37555fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
37565fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        public void onSwitchToAnotherUser() {
37575fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // Clear UI test automation state.
37585fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            if (mUiAutomationService != null) {
37595fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav                mUiAutomationService.binderDied();
37605fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            }
37615fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
37625fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // Unbind all services.
37635fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            unbindAllServicesLocked(this);
37645fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
37655fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // Clear service management state.
37665fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mBoundServices.clear();
37675fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mBindingServices.clear();
37685fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
37695fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // Clear event management state.
37705fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mHandledFeedbackTypes = 0;
37715fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mLastSentClientState = -1;
37725fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav
37735fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            // Clear state persisted in settings.
37745fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mEnabledServices.clear();
37755fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mTouchExplorationGrantedServices.clear();
37765fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mIsAccessibilityEnabled = false;
37775fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mIsTouchExplorationEnabled = false;
37785fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mIsEnhancedWebAccessibilityEnabled = false;
37795fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav            mIsDisplayMagnificationEnabled = false;
37805fec0c5ee5bbd83fd651644c90ff78fe32680a42Svetoslav        }
37813c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav
37823c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav        public void destroyUiAutomationService() {
37833c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            mUiAutomationService = null;
37843c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            mUiAutomationServiceClient = null;
37853c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            if (mUiAutomationServiceOwner != null) {
37863c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                mUiAutomationServiceOwner.unlinkToDeath(
37873c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                        mUiAutomationSerivceOnwerDeathRecipient, 0);
37883c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav                mUiAutomationServiceOwner = null;
37893c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav            }
37903c55e5c6595d28c64f5a760947c66fdefa2481e2Svetoslav        }
37917befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    }
37927befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
379358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    private final class AccessibilityContentObserver extends ContentObserver {
379458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
379558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private final Uri mAccessibilityEnabledUri = Settings.Secure.getUriFor(
379658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Settings.Secure.ACCESSIBILITY_ENABLED);
379758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
379858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private final Uri mTouchExplorationEnabledUri = Settings.Secure.getUriFor(
379958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Settings.Secure.TOUCH_EXPLORATION_ENABLED);
380058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
380158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private final Uri mDisplayMagnificationEnabledUri = Settings.Secure.getUriFor(
380258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
380358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
380458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor(
380558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
380658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
3807447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov        private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure
3808447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
3809447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
381057bf88508e0491caced22c4c592d33aba6d88129Svetoslav        private final Uri mEnhancedWebAccessibilityUri = Settings.Secure
3811447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION);
3812447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov
3813410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(
3814410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
3815410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette
3816410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        private final Uri mDisplayDaltonizerEnabledUri = Settings.Secure.getUriFor(
3817410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
3818cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
3819410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette        private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
3820410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
3821410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette
3822cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik        private final Uri mHighTextContrastUri = Settings.Secure.getUriFor(
3823cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);
3824cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
382558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public AccessibilityContentObserver(Handler handler) {
382658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            super(handler);
382758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
382858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
382958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public void register(ContentResolver contentResolver) {
383058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            contentResolver.registerContentObserver(mAccessibilityEnabledUri,
383158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    false, this, UserHandle.USER_ALL);
383258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            contentResolver.registerContentObserver(mTouchExplorationEnabledUri,
383358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    false, this, UserHandle.USER_ALL);
383458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            contentResolver.registerContentObserver(mDisplayMagnificationEnabledUri,
383558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    false, this, UserHandle.USER_ALL);
383658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri,
383758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    false, this, UserHandle.USER_ALL);
3838447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov            contentResolver.registerContentObserver(
3839447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    mTouchExplorationGrantedAccessibilityServicesUri,
3840447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    false, this, UserHandle.USER_ALL);
384157bf88508e0491caced22c4c592d33aba6d88129Svetoslav            contentResolver.registerContentObserver(mEnhancedWebAccessibilityUri,
3842447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    false, this, UserHandle.USER_ALL);
3843410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette            contentResolver.registerContentObserver(
3844410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                    mDisplayInversionEnabledUri, false, this, UserHandle.USER_ALL);
3845410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette            contentResolver.registerContentObserver(
3846410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                    mDisplayDaltonizerEnabledUri, false, this, UserHandle.USER_ALL);
3847410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette            contentResolver.registerContentObserver(
3848410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                    mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
3849cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            contentResolver.registerContentObserver(
3850cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    mHighTextContrastUri, false, this, UserHandle.USER_ALL);
385158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
385258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov
385358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        @Override
385458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        public void onChange(boolean selfChange, Uri uri) {
3855cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik            synchronized (mLock) {
3856cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                // Profiles share the accessibility state of the parent. Therefore,
3857cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                // we are checking for changes only the parent settings.
3858cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                UserState userState = getCurrentUserStateLocked();
3859cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
3860cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                // We will update when the automation service dies.
3861cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                if (userState.mUiAutomationService != null) {
3862cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    return;
386358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                }
3864cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik
3865cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                if (mAccessibilityEnabledUri.equals(uri)) {
3866cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readAccessibilityEnabledSettingLocked(userState)) {
3867cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
386858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
3869cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mTouchExplorationEnabledUri.equals(uri)) {
3870cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readTouchExplorationEnabledSettingLocked(userState)) {
3871cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
387258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
3873cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mDisplayMagnificationEnabledUri.equals(uri)) {
3874cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readDisplayMagnificationEnabledSettingLocked(userState)) {
3875cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
387658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov                    }
3877cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mEnabledAccessibilityServicesUri.equals(uri)) {
3878cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readEnabledAccessibilityServicesLocked(userState)) {
3879cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
3880447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    }
3881cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) {
3882cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readTouchExplorationGrantedAccessibilityServicesLocked(userState)) {
3883cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
3884447d94684ee73046d769649d8247aacd581bd6e3Svetoslav Ganov                    }
3885cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mEnhancedWebAccessibilityUri.equals(uri)) {
3886cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readEnhancedWebAccessibilityEnabledChangedLocked(userState)) {
3887cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
3888cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    }
3889cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mDisplayInversionEnabledUri.equals(uri)
3890cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        || mDisplayDaltonizerEnabledUri.equals(uri)
3891cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        || mDisplayDaltonizerUri.equals(uri)) {
3892cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readDisplayColorAdjustmentSettingsLocked(userState)) {
3893cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        updateDisplayColorAdjustmentSettingsLocked(userState);
3894cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    }
3895cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                } else if (mHighTextContrastUri.equals(uri)) {
3896cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                    if (readHighTextContrastEnabledSettingLocked(userState)) {
3897cce47eb580d666ead1f6095d1e3b65233592bbaaChris Craik                        onUserStateChangedLocked(userState);
3898410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                    }
3899410d4e33c5542ccdeacdc8d0ac4aa0e194da688aAlan Viverette                }
390058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov            }
390158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov        }
390258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov    }
390375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov}
3904