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; 20e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganovimport static android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; 214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 228643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.Manifest; 2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.AccessibilityService; 2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.AccessibilityServiceInfo; 254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovimport android.accessibilityservice.IAccessibilityServiceClient; 2675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.accessibilityservice.IAccessibilityServiceConnection; 27e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport android.app.AlertDialog; 28dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.app.PendingIntent; 295c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganovimport android.app.StatusBarManager; 3075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.BroadcastReceiver; 3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ComponentName; 3275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ContentResolver; 3375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context; 34e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport android.content.DialogInterface; 35e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport android.content.DialogInterface.OnClickListener; 3675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Intent; 3775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.IntentFilter; 3875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.ServiceConnection; 3975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.PackageManager; 4075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.pm.ResolveInfo; 4153e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganovimport android.content.pm.ServiceInfo; 4275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.database.ContentObserver; 43a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganovimport android.graphics.Point; 447961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganovimport android.graphics.Rect; 45a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganovimport android.hardware.display.DisplayManager; 46005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.hardware.input.InputManager; 4775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.net.Uri; 4875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Binder; 494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovimport android.os.Build; 50aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganovimport android.os.Bundle; 5175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Handler; 5275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.IBinder; 531cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganovimport android.os.Looper; 5475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.Message; 5558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.Process; 5658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.RemoteCallbackList; 5775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.RemoteException; 580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.ServiceManager; 59005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.os.SystemClock; 6058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport android.os.UserHandle; 617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.os.UserManager; 6275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.provider.Settings; 6375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.text.TextUtils; 6475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.text.TextUtils.SimpleStringSplitter; 658a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 6675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.SparseArray; 67a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganovimport android.view.Display; 688643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.IWindow; 69c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.view.IWindowManager; 70005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.view.InputDevice; 71005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.view.KeyCharacterMap; 72005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganovimport android.view.KeyEvent; 731cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganovimport android.view.WindowInfo; 74e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport android.view.WindowManager; 7575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent; 76e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport android.view.accessibility.AccessibilityInteractionClient; 7700aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganovimport android.view.accessibility.AccessibilityManager; 788643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 798643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.IAccessibilityInteractionConnection; 808643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.IAccessibilityInteractionConnectionCallback; 8175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.IAccessibilityManager; 8275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.IAccessibilityManagerClient; 8375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 84e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovimport com.android.internal.R; 858643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport com.android.internal.content.PackageMonitor; 86c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganovimport com.android.internal.statusbar.IStatusBarService; 878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 888643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport org.xmlpull.v1.XmlPullParserException; 898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 90cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganovimport java.io.IOException; 9175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.ArrayList; 9275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Arrays; 9375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.HashMap; 9475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.HashSet; 9521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport java.util.Iterator; 9675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.List; 9775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Map; 9875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport java.util.Set; 9958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganovimport java.util.concurrent.CopyOnWriteArrayList; 10075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov/** 10275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * This class is instantiated by the system as a system level service and can be 10375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * accessed only by the system. The task of this service is to be a centralized 10475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * event dispatch for {@link AccessibilityEvent}s generated across all processes 10575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * on the device. Events are dispatched to {@link AccessibilityService}s. 10675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 10775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @hide 10875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 109e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovpublic class AccessibilityManagerService extends IAccessibilityManager.Stub { 11075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 111736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov private static final boolean DEBUG = false; 112736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 11375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static final String LOG_TAG = "AccessibilityManagerService"; 11475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 1157befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // TODO: This is arbitrary. When there is time implement this by watching 1167befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // when that accessibility services are bound. 11759f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov private static final int WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS = 3000; 1187befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 1190d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = 1200d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov "registerUiTestAutomationService"; 1218643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 1227befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov private static final String TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED = 1237befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov "temporaryEnableAccessibilityStateUntilKeyguardRemoved"; 1247befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 1259a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov private static final char COMPONENT_NAME_SEPARATOR = ':'; 1269a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov 12775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private static final int OWN_PROCESS_ID = android.os.Process.myPid(); 12875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 129fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov private static int sIdCounter = 0; 130fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov 1318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private static int sNextWindowId; 1328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 13358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Context mContext; 13475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 13558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Object mLock = new Object(); 13675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 13758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final SimpleStringSplitter mStringColonSplitter = 13858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); 13975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 14058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final List<AccessibilityServiceInfo> mEnabledServicesForFeedbackTempList = 14158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new ArrayList<AccessibilityServiceInfo>(); 14275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 143a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov private final Rect mTempRect = new Rect(); 144a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov 145a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov private final Point mTempPoint = new Point(); 146a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov 147a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov private final Display mDefaultDisplay; 148a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov 14958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final PackageManager mPackageManager; 15075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final IWindowManager mWindowManagerService; 1529a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov 15358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final SecurityPolicy mSecurityPolicy; 1548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 15558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final MainHandler mMainHandler; 15675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private Service mUiAutomationService; 15875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private Service mQueryBridge; 16075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 16158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private AlertDialog mEnableTouchExplorationDialog; 16235bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov 1630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown private AccessibilityInputFilter mInputFilter; 16475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 16500aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov private boolean mHasInputFilter; 16600aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov 16758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients = 16858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new RemoteCallbackList<IAccessibilityManagerClient>(); 169f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov 17058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final SparseArray<AccessibilityConnectionWrapper> mGlobalInteractionConnections = 17158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new SparseArray<AccessibilityConnectionWrapper>(); 1721cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 17358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final SparseArray<IBinder> mGlobalWindowTokens = new SparseArray<IBinder>(); 1748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 17558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final SparseArray<UserState> mUserStates = new SparseArray<UserState>(); 176e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1777befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov private final TempUserStateChangeMemento mTempStateChangeForCurrentUserMemento = 1787befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov new TempUserStateChangeMemento(); 1797befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 180a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov private int mCurrentUserId = UserHandle.USER_OWNER; 1819b666d0faadd26827ca5b7cf6af3aa94af6adcd9Svetoslav Ganov 18258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private UserState getCurrentUserStateLocked() { 18358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return getUserStateLocked(mCurrentUserId); 18458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 18575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 18658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private UserState getUserStateLocked(int userId) { 18758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState state = mUserStates.get(userId); 18858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (state == null) { 18958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state = new UserState(userId); 19058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mUserStates.put(userId, state); 19158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 19258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return state; 19358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 1949a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov 19575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 19675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Creates a new instance. 19775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 19875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param context A {@link Context} instance. 19975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 2006e6cd7a5660af1a4b5a9ad091c41ef1c72ad2000Jeff Brown public AccessibilityManagerService(Context context) { 20175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mContext = context; 20275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mPackageManager = mContext.getPackageManager(); 20358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mWindowManagerService = (IWindowManager) ServiceManager.getService(Context.WINDOW_SERVICE); 2048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mSecurityPolicy = new SecurityPolicy(); 2051cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mMainHandler = new MainHandler(mContext.getMainLooper()); 206a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov //TODO: (multi-display) We need to support multiple displays. 207a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov DisplayManager displayManager = (DisplayManager) 208a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov mContext.getSystemService(Context.DISPLAY_SERVICE); 209a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); 21058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov registerBroadcastReceivers(); 21158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new AccessibilityContentObserver(mMainHandler).register( 21258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov context.getContentResolver()); 21375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 21475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 21558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void registerBroadcastReceivers() { 21621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn PackageMonitor monitor = new PackageMonitor() { 21775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 21821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void onSomePackagesChanged() { 21975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 22058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (getChangingUserId() != mCurrentUserId) { 22158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 22258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 2234074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov // We will update when the automation service dies. 2244074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov if (mUiAutomationService == null) { 22558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 22658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov populateInstalledAccessibilityServiceLocked(userState); 22758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov manageServicesLocked(userState); 2284074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov } 22921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 23021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 23100aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov 23221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn @Override 233d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov public void onPackageRemoved(String packageName, int uid) { 234d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov synchronized (mLock) { 23558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userId = getChangingUserId(); 23658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userId != mCurrentUserId) { 23758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 23858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 23958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState state = getUserStateLocked(userId); 24058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Iterator<ComponentName> it = state.mEnabledServices.iterator(); 241d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov while (it.hasNext()) { 242d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov ComponentName comp = it.next(); 243d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov String compPkg = comp.getPackageName(); 244d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov if (compPkg.equals(packageName)) { 245d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov it.remove(); 2469a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov // Update the enabled services setting. 2479a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov persistComponentNamesToSettingLocked( 2489a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, 24958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mEnabledServices, userId); 2509a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov // Update the touch exploration granted services setting. 25158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mTouchExplorationGrantedServices.remove(comp); 2529a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov persistComponentNamesToSettingLocked( 2539a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov Settings.Secure. 2549a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, 25558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mEnabledServices, userId); 256d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov return; 257d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov } 258d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov } 259d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov } 260d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov } 261d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov 262d07d60b9bc0fd2e88f58d6e68dbfadad1bdd31cfSvetoslav Ganov @Override 26321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean onHandleForceStop(Intent intent, String[] packages, 26421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn int uid, boolean doit) { 26521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (mLock) { 26658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userId = getChangingUserId(); 26758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userId != mCurrentUserId) { 26858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return false; 26958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 27058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState state = getUserStateLocked(userId); 27158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Iterator<ComponentName> it = state.mEnabledServices.iterator(); 27221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn while (it.hasNext()) { 27321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName comp = it.next(); 27421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String compPkg = comp.getPackageName(); 27521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String pkg : packages) { 27621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (compPkg.equals(pkg)) { 27721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (!doit) { 27821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 27921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 28021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn it.remove(); 2819a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov persistComponentNamesToSettingLocked( 2829a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, 28358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mEnabledServices, userId); 28421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 28521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 28621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 28721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 28821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 28921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 29075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov }; 29175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 29275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // package changes 29358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov monitor.register(mContext, null, UserHandle.ALL, true); 29475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 2957befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // user change and unlock 2967befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov IntentFilter intentFilter = new IntentFilter(); 2977befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 2987befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov intentFilter.addAction(Intent.ACTION_USER_REMOVED); 2997befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov intentFilter.addAction(Intent.ACTION_USER_PRESENT); 30075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 3017befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mContext.registerReceiverAsUser(new BroadcastReceiver() { 30258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov @Override 30358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void onReceive(Context context, Intent intent) { 30458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov String action = intent.getAction(); 30558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (Intent.ACTION_USER_SWITCHED.equals(action)) { 30658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); 30758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 30858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); 3097befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } else if (Intent.ACTION_USER_PRESENT.equals(action)) { 3107befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov restoreStateFromMementoIfNeeded(); 31175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 31258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 3137befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov }, UserHandle.ALL, intentFilter, null, null); 31475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 31575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 31658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public int addClient(IAccessibilityManagerClient client, int userId) { 31775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 31858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 31958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked(userId); 32058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // If the client is from a process that runs across users such as 32158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // the system UI or the system we add it to the global state that 32258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // is shared across users. 32358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(resolvedUserId); 32458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) { 32558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mGlobalClients.register(client); 326a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (DEBUG) { 327a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid()); 328a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 32958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return getClientState(userState); 33058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else { 33158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mClients.register(client); 33258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // If this client is not for the current user we do not 33358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // return a state since it is not for the foreground user. 33458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // We will send the state to the client on a user switch. 335a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (DEBUG) { 336a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid() 337a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov + " and userId:" + mCurrentUserId); 338a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 33958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return (resolvedUserId == mCurrentUserId) ? getClientState(userState) : 0; 34058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 34175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 34275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 34375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 34458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public boolean sendAccessibilityEvent(AccessibilityEvent event, int userId) { 34575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 34658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 34758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked(userId); 34858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // This method does nothing for a background user. 34958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 35058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return true; // yes, recycle the event 35158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 352eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) { 353a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov mSecurityPolicy.updateEventSourceLocked(event); 354a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_ACTIVE_WINDOW, 355a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov event.getWindowId(), event.getEventType()).sendToTarget(); 356eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov notifyAccessibilityServicesDelayedLocked(event, false); 357eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov notifyAccessibilityServicesDelayedLocked(event, true); 358eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov } 35986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov if (mHasInputFilter && mInputFilter != null) { 36058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mMainHandler.obtainMessage(MainHandler.MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER, 361e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov AccessibilityEvent.obtain(event)).sendToTarget(); 36286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov } 363cd94caf2bb94f07522ea5bbf0e37dea960b38220Svetoslav Ganov event.recycle(); 36458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov getUserStateLocked(resolvedUserId).mHandledFeedbackTypes = 0; 36575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 36675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return (OWN_PROCESS_ID != Binder.getCallingPid()); 36775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 36875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 36958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) { 37075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 37158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 37258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked(userId); 37358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return getUserStateLocked(resolvedUserId).mInstalledServices; 37475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 37575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 37675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 37758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, 37858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov int userId) { 37958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov List<AccessibilityServiceInfo> result = null; 380736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov synchronized (mLock) { 38158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 38258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked(userId); 38358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov result = mEnabledServicesForFeedbackTempList; 38458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov result.clear(); 38558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov List<Service> services = getUserStateLocked(resolvedUserId).mServices; 386cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov while (feedbackType != 0) { 387cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackType)); 388cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov feedbackType &= ~feedbackTypeBit; 389f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov final int serviceCount = services.size(); 390f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov for (int i = 0; i < serviceCount; i++) { 391f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov Service service = services.get(i); 392c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov if ((service.mFeedbackType & feedbackTypeBit) != 0) { 393f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov result.add(service.mAccessibilityServiceInfo); 394f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov } 395cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } 396736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 397736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 398f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov return result; 399736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 400736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 40158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void interrupt(int userId) { 40258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov CopyOnWriteArrayList<Service> services; 40375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 40458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 40558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked(userId); 40658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // This method does nothing for a background user. 40758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 40858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 40958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 41058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov services = getUserStateLocked(resolvedUserId).mServices; 41158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 41258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0, count = services.size(); i < count; i++) { 41358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Service service = services.get(i); 41458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov try { 41558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov service.mServiceInterface.onInterrupt(); 41658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } catch (RemoteException re) { 41758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Slog.e(LOG_TAG, "Error during sending interrupt request to " 41858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov + service.mService, re); 41975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 42075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 42175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 42275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 4238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public int addAccessibilityInteractionConnection(IWindow windowToken, 42458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IAccessibilityInteractionConnection connection, int userId) throws RemoteException { 4258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 42658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 42758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked(userId); 4288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final int windowId = sNextWindowId++; 42958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // If the window is from a process that runs across users such as 43058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // the system UI or the system we add it to the global state that 43158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // is shared across users. 43258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) { 43358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper( 43458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov windowId, connection, UserHandle.USER_ALL); 43558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov wrapper.linkToDeath(); 43658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mGlobalInteractionConnections.put(windowId, wrapper); 43758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mGlobalWindowTokens.put(windowId, windowToken.asBinder()); 438a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (DEBUG) { 439a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov Slog.i(LOG_TAG, "Added global connection for pid:" + Binder.getCallingPid() 440a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov + " with windowId: " + windowId); 441a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 44258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else { 44358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper( 44458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov windowId, connection, resolvedUserId); 44558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov wrapper.linkToDeath(); 44658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(resolvedUserId); 44758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mInteractionConnections.put(windowId, wrapper); 44858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mWindowTokens.put(windowId, windowToken.asBinder()); 449a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (DEBUG) { 450a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov Slog.i(LOG_TAG, "Added user connection for pid:" + Binder.getCallingPid() 451a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov + " with windowId: " + windowId + " and userId:" + mCurrentUserId); 452a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 45358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 4548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (DEBUG) { 4558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Slog.i(LOG_TAG, "Adding interaction connection to windowId: " + windowId); 4568643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4578643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return windowId; 4588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 46158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void removeAccessibilityInteractionConnection(IWindow window) { 4628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 46358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked( 46458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 46558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IBinder token = window.asBinder(); 466a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked( 46758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov token, mGlobalWindowTokens, mGlobalInteractionConnections); 468a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (removedWindowId >= 0) { 469a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (DEBUG) { 470a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid() 471a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov + " with windowId: " + removedWindowId); 472a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 47358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 47458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 47558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userCount = mUserStates.size(); 47658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0; i < userCount; i++) { 47758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = mUserStates.valueAt(i); 478a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov final int removedWindowIdForUser = 47958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov removeAccessibilityInteractionConnectionInternalLocked( 48058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov token, userState.mWindowTokens, userState.mInteractionConnections); 481a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (removedWindowIdForUser >= 0) { 482a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (DEBUG) { 483a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid() 484a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov + " with windowId: " + removedWindowIdForUser + " and userId:" 485a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov + mUserStates.keyAt(i)); 486a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 4878643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return; 4888643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4898643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 4928643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 493a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov private int removeAccessibilityInteractionConnectionInternalLocked(IBinder windowToken, 49458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov SparseArray<IBinder> windowTokens, 49558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov SparseArray<AccessibilityConnectionWrapper> interactionConnections) { 49658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int count = windowTokens.size(); 49758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0; i < count; i++) { 49858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (windowTokens.valueAt(i) == windowToken) { 49958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int windowId = windowTokens.keyAt(i); 50058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov windowTokens.removeAt(i); 50158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId); 50258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov wrapper.unlinkToDeath(); 50358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov interactionConnections.remove(windowId); 504a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov return windowId; 50558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 50658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 507a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov return -1; 50858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 50958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 5104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov public void registerUiTestAutomationService(IAccessibilityServiceClient serviceClient, 51179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov AccessibilityServiceInfo accessibilityServiceInfo) { 5128643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT, 5130d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE); 514e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov ComponentName componentName = new ComponentName("foo.bar", 515e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov "AutomationAccessibilityService"); 5168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 517b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // If an automation services is connected to the system all services are stopped 518b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // so the automation one is the only one running. Settings are not changed so when 519b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // the automation service goes away the state is restored from the settings. 52058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 52158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov unbindAllServicesLocked(userState); 522b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov 523b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // If necessary enable accessibility and announce that. 52458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (!userState.mIsAccessibilityEnabled) { 52558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mIsAccessibilityEnabled = true; 5268643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 527657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov // No touch exploration. 528657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov userState.mIsTouchExplorationEnabled = false; 529657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov 530657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov // Hook the automation service up. 531657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov mUiAutomationService = new Service(mCurrentUserId, componentName, 532657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov accessibilityServiceInfo, true); 533657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov mUiAutomationService.onServiceConnected(componentName, serviceClient.asBinder()); 534657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov 535657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov updateInputFilterLocked(userState); 536657968a65f29e9319c39b833fefc2ae7472c3e53Svetoslav Ganov scheduleSendStateToClientsLocked(userState); 5378643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 538d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 539d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 5407befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public void temporaryEnableAccessibilityStateUntilKeyguardRemoved( 5417befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov ComponentName service, boolean touchExplorationEnabled) { 5427befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mSecurityPolicy.enforceCallingPermission( 5437befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov Manifest.permission.TEMPORARY_ENABLE_ACCESSIBILITY, 5447befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED); 5457befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov try { 5467befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov if (!mWindowManagerService.isKeyguardLocked()) { 5477befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov return; 5487befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 5497befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } catch (RemoteException re) { 5507befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov return; 5517befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 5527befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov synchronized (mLock) { 5537befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov UserState userState = getCurrentUserStateLocked(); 5547befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // Stash the old state so we can restore it when the keyguard is gone. 5557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTempStateChangeForCurrentUserMemento.initialize(mCurrentUserId, getCurrentUserStateLocked()); 5567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // Set the temporary state. 5577befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mIsAccessibilityEnabled = true; 5587befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mIsTouchExplorationEnabled= touchExplorationEnabled; 5597befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mIsDisplayMagnificationEnabled = false; 5607befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mEnabledServices.clear(); 5617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mEnabledServices.add(service); 5627befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mTouchExplorationGrantedServices.clear(); 5637befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mTouchExplorationGrantedServices.add(service); 5647befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // Update the internal state. 5657befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov performServiceManagementLocked(userState); 5667befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov updateInputFilterLocked(userState); 5677befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov scheduleSendStateToClientsLocked(userState); 5687befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 5697befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 5707befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 5714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov public void unregisterUiTestAutomationService(IAccessibilityServiceClient serviceClient) { 57279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov synchronized (mLock) { 5739b666d0faadd26827ca5b7cf6af3aa94af6adcd9Svetoslav Ganov // Automation service is not bound, so pretend it died to perform clean up. 5747fd9882ba3e97423901e06188c6dbaaca661ecbdSvetoslav Ganov if (mUiAutomationService != null && mUiAutomationService.mServiceInterface != null 5757fd9882ba3e97423901e06188c6dbaaca661ecbdSvetoslav Ganov && serviceClient != null && mUiAutomationService.mServiceInterface 5767fd9882ba3e97423901e06188c6dbaaca661ecbdSvetoslav Ganov .asBinder() == serviceClient.asBinder()) { 5779b666d0faadd26827ca5b7cf6af3aa94af6adcd9Svetoslav Ganov mUiAutomationService.binderDied(); 57879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 57979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 58079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 58179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov 582e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov boolean onGesture(int gestureId) { 5834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov synchronized (mLock) { 584fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov boolean handled = notifyGestureLocked(gestureId, false); 585fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov if (!handled) { 586fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov handled = notifyGestureLocked(gestureId, true); 5874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 588fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov return handled; 589fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov } 590fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov } 591fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov 592e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov /** 59386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov * Gets the bounds of the accessibility focus in the active window. 594e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * 595e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * @param outBounds The output to which to write the focus bounds. 59686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov * @return Whether accessibility focus was found and the bounds are populated. 597e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov */ 598a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov // TODO: (multi-display) Make sure this works for multiple displays. 59986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov boolean getAccessibilityFocusBoundsInActiveWindow(Rect outBounds) { 600e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // Instead of keeping track of accessibility focus events per 601e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // window to be able to find the focus in the active window, 602e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // we take a stateless approach and look it up. This is fine 603e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // since we do this only when the user clicks/long presses. 604e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov Service service = getQueryBridge(); 605e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int connectionId = service.mId; 606e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); 607e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov client.addConnection(connectionId, service); 608e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov try { 609e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance() 610e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov .getRootInActiveWindow(connectionId); 611e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (root == null) { 612e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return false; 613e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 614e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityNodeInfo focus = root.findFocus( 615e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); 616e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (focus == null) { 617e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return false; 618e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 619e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov focus.getBoundsInScreen(outBounds); 620a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov // Clip to the window rectangle. 621a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov Rect windowBounds = mTempRect; 622a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov getActiveWindowBounds(windowBounds); 623a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov outBounds.intersect(windowBounds); 624a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov // Clip to the screen rectangle. 625a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov mDefaultDisplay.getRealSize(mTempPoint); 626a94c3194ffa896632f025b983ca57095cd4ba277Svetoslav Ganov outBounds.intersect(0, 0, mTempPoint.x, mTempPoint.y); 627e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return true; 628e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } finally { 629e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov client.removeConnection(connectionId); 630e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 631e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 632e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 63386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov /** 63486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov * Gets the bounds of the active window. 63586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov * 63686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov * @param outBounds The output to which to write the bounds. 63786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov */ 638c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov boolean getActiveWindowBounds(Rect outBounds) { 63958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IBinder token; 64086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov synchronized (mLock) { 64186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov final int windowId = mSecurityPolicy.mActiveWindowId; 64258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov token = mGlobalWindowTokens.get(windowId); 64358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (token == null) { 64458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov token = getCurrentUserStateLocked().mWindowTokens.get(windowId); 64558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 64658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 64758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov WindowInfo info = null; 64858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov try { 64958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov info = mWindowManagerService.getWindowInfo(token); 65058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (info != null) { 65158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov outBounds.set(info.frame); 65258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return true; 65358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 65458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } catch (RemoteException re) { 65558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov /* ignore */ 65658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } finally { 65758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (info != null) { 65858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov info.recycle(); 659c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 66086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov } 66158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return false; 66286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov } 66386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov 66458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov int getActiveWindowId() { 665385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov return mSecurityPolicy.mActiveWindowId; 666385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov } 667385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov 6686ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov void onTouchInteractionStart() { 6696ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov mSecurityPolicy.onTouchInteractionStart(); 6706ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov } 6716ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov 672f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov void onTouchInteractionEnd() { 673f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov mSecurityPolicy.onTouchInteractionEnd(); 674f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov } 675f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov 67658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void switchUser(int userId) { 67758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 6787befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // The user switched so we do not need to restore the current user 6797befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // state since we will fully rebuild it when he becomes current again. 6807befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTempStateChangeForCurrentUserMemento.clear(); 68158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 68258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // Disconnect from services for the old user. 68358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState oldUserState = getUserStateLocked(mCurrentUserId); 68458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov unbindAllServicesLocked(oldUserState); 68558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 68658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // Disable the local managers for the old user. 68758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (oldUserState.mClients.getRegisteredCallbackCount() > 0) { 68858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER, 68958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov oldUserState.mUserId, 0).sendToTarget(); 69058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 69158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 69259f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov // Announce user changes only if more that one exist. 69359f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 69459f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov final boolean announceNewUser = userManager.getUsers().size() > 1; 69559f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov 69658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // The user changed. 69758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mCurrentUserId = userId; 69858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 69958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // Recreate the internal state for the new user. 70058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mMainHandler.obtainMessage(MainHandler.MSG_SEND_RECREATE_INTERNAL_STATE, 70158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mCurrentUserId, 0).sendToTarget(); 7027befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 70359f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov if (announceNewUser) { 70459f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov // Schedule announcement of the current user if needed. 70559f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED, 70659f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS); 70759f07690c2bdd97b9e486b776d2175d914818d06Svetoslav Ganov } 70858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 70958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 71058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 71158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void removeUser(int userId) { 71258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 71358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mUserStates.remove(userId); 71458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 71558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 71658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 7177befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov private void restoreStateFromMementoIfNeeded() { 7187befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov synchronized (mLock) { 7197befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov if (mTempStateChangeForCurrentUserMemento.mUserId != UserHandle.USER_NULL) { 7207befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov UserState userState = getCurrentUserStateLocked(); 7217befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // Restore the state from the memento. 7227befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTempStateChangeForCurrentUserMemento.applyTo(userState); 7237befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTempStateChangeForCurrentUserMemento.clear(); 7247befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov // Update the internal state. 7257befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov performServiceManagementLocked(userState); 7267befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov updateInputFilterLocked(userState); 7277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov scheduleSendStateToClientsLocked(userState); 7287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 7297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 7307befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 7317befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 732e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private Service getQueryBridge() { 733e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (mQueryBridge == null) { 734e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityServiceInfo info = new AccessibilityServiceInfo(); 73558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mQueryBridge = new Service(UserHandle.USER_NULL, null, info, true); 736e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 737e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return mQueryBridge; 738e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 739e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 7404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov private boolean notifyGestureLocked(int gestureId, boolean isDefault) { 741fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // TODO: Now we are giving the gestures to the last enabled 742fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // service that can handle them which is the last one 743fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // in our list since we write the last enabled as the 744fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // last record in the enabled services setting. Ideally, 745fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // the user should make the call which service handles 746fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // gestures. However, only one service should handle 747e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov // gestures to avoid user frustration when different 748e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov // behavior is observed from different combinations of 749fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov // enabled accessibility services. 75058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState state = getCurrentUserStateLocked(); 75158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = state.mServices.size() - 1; i >= 0; i--) { 75258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Service service = state.mServices.get(i); 753a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov if (service.mRequestTouchExplorationMode && service.mIsDefault == isDefault) { 754e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov service.notifyGesture(gestureId); 755fefd20e927b7252d63acb7bb1852c5188e3c1b2eSvetoslav Ganov return true; 7564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 7574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 7584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return false; 7594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 7604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 761d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov /** 762d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov * Removes an AccessibilityInteractionConnection. 763d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov * 764d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov * @param windowId The id of the window to which the connection is targeted. 76558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * @param userId The id of the user owning the connection. UserHandle.USER_ALL 76658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * if global. 767d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov */ 76858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void removeAccessibilityInteractionConnectionLocked(int windowId, int userId) { 76958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userId == UserHandle.USER_ALL) { 77058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mGlobalWindowTokens.remove(windowId); 77158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mGlobalInteractionConnections.remove(windowId); 77258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else { 77358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 77458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mWindowTokens.remove(windowId); 77558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mInteractionConnections.remove(windowId); 77658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 777d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov if (DEBUG) { 778d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId); 779d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 7808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 7818643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 78258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void populateInstalledAccessibilityServiceLocked(UserState userState) { 78358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mInstalledServices.clear(); 78475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 78558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov List<ResolveInfo> installedServices = mPackageManager.queryIntentServicesAsUser( 786cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov new Intent(AccessibilityService.SERVICE_INTERFACE), 78758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, 78858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mCurrentUserId); 78975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 79075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = installedServices.size(); i < count; i++) { 791cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov ResolveInfo resolveInfo = installedServices.get(i); 79253e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov ServiceInfo serviceInfo = resolveInfo.serviceInfo; 79358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (!android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE.equals( 79458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov serviceInfo.permission)) { 79553e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov Slog.w(LOG_TAG, "Skipping accessibilty service " + new ComponentName( 79653e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov serviceInfo.packageName, serviceInfo.name).flattenToShortString() 79753e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov + ": it does not require the permission " 79853e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov + android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE); 79953e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov continue; 80053e184d34e7c5b1a65c74fac55f9a635d8131ddaSvetoslav Ganov } 801cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov AccessibilityServiceInfo accessibilityServiceInfo; 802cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov try { 803cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext); 80458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mInstalledServices.add(accessibilityServiceInfo); 805cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } catch (XmlPullParserException xppe) { 806cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe); 807cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } catch (IOException ioe) { 808cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", ioe); 809cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } 81075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 81175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 81275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 81358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void populateEnabledAccessibilityServicesLocked(UserState userState) { 8149a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov populateComponentNamesFromSettingLocked( 8159a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, 81658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mUserId, 81758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mEnabledServices); 8189a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 8199a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov 82058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void populateTouchExplorationGrantedAccessibilityServicesLocked( 82158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState) { 8229a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov populateComponentNamesFromSettingLocked( 8239a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, 82458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mUserId, 82558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mTouchExplorationGrantedServices); 8269a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 8279a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov 82875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 82975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Performs {@link AccessibilityService}s delayed notification. The delay is configurable 83075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * and denotes the period after the last event before notifying the service. 83175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 83275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param event The event. 83375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param isDefault True to notify default listeners, not default services. 83475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 83575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event, 83675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean isDefault) { 83785b598beda98706fafd05c7de9866d83d4a19965Charles Chen try { 83858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState state = getCurrentUserStateLocked(); 83958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0, count = state.mServices.size(); i < count; i++) { 84058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Service service = state.mServices.get(i); 84175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 84285b598beda98706fafd05c7de9866d83d4a19965Charles Chen if (service.mIsDefault == isDefault) { 84358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (canDispathEventLocked(service, event, state.mHandledFeedbackTypes)) { 84458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mHandledFeedbackTypes |= service.mFeedbackType; 845e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov service.notifyAccessibilityEvent(event); 84685b598beda98706fafd05c7de9866d83d4a19965Charles Chen } 84775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 84875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 84985b598beda98706fafd05c7de9866d83d4a19965Charles Chen } catch (IndexOutOfBoundsException oobe) { 85085b598beda98706fafd05c7de9866d83d4a19965Charles Chen // An out of bounds exception can happen if services are going away 85185b598beda98706fafd05c7de9866d83d4a19965Charles Chen // as the for loop is running. If that happens, just bail because 85285b598beda98706fafd05c7de9866d83d4a19965Charles Chen // there are no more services to notify. 85385b598beda98706fafd05c7de9866d83d4a19965Charles Chen return; 85475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 85575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 85675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 85775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 85858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * Adds a service for a user. 859f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov * 860f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov * @param service The service to add. 86158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * @param userId The user id. 862f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov */ 86358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void tryAddServiceLocked(Service service, int userId) { 864f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov try { 86558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(userId); 8661f22b6a25d7df6c5488d9bd01793e7a20d921349Svetoslav Ganov if (userState.mServices.contains(service)) { 867f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov return; 86875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 869f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov service.linkToOwnDeath(); 87058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mServices.add(service); 87158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mComponentNameToServiceMap.put(service.mComponentName, service); 87258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov updateInputFilterLocked(userState); 8739a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov tryEnableTouchExplorationLocked(service); 874f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov } catch (RemoteException e) { 875f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov /* do nothing */ 87675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 87775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 87875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 87975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 880f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov * Removes a service. 88175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 88275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param service The service. 88375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @return True if the service was removed, false otherwise. 88475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 885f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov private boolean tryRemoveServiceLocked(Service service) { 88658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(service.mUserId); 88758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final boolean removed = userState.mServices.remove(service); 888f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov if (!removed) { 889f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov return false; 89075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 89158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mComponentNameToServiceMap.remove(service.mComponentName); 892f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov service.unlinkToOwnDeath(); 893d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov service.dispose(); 89458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov updateInputFilterLocked(userState); 8959a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov tryDisableTouchExplorationLocked(service); 896f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov return removed; 89775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 89875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 89975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 90075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Determines if given event can be dispatched to a service based on the package of the 90175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * event source and already notified services for that event type. Specifically, a 90275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * service is notified if it is interested in events from the package and no other service 90375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * providing the same feedback type has been notified. Exception are services the 90475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * provide generic feedback (feedback type left as a safety net for unforeseen feedback 90575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * types) which are always notified. 90675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 90775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param service The potential receiver. 90875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param event The event. 90975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @param handledFeedbackTypes The feedback types for which services have been notified. 91075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * @return True if the listener should be notified, false otherwise. 91175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 91275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov private boolean canDispathEventLocked(Service service, AccessibilityEvent event, 91375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int handledFeedbackTypes) { 91475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 9151f22b6a25d7df6c5488d9bd01793e7a20d921349Svetoslav Ganov if (!service.canReceiveEvents()) { 91675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 91775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 91875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 9194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (!event.isImportantForAccessibility() 9204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov && !service.mIncludeNotImportantViews) { 9214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return false; 9224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 9234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 92475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int eventType = event.getEventType(); 92575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if ((service.mEventTypes & eventType) != eventType) { 92675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 92775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 92875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 92975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Set<String> packageNames = service.mPackageNames; 93075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov CharSequence packageName = event.getPackageName(); 93175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 93275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (packageNames.isEmpty() || packageNames.contains(packageName)) { 93375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int feedbackType = service.mFeedbackType; 93475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if ((handledFeedbackTypes & feedbackType) != feedbackType 93575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov || feedbackType == AccessibilityServiceInfo.FEEDBACK_GENERIC) { 93675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return true; 93775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 93875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 93975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 94075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov return false; 94175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 94275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 94375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 94475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Manages services by starting enabled ones and stopping disabled ones. 94575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 94658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void manageServicesLocked(UserState userState) { 94758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int enabledInstalledServicesCount = updateServicesStateLocked(userState); 9481e741b2705023be64389ac3e31c5f63d330470a5Svetoslav Ganov // No enabled installed services => disable accessibility to avoid 949b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // sending accessibility events with no recipient across processes. 95058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsAccessibilityEnabled && enabledInstalledServicesCount == 0) { 95158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.putIntForUser(mContext.getContentResolver(), 95258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId); 9531e741b2705023be64389ac3e31c5f63d330470a5Svetoslav Ganov } 95475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 95575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 95675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 95758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * Unbinds all bound services for a user. 95858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * 95958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * @param userState The user state. 96075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 96158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void unbindAllServicesLocked(UserState userState) { 96258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov List<Service> services = userState.mServices; 96375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov for (int i = 0, count = services.size(); i < count; i++) { 96475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = services.get(i); 9656ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov if (service.unbind()) { 9666ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov i--; 9676ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov count--; 9686ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov } 96975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 97075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 97175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 97275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 9739a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * Populates a set with the {@link ComponentName}s stored in a colon 97458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * separated value setting for a given user. 97575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 9769a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * @param settingName The setting to parse. 97758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * @param userId The user id. 9789a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * @param outComponentNames The output component names. 97975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 98058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void populateComponentNamesFromSettingLocked(String settingName, int userId, 9819a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov Set<ComponentName> outComponentNames) { 98258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(), 98358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov settingName, userId); 9849a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov outComponentNames.clear(); 9859a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov if (settingValue != null) { 98675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; 9879a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov splitter.setString(settingValue); 98875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov while (splitter.hasNext()) { 98921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String str = splitter.next(); 99021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (str == null || str.length() <= 0) { 99121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn continue; 99221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 99321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName enabledService = ComponentName.unflattenFromString(str); 99421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (enabledService != null) { 9959a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov outComponentNames.add(enabledService); 99621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 99775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 99875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 99975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 100075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 100175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 10029a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * Persists the component names in the specified setting in a 10039a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * colon separated fashion. 10049a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * 10059a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * @param settingName The setting name. 10069a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov * @param componentNames The component names. 10079a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov */ 10089a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov private void persistComponentNamesToSettingLocked(String settingName, 100958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Set<ComponentName> componentNames, int userId) { 10109a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov StringBuilder builder = new StringBuilder(); 10119a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov for (ComponentName componentName : componentNames) { 10129a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov if (builder.length() > 0) { 10139a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov builder.append(COMPONENT_NAME_SEPARATOR); 10149a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 10159a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov builder.append(componentName.flattenToShortString()); 10169a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 101758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.putStringForUser(mContext.getContentResolver(), 101858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov settingName, builder.toString(), userId); 10199a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 10209a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov 10219a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov /** 102275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Updates the state of each service by starting (or keeping running) enabled ones and 102375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * stopping the rest. 102475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * 102558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov * @param userState The user state for which to do that. 10261e741b2705023be64389ac3e31c5f63d330470a5Svetoslav Ganov * @return The number of enabled installed services. 102775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 102858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private int updateServicesStateLocked(UserState userState) { 102958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Map<ComponentName, Service> componentNameToServiceMap = 103058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mComponentNameToServiceMap; 103158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov boolean isEnabled = userState.mIsAccessibilityEnabled; 103275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10331e741b2705023be64389ac3e31c5f63d330470a5Svetoslav Ganov int enabledInstalledServices = 0; 103458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) { 103558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i); 1036cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov ComponentName componentName = ComponentName.unflattenFromString( 1037cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov installedService.getId()); 103875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Service service = componentNameToServiceMap.get(componentName); 103975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 1040f2245aa5d7f5d6f0ea6d55fb2acc66624b2ef13fSvetoslav Ganov if (isEnabled) { 104158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mEnabledServices.contains(componentName)) { 1042563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov if (service == null) { 104358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov service = new Service(userState.mUserId, componentName, 104458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov installedService, false); 1045563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov } 1046563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov service.bind(); 10471e741b2705023be64389ac3e31c5f63d330470a5Svetoslav Ganov enabledInstalledServices++; 104835bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov } else { 1049563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov if (service != null) { 1050563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov service.unbind(); 1051563d78401dc6ed58dd606ac744555151f1cc0ef1Svetoslav Ganov } 105275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 105375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 105475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (service != null) { 105575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov service.unbind(); 105675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 105775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 105875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 105975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 10601e741b2705023be64389ac3e31c5f63d330470a5Svetoslav Ganov return enabledInstalledServices; 106137fedf8b78dea969b97188fd3079fea5e71704beSvetoslav Ganov } 106237fedf8b78dea969b97188fd3079fea5e71704beSvetoslav Ganov 106358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void scheduleSendStateToClientsLocked(UserState userState) { 106458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mGlobalClients.getRegisteredCallbackCount() > 0 106558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || userState.mClients.getRegisteredCallbackCount() > 0) { 106658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int clientState = getClientState(userState); 106758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS, 106858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov clientState, userState.mUserId) .sendToTarget(); 106958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 107058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 107158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 107258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void updateInputFilterLocked(UserState userState) { 107358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov boolean setInputFilter = false; 107458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityInputFilter inputFilter = null; 107558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 107658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if ((userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) 107758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || userState.mIsDisplayMagnificationEnabled) { 107858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (!mHasInputFilter) { 107958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mHasInputFilter = true; 108058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mInputFilter == null) { 108158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mInputFilter = new AccessibilityInputFilter(mContext, 108258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityManagerService.this); 108358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 108458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov inputFilter = mInputFilter; 108558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov setInputFilter = true; 108658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 108758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov int flags = 0; 108858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsDisplayMagnificationEnabled) { 108958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER; 109058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 109158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsTouchExplorationEnabled) { 109258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION; 109358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 109458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mInputFilter.setEnabledFeatures(flags); 109558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else { 109658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mHasInputFilter) { 109758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mHasInputFilter = false; 109858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mInputFilter.setEnabledFeatures(0); 109958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov inputFilter = null; 110058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov setInputFilter = true; 110158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 110258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 110358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 110458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (setInputFilter) { 110575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 110658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mWindowManagerService.setInputFilter(inputFilter); 110775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 110858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov /* ignore */ 110975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 111075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 111175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 111275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 111358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void showEnableTouchExplorationDialog(final Service service) { 111458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov String label = service.mResolveInfo.loadLabel( 111558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mContext.getPackageManager()).toString(); 111658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 111758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final UserState state = getCurrentUserStateLocked(); 111858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (state.mIsTouchExplorationEnabled) { 111958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 112058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 112158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mEnableTouchExplorationDialog != null 112258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov && mEnableTouchExplorationDialog.isShowing()) { 112358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 112458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 112558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext) 112658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .setIcon(android.R.drawable.ic_dialog_alert) 112758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .setPositiveButton(android.R.string.ok, new OnClickListener() { 112858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov @Override 112958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void onClick(DialogInterface dialog, int which) { 113058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // The user allowed the service to toggle touch exploration. 113158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mTouchExplorationGrantedServices.add(service.mComponentName); 113258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov persistComponentNamesToSettingLocked( 113358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, 113458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov state.mTouchExplorationGrantedServices, state.mUserId); 113558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // Enable touch exploration. 113658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.putIntForUser(mContext.getContentResolver(), 113758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, 113858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov service.mUserId); 113958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 114058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov }) 114158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .setNegativeButton(android.R.string.cancel, new OnClickListener() { 114258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov @Override 114358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void onClick(DialogInterface dialog, int which) { 114458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov dialog.dismiss(); 114558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 114658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov }) 114758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .setTitle(R.string.enable_explore_by_touch_warning_title) 114858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .setMessage(mContext.getString( 114958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov R.string.enable_explore_by_touch_warning_message, label)) 115058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .create(); 115158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mEnableTouchExplorationDialog.getWindow().setType( 1152318b00bfeefa6dc05913c8eea0052d70185c7910Svetoslav Ganov WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 1153318b00bfeefa6dc05913c8eea0052d70185c7910Svetoslav Ganov mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags 1154318b00bfeefa6dc05913c8eea0052d70185c7910Svetoslav Ganov |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 115558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true); 115658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mEnableTouchExplorationDialog.show(); 115700aabf7d187bc05408199bd687a538b2e68bdc17Svetoslav Ganov } 115835bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov } 115935bfedeaba724aeadc6f6c890269cb6bf7ef42f5Svetoslav Ganov 116058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private int getClientState(UserState userState) { 116158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov int clientState = 0; 116258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsAccessibilityEnabled) { 116358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED; 116458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 116558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // Touch exploration relies on enabled accessibility. 116658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) { 116758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov clientState |= AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED; 116858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 116958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return clientState; 11701cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 11711cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 117258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void recreateInternalStateLocked(UserState userState) { 117358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov populateInstalledAccessibilityServiceLocked(userState); 117458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov populateEnabledAccessibilityServicesLocked(userState); 117558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov populateTouchExplorationGrantedAccessibilityServicesLocked(userState); 11761cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 117758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleTouchExplorationEnabledSettingChangedLocked(userState); 117858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleDisplayMagnificationEnabledSettingChangedLocked(userState); 117958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleAccessibilityEnabledSettingChangedLocked(userState); 11801cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 11817befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov performServiceManagementLocked(userState); 118258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov updateInputFilterLocked(userState); 118358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov scheduleSendStateToClientsLocked(userState); 11840029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 11850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 118658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void handleAccessibilityEnabledSettingChangedLocked(UserState userState) { 118758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mIsAccessibilityEnabled = Settings.Secure.getIntForUser( 118858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mContext.getContentResolver(), 118958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId) == 1; 11907befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 11917befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 11927befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov private void performServiceManagementLocked(UserState userState) { 119358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsAccessibilityEnabled ) { 119458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov manageServicesLocked(userState); 1195b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov } else { 119658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov unbindAllServicesLocked(userState); 1197b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov } 11980d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov } 11990d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov 120058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void handleTouchExplorationEnabledSettingChangedLocked(UserState userState) { 120158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mIsTouchExplorationEnabled = Settings.Secure.getIntForUser( 12020d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov mContext.getContentResolver(), 120358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId) == 1; 1204b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov } 1205b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov 120658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void handleDisplayMagnificationEnabledSettingChangedLocked(UserState userState) { 120758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mIsDisplayMagnificationEnabled = Settings.Secure.getIntForUser( 12081cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mContext.getContentResolver(), 120958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 121058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 0, userState.mUserId) == 1; 12111cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 12121cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 121358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void handleTouchExplorationGrantedAccessibilityServicesChangedLocked( 121458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState) { 121558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int serviceCount = userState.mServices.size(); 1216a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov for (int i = 0; i < serviceCount; i++) { 121758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Service service = userState.mServices.get(i); 1218a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov if (service.mRequestTouchExplorationMode 121958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov && userState.mTouchExplorationGrantedServices.contains( 122058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov service.mComponentName)) { 1221a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov tryEnableTouchExplorationLocked(service); 1222a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov return; 1223a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov } 1224a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov } 122558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsTouchExplorationEnabled) { 122658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.putIntForUser(mContext.getContentResolver(), 122758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId); 1228a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov } 1229a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov } 1230a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov 12319a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov private void tryEnableTouchExplorationLocked(final Service service) { 123258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(service.mUserId); 12331f22b6a25d7df6c5488d9bd01793e7a20d921349Svetoslav Ganov if (!userState.mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode 12341f22b6a25d7df6c5488d9bd01793e7a20d921349Svetoslav Ganov && service.canReceiveEvents()) { 123558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final boolean canToggleTouchExploration = 123658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState.mTouchExplorationGrantedServices.contains(service.mComponentName); 12379a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov if (!service.mIsAutomation && !canToggleTouchExploration) { 123858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov showEnableTouchExplorationDialog(service); 12394074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov } else { 124058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.putIntForUser(mContext.getContentResolver(), 124158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId); 12424074e8a3f429f62aff3312083d1d925d794ffaccSvetoslav Ganov } 1243e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1244e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1245e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 12469a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov private void tryDisableTouchExplorationLocked(Service service) { 124758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(service.mUserId); 124858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userState.mIsTouchExplorationEnabled) { 124958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int serviceCount = userState.mServices.size(); 125058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0; i < serviceCount; i++) { 125158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Service other = userState.mServices.get(i); 125258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (other != service && other.mRequestTouchExplorationMode) { 125358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return; 1254e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1255e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 125658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.putIntForUser(mContext.getContentResolver(), 125758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId); 1258e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1259e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1260e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1261d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov private class AccessibilityConnectionWrapper implements DeathRecipient { 1262d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov private final int mWindowId; 126358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final int mUserId; 1264d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov private final IAccessibilityInteractionConnection mConnection; 1265d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 1266d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov public AccessibilityConnectionWrapper(int windowId, 126758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IAccessibilityInteractionConnection connection, int userId) { 1268d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mWindowId = windowId; 126958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mUserId = userId; 1270d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mConnection = connection; 1271d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1272d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 1273d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov public void linkToDeath() throws RemoteException { 1274d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mConnection.asBinder().linkToDeath(this, 0); 1275d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1276d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 1277d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov public void unlinkToDeath() { 1278d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mConnection.asBinder().unlinkToDeath(this, 0); 1279d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1280d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 1281d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov @Override 1282d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov public void binderDied() { 1283d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov unlinkToDeath(); 1284d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov synchronized (mLock) { 128558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov removeAccessibilityInteractionConnectionLocked(mWindowId, mUserId); 1286d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1287d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1288d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1289d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 129058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final class MainHandler extends Handler { 129158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public static final int MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER = 1; 129258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public static final int MSG_SEND_STATE_TO_CLIENTS = 2; 129358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3; 129458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public static final int MSG_SEND_RECREATE_INTERNAL_STATE = 4; 1295a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov public static final int MSG_UPDATE_ACTIVE_WINDOW = 5; 12967befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public static final int MSG_ANNOUNCE_NEW_USER_IF_NEEDED = 6; 12971cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 12981cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov public MainHandler(Looper looper) { 12991cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov super(looper); 13001cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 13011cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 1302e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov @Override 1303e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov public void handleMessage(Message msg) { 1304e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int type = msg.what; 1305e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov switch (type) { 1306e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov case MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER: { 1307e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov AccessibilityEvent event = (AccessibilityEvent) msg.obj; 130858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 130958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mHasInputFilter && mInputFilter != null) { 131058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mInputFilter.notifyAccessibilityEvent(event); 131158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 1312e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov } 1313e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov event.recycle(); 1314e45c0b230ba92d7daf8bf625a59bd87d5948101bSvetoslav Ganov } break; 131558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case MSG_SEND_STATE_TO_CLIENTS: { 131658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int clientState = msg.arg1; 131758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userId = msg.arg2; 131858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov sendStateToClients(clientState, mGlobalClients); 131958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov sendStateToClientsForUser(clientState, userId); 132058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } break; 132158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: { 132258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userId = msg.arg1; 132358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov sendStateToClientsForUser(0, userId); 132458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } break; 132558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case MSG_SEND_RECREATE_INTERNAL_STATE: { 132658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userId = msg.arg1; 13271cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov synchronized (mLock) { 132858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getUserStateLocked(userId); 132958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov recreateInternalStateLocked(userState); 13301cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 133158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } break; 1332a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov case MSG_UPDATE_ACTIVE_WINDOW: { 1333a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov final int windowId = msg.arg1; 1334a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov final int eventType = msg.arg2; 1335a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov mSecurityPolicy.updateActiveWindow(windowId, eventType); 1336a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } break; 13377befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: { 13387befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov announceNewUserIfNeeded(); 13397befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } break; 13407befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 13417befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 13427befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 13437befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov private void announceNewUserIfNeeded() { 13447befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov synchronized (mLock) { 13457befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov UserState userState = getCurrentUserStateLocked(); 13467befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov if (userState.mIsAccessibilityEnabled) { 13477befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov UserManager userManager = (UserManager) mContext.getSystemService( 13487befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov Context.USER_SERVICE); 13497befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov String message = mContext.getString(R.string.user_switched, 13507befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userManager.getUserInfo(mCurrentUserId).name); 13517befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov AccessibilityEvent event = AccessibilityEvent.obtain( 13527befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov AccessibilityEvent.TYPE_ANNOUNCEMENT); 13537befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov event.getText().add(message); 1354fc9c4cd51b3bdca27726dd6d8a00d47e388ca2aaSvetoslav Ganov event.setWindowId(mSecurityPolicy.getRetrievalAllowingWindowLocked()); 13557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov sendAccessibilityEvent(event, mCurrentUserId); 13567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 1357e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1358e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 135958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 136058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void sendStateToClientsForUser(int clientState, int userId) { 136158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final UserState userState; 136258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 136358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov userState = getUserStateLocked(userId); 136458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 136558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov sendStateToClients(clientState, userState.mClients); 136658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 136758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 136858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private void sendStateToClients(int clientState, 136958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov RemoteCallbackList<IAccessibilityManagerClient> clients) { 137058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov try { 137158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int userClientCount = clients.beginBroadcast(); 137258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov for (int i = 0; i < userClientCount; i++) { 137358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IAccessibilityManagerClient client = clients.getBroadcastItem(i); 137458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov try { 137558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov client.setState(clientState); 137658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } catch (RemoteException re) { 137758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov /* ignore */ 137858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 137958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 138058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } finally { 138158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov clients.finishBroadcast(); 138258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 138358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 1384e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1385e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1386b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov /** 138775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * This class represents an accessibility service. It stores all per service 138875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * data required for the service management, provides API for starting/stopping the 138975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * service and is responsible for adding/removing the service in the data structures 139075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * for service management. The class also exposes configuration interface that is 139175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * passed to the service it represents as soon it is bound. It also serves as the 139275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * connection for the service. 139375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 1394f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov class Service extends IAccessibilityServiceConnection.Stub 1395f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov implements ServiceConnection, DeathRecipient { 1396e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1397e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // We pick the MSB to avoid collision since accessibility event types are 1398e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // used as message types allowing us to remove messages per event type. 1399e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private static final int MSG_ON_GESTURE = 0x80000000; 1400e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 140158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int mUserId; 140258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 140375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int mId = 0; 140475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 1405cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov AccessibilityServiceInfo mAccessibilityServiceInfo; 1406736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 140775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov IBinder mService; 140875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 14094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov IAccessibilityServiceClient mServiceInterface; 141075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 141175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int mEventTypes; 141275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 141375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov int mFeedbackType; 141475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 141575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Set<String> mPackageNames = new HashSet<String>(); 141675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 141775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov boolean mIsDefault; 141875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 1419e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov boolean mRequestTouchExplorationMode; 1420e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 14214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov boolean mIncludeNotImportantViews; 14224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 142375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov long mNotificationTimeout; 142475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 142575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov ComponentName mComponentName; 142675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 142775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov Intent mIntent; 142875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 14298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov boolean mCanRetrieveScreenContent; 14308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 1431e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov boolean mIsAutomation; 14328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 14337961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganov final Rect mTempBounds = new Rect(); 14347961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganov 1435e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final ResolveInfo mResolveInfo; 1436e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 143775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov // the events pending events to be dispatched to this service 143875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov final SparseArray<AccessibilityEvent> mPendingEvents = 143975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov new SparseArray<AccessibilityEvent>(); 144075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 1441e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov /** 1442e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * Handler for delayed event dispatch. 1443e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov */ 1444ec2c1717780fa4f61ed11dced16a87b8ae5d7fb0Svetoslav Ganov public Handler mHandler = new Handler(mMainHandler.getLooper()) { 1445e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov @Override 1446e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov public void handleMessage(Message message) { 1447e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int type = message.what; 1448e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov switch (type) { 1449e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov case MSG_ON_GESTURE: { 1450e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int gestureId = message.arg1; 1451e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov notifyGestureInternal(gestureId); 1452e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } break; 1453e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov default: { 1454e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int eventType = type; 1455e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov notifyAccessibilityEventInternal(eventType); 1456e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } break; 1457e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1458e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1459e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov }; 1460e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 146158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public Service(int userId, ComponentName componentName, 1462e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov AccessibilityServiceInfo accessibilityServiceInfo, boolean isAutomation) { 146358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mUserId = userId; 1464e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mResolveInfo = accessibilityServiceInfo.getResolveInfo(); 146575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mId = sIdCounter++; 14668643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mComponentName = componentName; 14678643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mAccessibilityServiceInfo = accessibilityServiceInfo; 1468e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov mIsAutomation = isAutomation; 1469e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!isAutomation) { 14708643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent(); 1471a43ef3d1c553007b3fa158fe1d3ec4ddb99a71afSvetoslav Ganov mRequestTouchExplorationMode = 1472e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov (accessibilityServiceInfo.flags 1473e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; 14748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mIntent = new Intent().setComponent(mComponentName); 14758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, 14768643aa0179e598e78d938c59035389054535a229Svetoslav Ganov com.android.internal.R.string.accessibility_binding_label); 14778643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( 14788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0)); 14798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } else { 14808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mCanRetrieveScreenContent = true; 14818643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 14828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov setDynamicallyConfigurableProperties(accessibilityServiceInfo); 14838643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 14848643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 14858643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public void setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) { 1486cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov mEventTypes = info.eventTypes; 1487cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov mFeedbackType = info.feedbackType; 1488cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov String[] packageNames = info.packageNames; 1489cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov if (packageNames != null) { 1490cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov mPackageNames.addAll(Arrays.asList(packageNames)); 1491cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } 1492cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov mNotificationTimeout = info.notificationTimeout; 14934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov mIsDefault = (info.flags & DEFAULT) != 0; 14944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 1495df549f83810c6fa76be1845363ef69809a30e569Guang Zhu if (mIsAutomation || info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion 14965a48f9758b990fe6c46359927a40aecb6a02b64cSvetoslav Ganov >= Build.VERSION_CODES.JELLY_BEAN) { 1497df549f83810c6fa76be1845363ef69809a30e569Guang Zhu mIncludeNotImportantViews = 1498e4abc512aa6474f0106f407f7b399832da34483fSvetoslav Ganov (info.flags & FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0; 14994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 1500c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov 1501e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mRequestTouchExplorationMode = (info.flags 1502e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; 1503e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 15049a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov // If this service is up and running we may have to enable touch 15059a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov // exploration, otherwise this will happen when the service connects. 1506c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov synchronized (mLock) { 15071f22b6a25d7df6c5488d9bd01793e7a20d921349Svetoslav Ganov if (canReceiveEvents()) { 15089a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov if (mRequestTouchExplorationMode) { 15099a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov tryEnableTouchExplorationLocked(this); 15109a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } else { 15119a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov tryDisableTouchExplorationLocked(this); 15129a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 15139a4c5cd19106c3021eeead27fbc2aa05ad7d0d18Svetoslav Ganov } 1514c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov } 1515cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov } 1516cc4053e031371456fe54d51bbad1db721db4ae38Svetoslav Ganov 151775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 151875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Binds to the accessibility service. 15196ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov * 15206ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov * @return True if binding is successful. 152175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 15226ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov public boolean bind() { 1523e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!mIsAutomation && mService == null) { 152458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return mContext.bindService(mIntent, this, Context.BIND_AUTO_CREATE, mUserId); 152575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 15266ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov return false; 152775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 152875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 152975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov /** 153075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * Unbinds form the accessibility service and removes it from the data 153175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov * structures for service management. 15326ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov * 15336ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov * @return True if unbinding is successful. 153475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov */ 15356ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov public boolean unbind() { 153675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov if (mService != null) { 1537c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov synchronized (mLock) { 1538c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov tryRemoveServiceLocked(this); 1539c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov } 1540e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!mIsAutomation) { 15418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov mContext.unbindService(this); 15428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 15436ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov return true; 154475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 15456ff5f103545f90aee3176ad6ca06d9233f899c51Svetoslav Ganov return false; 154675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 154775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15481f22b6a25d7df6c5488d9bd01793e7a20d921349Svetoslav Ganov public boolean canReceiveEvents() { 1549c321c19fc91bfec9a74039ed4d37b815dd4ef379Svetoslav Ganov return (mEventTypes != 0 && mFeedbackType != 0 && mService != null); 155075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 155175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 15534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov public AccessibilityServiceInfo getServiceInfo() { 15544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov synchronized (mLock) { 15554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return mAccessibilityServiceInfo; 15564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 15574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 15584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 15594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 156075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void setServiceInfo(AccessibilityServiceInfo info) { 156158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 156258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov try { 156358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 156458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // If the XML manifest had data to configure the service its info 156558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // should be already set. In such a case update only the dynamically 156658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // configurable properties. 156758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityServiceInfo oldInfo = mAccessibilityServiceInfo; 156858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (oldInfo != null) { 156958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov oldInfo.updateDynamicallyConfigurableProperties(info); 157058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov setDynamicallyConfigurableProperties(oldInfo); 157158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else { 157258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov setDynamicallyConfigurableProperties(info); 157358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 15744213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 157558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } finally { 157658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Binder.restoreCallingIdentity(identity); 15774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 157875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 157975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 158175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void onServiceConnected(ComponentName componentName, IBinder service) { 158275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov mService = service; 15834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov mServiceInterface = IAccessibilityServiceClient.Stub.asInterface(service); 158475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov try { 1585d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mServiceInterface.setConnection(this, mId); 158675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 158758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov tryAddServiceLocked(this, mUserId); 158875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 158975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } catch (RemoteException re) { 15908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(LOG_TAG, "Error while setting Controller for service: " + service, re); 159175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 159275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 159375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 15944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 159579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov public float findAccessibilityNodeInfoByViewId(int accessibilityWindowId, 159679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov long accessibilityNodeId, int viewId, int interactionId, 159779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 15984a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov throws RemoteException { 159958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedWindowId; 16008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov IAccessibilityInteractionConnection connection = null; 16018643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 160258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 160358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 160458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 160558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 160658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return -1; 160758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 16084a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov mSecurityPolicy.enforceCanRetrieveWindowContent(this); 16098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final boolean permissionGranted = mSecurityPolicy.canRetrieveWindowContent(this); 1610e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!permissionGranted) { 16118bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return 0; 1612e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } else { 161358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 161479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov connection = getConnectionLocked(resolvedWindowId); 1615e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (connection == null) { 16168bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return 0; 1617e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } 16188643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int flags = (mIncludeNotImportantViews) ? 16214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; 16228bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov final int interrogatingPid = Binder.getCallingPid(); 16238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final long identityToken = Binder.clearCallingIdentity(); 16248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov try { 162579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov connection.findAccessibilityNodeInfoByViewId(accessibilityNodeId, viewId, 1626c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov interactionId, callback, flags, interrogatingPid, interrogatingTid); 1627c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return getCompatibilityScale(resolvedWindowId); 16288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } catch (RemoteException re) { 16298643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (DEBUG) { 163079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId()."); 16318643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16328643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } finally { 16338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Binder.restoreCallingIdentity(identityToken); 16348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 1635c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return 0; 1636eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov } 1637eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov 16384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 163979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov public float findAccessibilityNodeInfosByText(int accessibilityWindowId, 164079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov long accessibilityNodeId, String text, int interactionId, 16418bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 16428bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov throws RemoteException { 164358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedWindowId; 16448643aa0179e598e78d938c59035389054535a229Svetoslav Ganov IAccessibilityInteractionConnection connection = null; 16458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 164658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 164758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 164858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 164958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 165058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return -1; 165158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 16524a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov mSecurityPolicy.enforceCanRetrieveWindowContent(this); 165358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 1654eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov final boolean permissionGranted = 165579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId); 1656e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!permissionGranted) { 16578bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return 0; 1658e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } else { 165979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov connection = getConnectionLocked(resolvedWindowId); 1660e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (connection == null) { 16618bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return 0; 1662e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } 16638643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16648643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int flags = (mIncludeNotImportantViews) ? 16664213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; 16678bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov final int interrogatingPid = Binder.getCallingPid(); 16688643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final long identityToken = Binder.clearCallingIdentity(); 16698643aa0179e598e78d938c59035389054535a229Svetoslav Ganov try { 1670c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text, 1671c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov interactionId, callback, flags, interrogatingPid, 167286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov interrogatingTid); 1673c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return getCompatibilityScale(resolvedWindowId); 16748643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } catch (RemoteException re) { 16758643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (DEBUG) { 167679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()"); 16778643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16788643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } finally { 16798643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Binder.restoreCallingIdentity(identityToken); 16808643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 1681c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return 0; 16828643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 16838643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 16844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 16858bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov public float findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId, 1686021078554b902179442a345a9d080a165c3b5139Svetoslav Ganov long accessibilityNodeId, int interactionId, 16874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov IAccessibilityInteractionConnectionCallback callback, int flags, 16884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov long interrogatingTid) throws RemoteException { 168958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedWindowId; 16908643aa0179e598e78d938c59035389054535a229Svetoslav Ganov IAccessibilityInteractionConnection connection = null; 16918643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 169258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 169358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 169458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 169558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 169658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return -1; 169758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 16984a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov mSecurityPolicy.enforceCanRetrieveWindowContent(this); 169958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 17008643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final boolean permissionGranted = 170179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId); 1702e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!permissionGranted) { 17038bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return 0; 1704e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } else { 170579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov connection = getConnectionLocked(resolvedWindowId); 170679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov if (connection == null) { 17078bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return 0; 1708e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } 17098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 17108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 17114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int allFlags = flags | ((mIncludeNotImportantViews) ? 17124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0); 17138bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov final int interrogatingPid = Binder.getCallingPid(); 17148643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final long identityToken = Binder.clearCallingIdentity(); 17158643aa0179e598e78d938c59035389054535a229Svetoslav Ganov try { 1716021078554b902179442a345a9d080a165c3b5139Svetoslav Ganov connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId, 1717c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov interactionId, callback, allFlags, interrogatingPid, interrogatingTid); 1718c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return getCompatibilityScale(resolvedWindowId); 17198643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } catch (RemoteException re) { 17208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (DEBUG) { 172179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()"); 17228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 17238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } finally { 17248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Binder.restoreCallingIdentity(identityToken); 17258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 1726c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return 0; 17278643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 17288643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 17294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 17304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov public float findFocus(int accessibilityWindowId, long accessibilityNodeId, 17314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov int focusType, int interactionId, 17324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 17334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov throws RemoteException { 173458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedWindowId; 17354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov IAccessibilityInteractionConnection connection = null; 17364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov synchronized (mLock) { 173758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 173858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 173958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 174058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 174158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return -1; 174258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 17434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov mSecurityPolicy.enforceCanRetrieveWindowContent(this); 174458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 17454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final boolean permissionGranted = 17464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId); 17474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (!permissionGranted) { 17484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return 0; 17494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } else { 17504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov connection = getConnectionLocked(resolvedWindowId); 17514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (connection == null) { 17524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return 0; 17534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 17544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 17554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 17564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int flags = (mIncludeNotImportantViews) ? 17574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; 17584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int interrogatingPid = Binder.getCallingPid(); 17594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final long identityToken = Binder.clearCallingIdentity(); 17604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov try { 1761c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov connection.findFocus(accessibilityNodeId, focusType, interactionId, callback, 1762c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov flags, interrogatingPid, interrogatingTid); 1763c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return getCompatibilityScale(resolvedWindowId); 17644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } catch (RemoteException re) { 17654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (DEBUG) { 17664213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov Slog.e(LOG_TAG, "Error calling findAccessibilityFocus()"); 17674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 17684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } finally { 17694213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov Binder.restoreCallingIdentity(identityToken); 17704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 1771c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return 0; 17724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 17734213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 17744213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 17754213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov public float focusSearch(int accessibilityWindowId, long accessibilityNodeId, 17764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov int direction, int interactionId, 17774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 17784213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov throws RemoteException { 177958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedWindowId; 17804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov IAccessibilityInteractionConnection connection = null; 17814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov synchronized (mLock) { 178258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 178358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 178458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 178558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 178658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return -1; 178758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 17884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov mSecurityPolicy.enforceCanRetrieveWindowContent(this); 178958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 17904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final boolean permissionGranted = 17914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId); 17924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (!permissionGranted) { 17934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return 0; 17944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } else { 17954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov connection = getConnectionLocked(resolvedWindowId); 17964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (connection == null) { 17974213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov return 0; 17984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 17994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 18004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 18014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int flags = (mIncludeNotImportantViews) ? 18024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; 18034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final int interrogatingPid = Binder.getCallingPid(); 18044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov final long identityToken = Binder.clearCallingIdentity(); 18054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov try { 1806c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov connection.focusSearch(accessibilityNodeId, direction, interactionId, callback, 1807c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov flags, interrogatingPid, interrogatingTid); 1808c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return getCompatibilityScale(resolvedWindowId); 18094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } catch (RemoteException re) { 18104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov if (DEBUG) { 18114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()"); 18124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 18134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } finally { 18144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov Binder.restoreCallingIdentity(identityToken); 18154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 1816c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return 0; 18174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov } 18184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 18194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov @Override 18208643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public boolean performAccessibilityAction(int accessibilityWindowId, 1821aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganov long accessibilityNodeId, int action, Bundle arguments, int interactionId, 182258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 182358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov throws RemoteException { 182458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedWindowId; 18258643aa0179e598e78d938c59035389054535a229Svetoslav Ganov IAccessibilityInteractionConnection connection = null; 18268643aa0179e598e78d938c59035389054535a229Svetoslav Ganov synchronized (mLock) { 182758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 182858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 182958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 183058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 183158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return false; 183258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 183358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mSecurityPolicy.enforceCanRetrieveWindowContent(this); 183458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 18358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final boolean permissionGranted = mSecurityPolicy.canPerformActionLocked(this, 1836b7ff3255c6d4e12f9d2334e3bbec0a125b7b09dcSvetoslav Ganov resolvedWindowId, action, arguments); 1837e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov if (!permissionGranted) { 1838e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov return false; 1839e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } else { 184079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov connection = getConnectionLocked(resolvedWindowId); 184179311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov if (connection == null) { 1842e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov return false; 1843e8f95352cf4fd2bb38fd124bf5fcefddddeb0692Svetoslav Ganov } 18448643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 18458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 18469bf21873c900e7bf82d864172ab40527a48dae3eSvetoslav Ganov final int flags = (mIncludeNotImportantViews) ? 18479bf21873c900e7bf82d864172ab40527a48dae3eSvetoslav Ganov AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; 18489bf21873c900e7bf82d864172ab40527a48dae3eSvetoslav Ganov final int interrogatingPid = Binder.getCallingPid(); 18498643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final long identityToken = Binder.clearCallingIdentity(); 18508643aa0179e598e78d938c59035389054535a229Svetoslav Ganov try { 1851aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganov connection.performAccessibilityAction(accessibilityNodeId, action, arguments, 1852aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganov interactionId, callback, flags, interrogatingPid, interrogatingTid); 18538643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } catch (RemoteException re) { 18548643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (DEBUG) { 185579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov Slog.e(LOG_TAG, "Error calling performAccessibilityAction()"); 18568643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 18578643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } finally { 18588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Binder.restoreCallingIdentity(identityToken); 18598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 18608bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov return true; 18618643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 18628643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 1863e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov public boolean performGlobalAction(int action) { 186458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 186558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int resolvedUserId = mSecurityPolicy 186658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .resolveCallingUserIdEnforcingPermissionsLocked( 186758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserHandle.getCallingUserId()); 186858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (resolvedUserId != mCurrentUserId) { 186958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return false; 187058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 187158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 187258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final long identity = Binder.clearCallingIdentity(); 187358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov try { 187458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov switch (action) { 187558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case AccessibilityService.GLOBAL_ACTION_BACK: { 187658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK); 187758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } return true; 187858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case AccessibilityService.GLOBAL_ACTION_HOME: { 187958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME); 188058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } return true; 188158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case AccessibilityService.GLOBAL_ACTION_RECENTS: { 188258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov openRecents(); 188358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } return true; 188458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: { 1885e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov expandNotifications(); 1886e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov } return true; 1887e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov case AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS: { 1888e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov expandQuickSettings(); 188958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } return true; 189058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 189158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return false; 189258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } finally { 189358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Binder.restoreCallingIdentity(identity); 1894005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov } 1895005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov } 1896005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov 189775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov public void onServiceDisconnected(ComponentName componentName) { 1898f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov /* do nothing - #binderDied takes care */ 1899f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov } 1900f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov 1901f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov public void linkToOwnDeath() throws RemoteException { 1902f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov mService.linkToDeath(this, 0); 1903f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov } 1904f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov 1905f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov public void unlinkToOwnDeath() { 1906f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov mService.unlinkToDeath(this, 0); 1907f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov } 1908f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov 1909d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov public void dispose() { 1910d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov try { 1911d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov // Clear the proxy in the other process so this 1912d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov // IAccessibilityServiceConnection can be garbage collected. 1913d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mServiceInterface.setConnection(null, mId); 1914d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } catch (RemoteException re) { 1915d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov /* ignore */ 1916d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1917d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mService = null; 1918d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov mServiceInterface = null; 1919d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov } 1920d116d7c78a9c53f30a73bf273bd7618312cf3847Svetoslav Ganov 1921f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov public void binderDied() { 192275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov synchronized (mLock) { 19230d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov // The death recipient is unregistered in tryRemoveServiceLocked 1924f9886f3ee9db23cc5a553b92e2aeff0ae842c915Svetoslav Ganov tryRemoveServiceLocked(this); 1925b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // We no longer have an automation service, so restore 1926b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov // the state based on values in the settings database. 1927b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov if (mIsAutomation) { 19289b666d0faadd26827ca5b7cf6af3aa94af6adcd9Svetoslav Ganov mUiAutomationService = null; 192958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov recreateInternalStateLocked(getUserStateLocked(mUserId)); 1930b6eca6e6691d4563d8395b3c3843d9932a2a6560Svetoslav Ganov } 193175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 193275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 19338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 1934e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov /** 1935e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * Performs a notification for an {@link AccessibilityEvent}. 1936e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * 1937e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * @param event The event. 1938e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov */ 1939e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov public void notifyAccessibilityEvent(AccessibilityEvent event) { 1940e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov synchronized (mLock) { 1941e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int eventType = event.getEventType(); 1942e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // Make a copy since during dispatch it is possible the event to 1943e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // be modified to remove its source if the receiving service does 1944e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // not have permission to access the window content. 1945e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityEvent newEvent = AccessibilityEvent.obtain(event); 1946e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityEvent oldEvent = mPendingEvents.get(eventType); 1947e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mPendingEvents.put(eventType, newEvent); 1948e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1949e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov final int what = eventType; 1950e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (oldEvent != null) { 1951e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mHandler.removeMessages(what); 1952e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov oldEvent.recycle(); 1953e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1954e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1955e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov Message message = mHandler.obtainMessage(what); 1956e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mHandler.sendMessageDelayed(message, mNotificationTimeout); 1957e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1958e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1959e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1960e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov /** 1961e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * Notifies an accessibility service client for a scheduled event given the event type. 1962e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * 1963e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov * @param eventType The type of the event to dispatch. 1964e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov */ 1965e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private void notifyAccessibilityEventInternal(int eventType) { 1966e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov IAccessibilityServiceClient listener; 1967e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov AccessibilityEvent event; 1968e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1969e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov synchronized (mLock) { 1970e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov listener = mServiceInterface; 1971e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1972e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // If the service died/was disabled while the message for dispatching 1973e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // the accessibility event was propagating the listener may be null. 1974e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (listener == null) { 1975e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return; 1976e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1977e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1978e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov event = mPendingEvents.get(eventType); 1979e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1980e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // Check for null here because there is a concurrent scenario in which this 1981e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // happens: 1) A binder thread calls notifyAccessibilityServiceDelayedLocked 1982e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // which posts a message for dispatching an event. 2) The message is pulled 1983e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // from the queue by the handler on the service thread and the latter is 1984e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // just about to acquire the lock and call this method. 3) Now another binder 1985e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // thread acquires the lock calling notifyAccessibilityServiceDelayedLocked 1986e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // so the service thread waits for the lock; 4) The binder thread replaces 1987e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // the event with a more recent one (assume the same event type) and posts a 1988e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // dispatch request releasing the lock. 5) Now the main thread is unblocked and 1989e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // dispatches the event which is removed from the pending ones. 6) And ... now 1990e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // the service thread handles the last message posted by the last binder call 1991e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // but the event is already dispatched and hence looking it up in the pending 1992e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // ones yields null. This check is much simpler that keeping count for each 1993e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // event type of each service to catch such a scenario since only one message 1994e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // is processed at a time. 1995e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (event == null) { 1996e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return; 1997e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 1998e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 1999e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mPendingEvents.remove(eventType); 2000e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (mSecurityPolicy.canRetrieveWindowContent(this)) { 2001e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov event.setConnectionId(mId); 2002e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } else { 2003e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov event.setSource(null); 2004e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2005e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov event.setSealed(true); 2006e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2007e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 2008e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov try { 2009e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov listener.onAccessibilityEvent(event); 2010e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (DEBUG) { 2011e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov Slog.i(LOG_TAG, "Event " + event + " sent to " + listener); 2012e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2013e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } catch (RemoteException re) { 2014e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov Slog.e(LOG_TAG, "Error during sending " + event + " to " + listener, re); 2015e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } finally { 2016e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov event.recycle(); 2017e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2018e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2019e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 2020e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov public void notifyGesture(int gestureId) { 2021e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mHandler.obtainMessage(MSG_ON_GESTURE, gestureId, 0).sendToTarget(); 2022e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2023e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 2024e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private void notifyGestureInternal(int gestureId) { 2025e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov IAccessibilityServiceClient listener = mServiceInterface; 2026e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (listener != null) { 2027e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov try { 2028e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov listener.onGesture(gestureId); 2029e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } catch (RemoteException re) { 2030e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov Slog.e(LOG_TAG, "Error during sending gesture " + gestureId 2031e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov + " to " + mService, re); 2032e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2033e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2034e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2035e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 2036005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov private void sendDownAndUpKeyEvents(int keyCode) { 2037005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov final long token = Binder.clearCallingIdentity(); 2038005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov 2039005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov // Inject down. 2040005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov final long downTime = SystemClock.uptimeMillis(); 2041005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov KeyEvent down = KeyEvent.obtain(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, 0, 0, 2042005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, 2043005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov InputDevice.SOURCE_KEYBOARD, null); 2044005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov InputManager.getInstance().injectInputEvent(down, 2045005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 2046005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov down.recycle(); 2047005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov 2048005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov // Inject up. 2049005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov final long upTime = SystemClock.uptimeMillis(); 2050005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov KeyEvent up = KeyEvent.obtain(downTime, upTime, KeyEvent.ACTION_UP, keyCode, 0, 0, 2051005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, 2052005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov InputDevice.SOURCE_KEYBOARD, null); 2053005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov InputManager.getInstance().injectInputEvent(up, 2054005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 2055005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov up.recycle(); 2056005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov 2057005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov Binder.restoreCallingIdentity(token); 2058005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov } 2059005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov 2060e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov private void expandNotifications() { 2061e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov final long token = Binder.clearCallingIdentity(); 2062e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov 2063e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService( 2064e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov android.app.Service.STATUS_BAR_SERVICE); 206511cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler statusBarManager.expandNotificationsPanel(); 2066e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov 2067e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov Binder.restoreCallingIdentity(token); 2068e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov } 2069e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov 2070e20a177d3f147f3011647c3bdab401f90b2c5d1dSvetoslav Ganov private void expandQuickSettings() { 20715c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov final long token = Binder.clearCallingIdentity(); 20725c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov 20735c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService( 20745c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov android.app.Service.STATUS_BAR_SERVICE); 207511cf178100e71d3f9f34ab5865e03a277c5eadaaDaniel Sandler statusBarManager.expandSettingsPanel(); 20765c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov 20775c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov Binder.restoreCallingIdentity(token); 20785c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov } 20795c89f44ea16667bf18297ccb9fb10aad639dab1fSvetoslav Ganov 2080c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov private void openRecents() { 2081c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov final long token = Binder.clearCallingIdentity(); 2082c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov 2083c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov IStatusBarService statusBarService = IStatusBarService.Stub.asInterface( 2084c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov ServiceManager.getService("statusbar")); 2085c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov try { 2086c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov statusBarService.toggleRecentApps(); 2087c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov } catch (RemoteException e) { 2088c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov Slog.e(LOG_TAG, "Error toggling recent apps."); 2089c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov } 2090c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov 2091c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov Binder.restoreCallingIdentity(token); 2092c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov } 2093c682fc965df2518a95d23e39ec51d788100d20ecSvetoslav Ganov 209479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov private IAccessibilityInteractionConnection getConnectionLocked(int windowId) { 20958643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (DEBUG) { 20968643aa0179e598e78d938c59035389054535a229Svetoslav Ganov Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId); 20978643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 209858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov AccessibilityConnectionWrapper wrapper = mGlobalInteractionConnections.get(windowId); 209958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (wrapper == null) { 210058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov wrapper = getCurrentUserStateLocked().mInteractionConnections.get(windowId); 210158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 210279311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov if (wrapper != null && wrapper.mConnection != null) { 210379311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov return wrapper.mConnection; 210479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 210579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov if (DEBUG) { 210679311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov Slog.e(LOG_TAG, "No interaction connection to window: " + windowId); 210779311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 210879311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov return null; 210979311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 211079311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov 211158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) { 21120d04e245534cf777dfaf16dce3c51553837c14ffSvetoslav Ganov if (accessibilityWindowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) { 2113e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return mSecurityPolicy.mActiveWindowId; 211479311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov } 211579311c4af8b54d3cd47ab37a120c648bfc990511Svetoslav Ganov return accessibilityWindowId; 21168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 21177961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganov 21188bd69610aafc6995126965d1d23b771fe02a9084Svetoslav Ganov private float getCompatibilityScale(int windowId) { 2119c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov try { 212058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IBinder windowToken = mGlobalWindowTokens.get(windowId); 212158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (windowToken != null) { 212258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return mWindowManagerService.getWindowCompatibilityScale(windowToken); 212358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 212458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov windowToken = getCurrentUserStateLocked().mWindowTokens.get(windowId); 212558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (windowToken != null) { 212658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return mWindowManagerService.getWindowCompatibilityScale(windowToken); 212758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 2128c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } catch (RemoteException re) { 2129c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov /* ignore */ 2130c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 2131c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov return 1.0f; 21327961be75f4161769f620e44dec3f5911e50ebe03Svetoslav Ganov } 21338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 21348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 21358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov final class SecurityPolicy { 21364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov private static final int VALID_ACTIONS = 21374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityNodeInfo.ACTION_CLICK 213876f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov | AccessibilityNodeInfo.ACTION_LONG_CLICK 21394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityNodeInfo.ACTION_FOCUS 21404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityNodeInfo.ACTION_CLEAR_FOCUS 21414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityNodeInfo.ACTION_SELECT 21424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityNodeInfo.ACTION_CLEAR_SELECTION 21434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS 2144aa780c110922148a6a4ba06734bb2b0bb8c98f93Svetoslav Ganov | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS 21452b435aada3d274a9c08d334946fff1ab9ba15b48Svetoslav Ganov | AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY 21462b435aada3d274a9c08d334946fff1ab9ba15b48Svetoslav Ganov | AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY 2147b7ff3255c6d4e12f9d2334e3bbec0a125b7b09dcSvetoslav Ganov | AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT 2148a1dc761c8322355eb1bb71d3d6c9c603c1d1fc0fSvetoslav Ganov | AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT 2149a1dc761c8322355eb1bb71d3d6c9c603c1d1fc0fSvetoslav Ganov | AccessibilityNodeInfo.ACTION_SCROLL_FORWARD 2150a1dc761c8322355eb1bb71d3d6c9c603c1d1fc0fSvetoslav Ganov | AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD; 21518643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 21528643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private static final int RETRIEVAL_ALLOWING_EVENT_TYPES = 21534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov AccessibilityEvent.TYPE_VIEW_CLICKED 21544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_FOCUSED 21554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER 21564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT 21574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED 21584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED 21594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED 21604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_SELECTED 2161a0156177cdc809795dd8bc5a19943dd2b6f82b66Svetoslav Ganov | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED 2162a0156177cdc809795dd8bc5a19943dd2b6f82b66Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED 21634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_SCROLLED 21644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED 21654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED; 21668643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 2167e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private int mActiveWindowId; 21686ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov private boolean mTouchInteractionInProgress; 21698643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 2170eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov private boolean canDispatchAccessibilityEvent(AccessibilityEvent event) { 217158fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov final int eventType = event.getEventType(); 217258fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov switch (eventType) { 217358fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // All events that are for changes in a global window 217458fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // state should *always* be dispatched. 217558fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: 217658fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED: 217758fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // All events generated by the user touching the 217858fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // screen should *always* be dispatched. 217958fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START: 218058fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END: 218158fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_GESTURE_DETECTION_START: 218258fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_GESTURE_DETECTION_END: 218358fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START: 218458fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END: 218558fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // These will change the active window, so dispatch. 218658fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: 218758fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { 218858fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov return true; 218958fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov } 219058fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // All events for changes in window content should be 219158fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov // dispatched *only* if this window is the active one. 219258fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov default: 219358fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov return event.getWindowId() == mActiveWindowId; 219458fd9f8d6ad6bf1975e834f1a69e68673db9a452Svetoslav Ganov } 2195eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov } 2196eeee4d2c01d3c4ed99e4891dbc75c7de69a803faSvetoslav Ganov 2197a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov public void updateEventSourceLocked(AccessibilityEvent event) { 2198a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) { 2199a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov event.setSource(null); 2200a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 2201a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 2202a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov 2203a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov public void updateActiveWindow(int windowId, int eventType) { 2204e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // The active window is either the window that has input focus or 2205e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // the window that the user is currently touching. If the user is 2206e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // touching a window that does not have input focus as soon as the 2207e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // the user stops touching that window the focused window becomes 2208e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov // the active one. 2209e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov switch (eventType) { 2210e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: { 2211e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov if (getFocusedWindowId() == windowId) { 2212e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mActiveWindowId = windowId; 2213e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2214e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } break; 2215f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: { 22166ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov // Do not allow delayed hover events to confuse us 22176ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov // which the active window is. 22186ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov if (mTouchInteractionInProgress) { 22196ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov mActiveWindowId = windowId; 22206ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov } 2221e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } break; 22224e2a762eae1f6981d32e6098a95498865ad7f795Svetoslav Ganov } 22238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 22248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 22256ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov public void onTouchInteractionStart() { 22266ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov mTouchInteractionInProgress = true; 22276ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov } 22286ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov 2229f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov public void onTouchInteractionEnd() { 22306ae8a24fc045bc7970f2843fa9baf06aff15e22dSvetoslav Ganov mTouchInteractionInProgress = false; 2231f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // We want to set the active window to be current immediately 2232f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // after the user has stopped touching the screen since if the 2233f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // user types with the IME he should get a feedback for the 2234f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // letter typed in the text view which is in the input focused 2235f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // window. Note that we always deliver hover accessibility events 2236f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // (they are a result of user touching the screen) so change of 2237f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // the active window before all hover accessibility events from 2238f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov // the touched window are delivered is fine. 2239f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov mActiveWindowId = getFocusedWindowId(); 2240f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov } 2241f772cba59760d1ad9eb5cb9205b2e2e9126e488dSvetoslav Ganov 22428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public int getRetrievalAllowingWindowLocked() { 2243e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return mActiveWindowId; 22448643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 22458643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 22468643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public boolean canGetAccessibilityNodeInfoLocked(Service service, int windowId) { 22478643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return canRetrieveWindowContent(service) && isRetrievalAllowingWindow(windowId); 22488643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 22498643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 2250b7ff3255c6d4e12f9d2334e3bbec0a125b7b09dcSvetoslav Ganov public boolean canPerformActionLocked(Service service, int windowId, int action, 2251b7ff3255c6d4e12f9d2334e3bbec0a125b7b09dcSvetoslav Ganov Bundle arguments) { 22528643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return canRetrieveWindowContent(service) 22538643aa0179e598e78d938c59035389054535a229Svetoslav Ganov && isRetrievalAllowingWindow(windowId) 2254afe8cf2623f6e28e2c2bf350173e66718b5aa4c0Svetoslav Ganov && isActionPermitted(action); 22558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 22568643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 22578643aa0179e598e78d938c59035389054535a229Svetoslav Ganov public boolean canRetrieveWindowContent(Service service) { 22588643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return service.mCanRetrieveScreenContent; 22598643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 22608643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 22614a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov public void enforceCanRetrieveWindowContent(Service service) throws RemoteException { 22624a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov // This happens due to incorrect registration so make it apparent. 22634a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov if (!canRetrieveWindowContent(service)) { 22644a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov Slog.e(LOG_TAG, "Accessibility serivce " + service.mComponentName + " does not " + 22654a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov "declare android:canRetrieveWindowContent."); 22664a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov throw new RemoteException(); 22674a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov } 22684a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov } 22694a49d9fe52a76c7f91f81113e0a8e9f97ac3f24cSvetoslav Ganov 227058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public int resolveCallingUserIdEnforcingPermissionsLocked(int userId) { 227158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int callingUid = Binder.getCallingUid(); 227258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (callingUid == Process.SYSTEM_UID 227358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || callingUid == Process.SHELL_UID) { 227458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return mCurrentUserId; 227558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 227658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int callingUserId = UserHandle.getUserId(callingUid); 227758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (callingUserId == userId) { 227858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return userId; 227958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 228058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (!hasPermission(Manifest.permission.INTERACT_ACROSS_USERS) 228158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov && !hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)) { 228258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov throw new SecurityException("Call from user " + callingUserId + " as user " 228358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov + userId + " without permission INTERACT_ACROSS_USERS or " 228458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov + "INTERACT_ACROSS_USERS_FULL not allowed."); 228558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 228658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (userId == UserHandle.USER_CURRENT 228758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || userId == UserHandle.USER_CURRENT_OR_SELF) { 228858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return mCurrentUserId; 228958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 229058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov throw new IllegalArgumentException("Calling user can be changed to only " 229158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF."); 229258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 229358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 229458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public boolean isCallerInteractingAcrossUsers(int userId) { 229558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov final int callingUid = Binder.getCallingUid(); 2296a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov return (Binder.getCallingPid() == android.os.Process.myPid() 229758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || callingUid == Process.SHELL_UID 229858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || userId == UserHandle.USER_CURRENT 229958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov || userId == UserHandle.USER_CURRENT_OR_SELF); 230058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 230158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 23028643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private boolean isRetrievalAllowingWindow(int windowId) { 2303e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return (mActiveWindowId == windowId); 23048643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 23058643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 23068643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private boolean isActionPermitted(int action) { 23078643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return (VALID_ACTIONS & action) != 0; 23088643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 23098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov 23108643aa0179e598e78d938c59035389054535a229Svetoslav Ganov private void enforceCallingPermission(String permission, String function) { 23118643aa0179e598e78d938c59035389054535a229Svetoslav Ganov if (OWN_PROCESS_ID == Binder.getCallingPid()) { 23128643aa0179e598e78d938c59035389054535a229Svetoslav Ganov return; 23138643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 23149371a0a0c0cdf9be0e0a32e4c3037cc2e216cfa0Svetoslav Ganov if (!hasPermission(permission)) { 23158643aa0179e598e78d938c59035389054535a229Svetoslav Ganov throw new SecurityException("You do not have " + permission 23168643aa0179e598e78d938c59035389054535a229Svetoslav Ganov + " required to call " + function); 23178643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 23188643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 2319e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov 232058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private boolean hasPermission(String permission) { 232158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; 232258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 232358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 2324e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private int getFocusedWindowId() { 2325c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov try { 2326c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov // We call this only on window focus change or after touch 2327c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov // exploration gesture end and the shown windows are not that 2328c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov // many, so the linear look up is just fine. 232958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov IBinder token = mWindowManagerService.getFocusedWindowToken(); 2330c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov if (token != null) { 2331a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov synchronized (mLock) { 2332a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov int windowId = getFocusedWindowIdLocked(token, mGlobalWindowTokens); 2333a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (windowId < 0) { 2334a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov windowId = getFocusedWindowIdLocked(token, 2335a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov getCurrentUserStateLocked().mWindowTokens); 2336c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 2337a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov return windowId; 2338e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2339e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2340c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } catch (RemoteException re) { 2341c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov /* ignore */ 2342a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 2343a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov return -1; 2344a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 2345a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov 2346a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov private int getFocusedWindowIdLocked(IBinder token, SparseArray<IBinder> windows) { 2347a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov final int windowCount = windows.size(); 2348a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov for (int i = 0; i < windowCount; i++) { 2349a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov if (windows.valueAt(i) == token) { 2350a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov return windows.keyAt(i); 2351a8afa694d6881266ad762aacdac92b2047f9a86cSvetoslav Ganov } 2352e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 2353e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov return -1; 2354e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov } 23558643aa0179e598e78d938c59035389054535a229Svetoslav Ganov } 235658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 235758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private class UserState { 235858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final int mUserId; 235958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 236058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final CopyOnWriteArrayList<Service> mServices = new CopyOnWriteArrayList<Service>(); 236158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 236258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final RemoteCallbackList<IAccessibilityManagerClient> mClients = 236358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new RemoteCallbackList<IAccessibilityManagerClient>(); 236458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 236558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final Map<ComponentName, Service> mComponentNameToServiceMap = 236658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new HashMap<ComponentName, Service>(); 236758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 236858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final List<AccessibilityServiceInfo> mInstalledServices = 236958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new ArrayList<AccessibilityServiceInfo>(); 237058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 237158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>(); 237258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 237358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final Set<ComponentName> mTouchExplorationGrantedServices = 237458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new HashSet<ComponentName>(); 237558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 237658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final SparseArray<AccessibilityConnectionWrapper> 237758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mInteractionConnections = 237858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov new SparseArray<AccessibilityConnectionWrapper>(); 237958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 238058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public final SparseArray<IBinder> mWindowTokens = new SparseArray<IBinder>(); 238158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 238258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public int mHandledFeedbackTypes = 0; 238358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 238458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public boolean mIsAccessibilityEnabled; 238558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public boolean mIsTouchExplorationEnabled; 238658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public boolean mIsDisplayMagnificationEnabled; 238758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 238858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public UserState(int userId) { 238958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mUserId = userId; 239058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 239158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 239258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 23937befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov private class TempUserStateChangeMemento { 23947befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public int mUserId = UserHandle.USER_NULL; 23957befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public boolean mIsAccessibilityEnabled; 23967befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public boolean mIsTouchExplorationEnabled; 23977befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public boolean mIsDisplayMagnificationEnabled; 23987befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>(); 23997befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public final Set<ComponentName> mTouchExplorationGrantedServices = 24007befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov new HashSet<ComponentName>(); 24017befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 24027befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public void initialize(int userId, UserState userState) { 24037befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mUserId = userId; 24047befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mIsAccessibilityEnabled = userState.mIsAccessibilityEnabled; 24057befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mIsTouchExplorationEnabled = userState.mIsTouchExplorationEnabled; 24067befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mIsDisplayMagnificationEnabled = userState.mIsDisplayMagnificationEnabled; 24077befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mEnabledServices.clear(); 24087befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mEnabledServices.addAll(userState.mEnabledServices); 24097befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTouchExplorationGrantedServices.clear(); 24107befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTouchExplorationGrantedServices.addAll(userState.mTouchExplorationGrantedServices); 24117befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 24127befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 24137befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public void applyTo(UserState userState) { 24147befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mIsAccessibilityEnabled = mIsAccessibilityEnabled; 24157befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mIsTouchExplorationEnabled = mIsTouchExplorationEnabled; 24167befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled; 24177befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mEnabledServices.clear(); 24187befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mEnabledServices.addAll(mEnabledServices); 24197befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mTouchExplorationGrantedServices.clear(); 24207befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov userState.mTouchExplorationGrantedServices.addAll(mTouchExplorationGrantedServices); 24217befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 24227befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 24237befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov public void clear() { 24247befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mUserId = UserHandle.USER_NULL; 24257befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mIsAccessibilityEnabled = false; 24267befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mIsTouchExplorationEnabled = false; 24277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mIsDisplayMagnificationEnabled = false; 24287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mEnabledServices.clear(); 24297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov mTouchExplorationGrantedServices.clear(); 24307befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 24317befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov } 24327befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov 243358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final class AccessibilityContentObserver extends ContentObserver { 243458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 243558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Uri mAccessibilityEnabledUri = Settings.Secure.getUriFor( 243658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.ACCESSIBILITY_ENABLED); 243758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 243858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Uri mTouchExplorationEnabledUri = Settings.Secure.getUriFor( 243958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.TOUCH_EXPLORATION_ENABLED); 244058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 244158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Uri mDisplayMagnificationEnabledUri = Settings.Secure.getUriFor( 244258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); 244358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 244458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor( 244558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); 244658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 244758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure 244858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES); 244958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 245058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public AccessibilityContentObserver(Handler handler) { 245158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov super(handler); 245258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 245358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 245458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void register(ContentResolver contentResolver) { 245558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov contentResolver.registerContentObserver(mAccessibilityEnabledUri, 245658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov false, this, UserHandle.USER_ALL); 245758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov contentResolver.registerContentObserver(mTouchExplorationEnabledUri, 245858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov false, this, UserHandle.USER_ALL); 245958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov contentResolver.registerContentObserver(mDisplayMagnificationEnabledUri, 246058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov false, this, UserHandle.USER_ALL); 246158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri, 246258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov false, this, UserHandle.USER_ALL); 246358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov contentResolver.registerContentObserver( 246458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov mTouchExplorationGrantedAccessibilityServicesUri, 246558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov false, this, UserHandle.USER_ALL); 246658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 246758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov 246858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov @Override 246958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov public void onChange(boolean selfChange, Uri uri) { 247058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mAccessibilityEnabledUri.equals(uri)) { 247158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 247258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // We will update when the automation service dies. 247358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mUiAutomationService == null) { 247458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 247558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleAccessibilityEnabledSettingChangedLocked(userState); 24767befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov performServiceManagementLocked(userState); 247758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov updateInputFilterLocked(userState); 247858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov scheduleSendStateToClientsLocked(userState); 247958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 248058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 248158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else if (mTouchExplorationEnabledUri.equals(uri)) { 248258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 248358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // We will update when the automation service dies. 248458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mUiAutomationService == null) { 248558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 248658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleTouchExplorationEnabledSettingChangedLocked(userState); 248758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov updateInputFilterLocked(userState); 248858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov scheduleSendStateToClientsLocked(userState); 248958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 249058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 249158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else if (mDisplayMagnificationEnabledUri.equals(uri)) { 249258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 249358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // We will update when the automation service dies. 249458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mUiAutomationService == null) { 249558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 249658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleDisplayMagnificationEnabledSettingChangedLocked(userState); 249758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov updateInputFilterLocked(userState); 249858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov scheduleSendStateToClientsLocked(userState); 249958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 250058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 250158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else if (mEnabledAccessibilityServicesUri.equals(uri)) { 250258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 250358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // We will update when the automation service dies. 250458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mUiAutomationService == null) { 250558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 250658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov populateEnabledAccessibilityServicesLocked(userState); 250758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov manageServicesLocked(userState); 250858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 250958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 251058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) { 251158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov synchronized (mLock) { 251258d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov // We will update when the automation service dies. 251358d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov if (mUiAutomationService == null) { 251458d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov UserState userState = getCurrentUserStateLocked(); 251558d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov populateTouchExplorationGrantedAccessibilityServicesLocked(userState); 251658d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState); 251758d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 251858d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 251958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 252058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 252158d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov } 252275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov} 2523