Home | History | Annotate | Download | only in accessibility
      1 /*
      2  ** Copyright 2009, The Android Open Source Project
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 package com.android.server.accessibility;
     18 
     19 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
     20 import static android.view.Display.DEFAULT_DISPLAY;
     21 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
     22 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
     23 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
     24 
     25 import android.Manifest;
     26 import android.accessibilityservice.AccessibilityService;
     27 import android.accessibilityservice.AccessibilityServiceInfo;
     28 import android.accessibilityservice.GestureDescription;
     29 import android.accessibilityservice.IAccessibilityServiceClient;
     30 import android.accessibilityservice.IAccessibilityServiceConnection;
     31 import android.annotation.NonNull;
     32 import android.app.ActivityManagerInternal;
     33 import android.app.AlertDialog;
     34 import android.app.PendingIntent;
     35 import android.app.StatusBarManager;
     36 import android.app.UiAutomation;
     37 import android.content.BroadcastReceiver;
     38 import android.content.ComponentName;
     39 import android.content.ContentResolver;
     40 import android.content.Context;
     41 import android.content.DialogInterface;
     42 import android.content.DialogInterface.OnClickListener;
     43 import android.content.Intent;
     44 import android.content.IntentFilter;
     45 import android.content.ServiceConnection;
     46 import android.content.pm.PackageManager;
     47 import android.content.pm.ParceledListSlice;
     48 import android.content.pm.ResolveInfo;
     49 import android.content.pm.ServiceInfo;
     50 import android.content.pm.UserInfo;
     51 import android.database.ContentObserver;
     52 import android.graphics.Point;
     53 import android.graphics.Rect;
     54 import android.graphics.Region;
     55 import android.hardware.display.DisplayManager;
     56 import android.hardware.fingerprint.IFingerprintService;
     57 import android.hardware.input.InputManager;
     58 import android.media.AudioManagerInternal;
     59 import android.net.Uri;
     60 import android.os.Binder;
     61 import android.os.Build;
     62 import android.os.Bundle;
     63 import android.os.Handler;
     64 import android.os.IBinder;
     65 import android.os.Looper;
     66 import android.os.Message;
     67 import android.os.PowerManager;
     68 import android.os.Process;
     69 import android.os.RemoteCallbackList;
     70 import android.os.RemoteException;
     71 import android.os.ServiceManager;
     72 import android.os.SystemClock;
     73 import android.os.UserHandle;
     74 import android.os.UserManager;
     75 import android.os.UserManagerInternal;
     76 import android.provider.Settings;
     77 import android.provider.SettingsStringUtil;
     78 import android.provider.SettingsStringUtil.ComponentNameSet;
     79 import android.provider.SettingsStringUtil.SettingStringHelper;
     80 import android.text.TextUtils;
     81 import android.text.TextUtils.SimpleStringSplitter;
     82 import android.util.IntArray;
     83 import android.util.Slog;
     84 import android.util.SparseArray;
     85 import android.view.Display;
     86 import android.view.IWindow;
     87 import android.view.InputDevice;
     88 import android.view.KeyCharacterMap;
     89 import android.view.KeyEvent;
     90 import android.view.MagnificationSpec;
     91 import android.view.View;
     92 import android.view.WindowInfo;
     93 import android.view.WindowManager;
     94 import android.view.WindowManagerInternal;
     95 import android.view.accessibility.AccessibilityCache;
     96 import android.view.accessibility.AccessibilityEvent;
     97 import android.view.accessibility.AccessibilityInteractionClient;
     98 import android.view.accessibility.AccessibilityManager;
     99 import android.view.accessibility.AccessibilityNodeInfo;
    100 import android.view.accessibility.AccessibilityWindowInfo;
    101 import android.view.accessibility.IAccessibilityInteractionConnection;
    102 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
    103 import android.view.accessibility.IAccessibilityManager;
    104 import android.view.accessibility.IAccessibilityManagerClient;
    105 
    106 import com.android.internal.R;
    107 import com.android.internal.annotations.GuardedBy;
    108 import com.android.internal.annotations.VisibleForTesting;
    109 import com.android.internal.content.PackageMonitor;
    110 import com.android.internal.os.SomeArgs;
    111 import com.android.internal.util.DumpUtils;
    112 import com.android.internal.util.IntPair;
    113 import com.android.server.LocalServices;
    114 import com.android.server.policy.AccessibilityShortcutController;
    115 import com.android.server.statusbar.StatusBarManagerInternal;
    116 
    117 import org.xmlpull.v1.XmlPullParserException;
    118 
    119 import java.io.FileDescriptor;
    120 import java.io.IOException;
    121 import java.io.PrintWriter;
    122 import java.util.ArrayList;
    123 import java.util.Arrays;
    124 import java.util.Collections;
    125 import java.util.HashMap;
    126 import java.util.HashSet;
    127 import java.util.Iterator;
    128 import java.util.List;
    129 import java.util.Map;
    130 import java.util.Set;
    131 import java.util.concurrent.CopyOnWriteArrayList;
    132 import java.util.function.Consumer;
    133 
    134 /**
    135  * This class is instantiated by the system as a system level service and can be
    136  * accessed only by the system. The task of this service is to be a centralized
    137  * event dispatch for {@link AccessibilityEvent}s generated across all processes
    138  * on the device. Events are dispatched to {@link AccessibilityService}s.
    139  */
    140 public class AccessibilityManagerService extends IAccessibilityManager.Stub {
    141 
    142     private static final boolean DEBUG = false;
    143 
    144     private static final String LOG_TAG = "AccessibilityManagerService";
    145 
    146     // TODO: This is arbitrary. When there is time implement this by watching
    147     //       when that accessibility services are bound.
    148     private static final int WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS = 3000;
    149 
    150     private static final int WAIT_WINDOWS_TIMEOUT_MILLIS = 5000;
    151 
    152     // TODO: Restructure service initialization so services aren't connected before all of
    153     //       their capabilities are ready.
    154     private static final int WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS = 1000;
    155 
    156     private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
    157         "registerUiTestAutomationService";
    158 
    159     private static final String TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED =
    160             "temporaryEnableAccessibilityStateUntilKeyguardRemoved";
    161 
    162     private static final String GET_WINDOW_TOKEN = "getWindowToken";
    163 
    164     private static final String SET_PIP_ACTION_REPLACEMENT =
    165             "setPictureInPictureActionReplacingConnection";
    166 
    167     private static final ComponentName sFakeAccessibilityServiceComponentName =
    168             new ComponentName("foo.bar", "FakeService");
    169 
    170     private static final String FUNCTION_DUMP = "dump";
    171 
    172     private static final char COMPONENT_NAME_SEPARATOR = ':';
    173 
    174     private static final int OWN_PROCESS_ID = android.os.Process.myPid();
    175 
    176     // Each service has an ID. Also provide one for magnification gesture handling
    177     public static final int MAGNIFICATION_GESTURE_HANDLER_ID = 0;
    178 
    179     private static int sIdCounter = MAGNIFICATION_GESTURE_HANDLER_ID + 1;
    180 
    181     private static int sNextWindowId;
    182 
    183     private final Context mContext;
    184 
    185     private final Object mLock = new Object();
    186 
    187     private final SimpleStringSplitter mStringColonSplitter =
    188             new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
    189 
    190     private final Rect mTempRect = new Rect();
    191 
    192     private final Rect mTempRect1 = new Rect();
    193 
    194     private final Point mTempPoint = new Point();
    195 
    196     private final PackageManager mPackageManager;
    197 
    198     private final PowerManager mPowerManager;
    199 
    200     private final WindowManagerInternal mWindowManagerService;
    201 
    202     private final SecurityPolicy mSecurityPolicy;
    203 
    204     private final MainHandler mMainHandler;
    205 
    206     private MagnificationController mMagnificationController;
    207 
    208     private InteractionBridge mInteractionBridge;
    209 
    210     private AlertDialog mEnableTouchExplorationDialog;
    211 
    212     private AccessibilityInputFilter mInputFilter;
    213 
    214     private boolean mHasInputFilter;
    215 
    216     private KeyEventDispatcher mKeyEventDispatcher;
    217 
    218     private MotionEventInjector mMotionEventInjector;
    219 
    220     private FingerprintGestureDispatcher mFingerprintGestureDispatcher;
    221 
    222     private final Set<ComponentName> mTempComponentNameSet = new HashSet<>();
    223 
    224     private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList =
    225             new ArrayList<>();
    226 
    227     private final IntArray mTempIntArray = new IntArray(0);
    228 
    229     private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients =
    230             new RemoteCallbackList<>();
    231 
    232     private final SparseArray<AccessibilityConnectionWrapper> mGlobalInteractionConnections =
    233             new SparseArray<>();
    234 
    235     private AccessibilityConnectionWrapper mPictureInPictureActionReplacingConnection;
    236 
    237     private final SparseArray<IBinder> mGlobalWindowTokens = new SparseArray<>();
    238 
    239     private final SparseArray<UserState> mUserStates = new SparseArray<>();
    240 
    241     private final UserManager mUserManager;
    242 
    243     private int mCurrentUserId = UserHandle.USER_SYSTEM;
    244 
    245     //TODO: Remove this hack
    246     private boolean mInitialized;
    247 
    248     private WindowsForAccessibilityCallback mWindowsForAccessibilityCallback;
    249 
    250     private boolean mIsAccessibilityButtonShown;
    251 
    252     private UserState getCurrentUserStateLocked() {
    253         return getUserStateLocked(mCurrentUserId);
    254     }
    255 
    256     /**
    257      * Creates a new instance.
    258      *
    259      * @param context A {@link Context} instance.
    260      */
    261     public AccessibilityManagerService(Context context) {
    262         mContext = context;
    263         mPackageManager = mContext.getPackageManager();
    264         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    265         mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
    266         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
    267         mSecurityPolicy = new SecurityPolicy();
    268         mMainHandler = new MainHandler(mContext.getMainLooper());
    269         registerBroadcastReceivers();
    270         new AccessibilityContentObserver(mMainHandler).register(
    271                 context.getContentResolver());
    272     }
    273 
    274     private UserState getUserStateLocked(int userId) {
    275         UserState state = mUserStates.get(userId);
    276         if (state == null) {
    277             state = new UserState(userId);
    278             mUserStates.put(userId, state);
    279         }
    280         return state;
    281     }
    282 
    283     private void registerBroadcastReceivers() {
    284         PackageMonitor monitor = new PackageMonitor() {
    285             @Override
    286             public void onSomePackagesChanged() {
    287                 synchronized (mLock) {
    288                     // Only the profile parent can install accessibility services.
    289                     // Therefore we ignore packages from linked profiles.
    290                     if (getChangingUserId() != mCurrentUserId) {
    291                         return;
    292                     }
    293                     // We will update when the automation service dies.
    294                     UserState userState = getCurrentUserStateLocked();
    295                     // We have to reload the installed services since some services may
    296                     // have different attributes, resolve info (does not support equals),
    297                     // etc. Remove them then to force reload.
    298                     userState.mInstalledServices.clear();
    299                     if (!userState.isUiAutomationSuppressingOtherServices()) {
    300                         if (readConfigurationForUserStateLocked(userState)) {
    301                             onUserStateChangedLocked(userState);
    302                         }
    303                     }
    304                 }
    305             }
    306 
    307             @Override
    308             public void onPackageUpdateFinished(String packageName, int uid) {
    309                 // Unbind all services from this package, and then update the user state to
    310                 // re-bind new versions of them.
    311                 synchronized (mLock) {
    312                     final int userId = getChangingUserId();
    313                     if (userId != mCurrentUserId) {
    314                         return;
    315                     }
    316                     UserState userState = getUserStateLocked(userId);
    317                     boolean unboundAService = false;
    318                     for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
    319                         Service boundService = userState.mBoundServices.get(i);
    320                         String servicePkg = boundService.mComponentName.getPackageName();
    321                         if (servicePkg.equals(packageName)) {
    322                             boundService.unbindLocked();
    323                             unboundAService = true;
    324                         }
    325                     }
    326                     if (unboundAService) {
    327                         onUserStateChangedLocked(userState);
    328                     }
    329                 }
    330             }
    331 
    332             @Override
    333             public void onPackageRemoved(String packageName, int uid) {
    334                 synchronized (mLock) {
    335                     final int userId = getChangingUserId();
    336                     // Only the profile parent can install accessibility services.
    337                     // Therefore we ignore packages from linked profiles.
    338                     if (userId != mCurrentUserId) {
    339                         return;
    340                     }
    341                     UserState userState = getUserStateLocked(userId);
    342                     Iterator<ComponentName> it = userState.mEnabledServices.iterator();
    343                     while (it.hasNext()) {
    344                         ComponentName comp = it.next();
    345                         String compPkg = comp.getPackageName();
    346                         if (compPkg.equals(packageName)) {
    347                             it.remove();
    348                             // Update the enabled services setting.
    349                             persistComponentNamesToSettingLocked(
    350                                     Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
    351                                     userState.mEnabledServices, userId);
    352                             // Update the touch exploration granted services setting.
    353                             userState.mTouchExplorationGrantedServices.remove(comp);
    354                             persistComponentNamesToSettingLocked(
    355                                     Settings.Secure.
    356                                     TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
    357                                     userState.mTouchExplorationGrantedServices, userId);
    358                             // We will update when the automation service dies.
    359                             if (!userState.isUiAutomationSuppressingOtherServices()) {
    360                                 onUserStateChangedLocked(userState);
    361                             }
    362                             return;
    363                         }
    364                     }
    365                 }
    366             }
    367 
    368             @Override
    369             public boolean onHandleForceStop(Intent intent, String[] packages,
    370                     int uid, boolean doit) {
    371                 synchronized (mLock) {
    372                     final int userId = getChangingUserId();
    373                     // Only the profile parent can install accessibility services.
    374                     // Therefore we ignore packages from linked profiles.
    375                     if (userId != mCurrentUserId) {
    376                         return false;
    377                     }
    378                     UserState userState = getUserStateLocked(userId);
    379                     Iterator<ComponentName> it = userState.mEnabledServices.iterator();
    380                     while (it.hasNext()) {
    381                         ComponentName comp = it.next();
    382                         String compPkg = comp.getPackageName();
    383                         for (String pkg : packages) {
    384                             if (compPkg.equals(pkg)) {
    385                                 if (!doit) {
    386                                     return true;
    387                                 }
    388                                 it.remove();
    389                                 persistComponentNamesToSettingLocked(
    390                                         Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
    391                                         userState.mEnabledServices, userId);
    392                                 // We will update when the automation service dies.
    393                                 if (!userState.isUiAutomationSuppressingOtherServices()) {
    394                                     onUserStateChangedLocked(userState);
    395                                 }
    396                             }
    397                         }
    398                     }
    399                     return false;
    400                 }
    401             }
    402         };
    403 
    404         // package changes
    405         monitor.register(mContext, null,  UserHandle.ALL, true);
    406 
    407         // user change and unlock
    408         IntentFilter intentFilter = new IntentFilter();
    409         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
    410         intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
    411         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
    412         intentFilter.addAction(Intent.ACTION_USER_PRESENT);
    413         intentFilter.addAction(Intent.ACTION_SETTING_RESTORED);
    414 
    415         mContext.registerReceiverAsUser(new BroadcastReceiver() {
    416             @Override
    417             public void onReceive(Context context, Intent intent) {
    418                 String action = intent.getAction();
    419                 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
    420                     switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
    421                 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
    422                     unlockUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
    423                 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
    424                     removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
    425                 } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
    426                     // We will update when the automation service dies.
    427                     synchronized (mLock) {
    428                         UserState userState = getCurrentUserStateLocked();
    429                         if (!userState.isUiAutomationSuppressingOtherServices()) {
    430                             if (readConfigurationForUserStateLocked(userState)) {
    431                                 onUserStateChangedLocked(userState);
    432                             }
    433                         }
    434                     }
    435                 } else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
    436                     final String which = intent.getStringExtra(Intent.EXTRA_SETTING_NAME);
    437                     if (Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES.equals(which)) {
    438                         synchronized (mLock) {
    439                             restoreEnabledAccessibilityServicesLocked(
    440                                     intent.getStringExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE),
    441                                     intent.getStringExtra(Intent.EXTRA_SETTING_NEW_VALUE));
    442                         }
    443                     }
    444                 }
    445             }
    446         }, UserHandle.ALL, intentFilter, null, null);
    447     }
    448 
    449     @Override
    450     public long addClient(IAccessibilityManagerClient client, int userId) {
    451         synchronized (mLock) {
    452             // We treat calls from a profile as if made by its parent as profiles
    453             // share the accessibility state of the parent. The call below
    454             // performs the current profile parent resolution.
    455             final int resolvedUserId = mSecurityPolicy
    456                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    457             // If the client is from a process that runs across users such as
    458             // the system UI or the system we add it to the global state that
    459             // is shared across users.
    460             UserState userState = getUserStateLocked(resolvedUserId);
    461             if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
    462                 mGlobalClients.register(client);
    463                 if (DEBUG) {
    464                     Slog.i(LOG_TAG, "Added global client for pid:" + Binder.getCallingPid());
    465                 }
    466                 return IntPair.of(
    467                         userState.getClientState(), userState.mLastSentRelevantEventTypes);
    468             } else {
    469                 userState.mUserClients.register(client);
    470                 // If this client is not for the current user we do not
    471                 // return a state since it is not for the foreground user.
    472                 // We will send the state to the client on a user switch.
    473                 if (DEBUG) {
    474                     Slog.i(LOG_TAG, "Added user client for pid:" + Binder.getCallingPid()
    475                             + " and userId:" + mCurrentUserId);
    476                 }
    477                 return IntPair.of(
    478                         (resolvedUserId == mCurrentUserId) ? userState.getClientState() : 0,
    479                         userState.mLastSentRelevantEventTypes);
    480             }
    481         }
    482     }
    483 
    484     @Override
    485     public void sendAccessibilityEvent(AccessibilityEvent event, int userId) {
    486         boolean dispatchEvent = false;
    487 
    488         synchronized (mLock) {
    489             if (event.getWindowId() ==
    490                 AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID) {
    491                 // The replacer window isn't shown to services. Move its events into the pip.
    492                 AccessibilityWindowInfo pip = mSecurityPolicy.getPictureInPictureWindow();
    493                 if (pip != null) {
    494                     int pipId = pip.getId();
    495                     event.setWindowId(pipId);
    496                 }
    497             }
    498 
    499             // We treat calls from a profile as if made by its parent as profiles
    500             // share the accessibility state of the parent. The call below
    501             // performs the current profile parent resolution..
    502             final int resolvedUserId = mSecurityPolicy
    503                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    504             // This method does nothing for a background user.
    505             if (resolvedUserId == mCurrentUserId) {
    506                 if (mSecurityPolicy.canDispatchAccessibilityEventLocked(event)) {
    507                     mSecurityPolicy.updateActiveAndAccessibilityFocusedWindowLocked(
    508                             event.getWindowId(), event.getSourceNodeId(),
    509                             event.getEventType(), event.getAction());
    510                     mSecurityPolicy.updateEventSourceLocked(event);
    511                     dispatchEvent = true;
    512                 }
    513                 if (mHasInputFilter && mInputFilter != null) {
    514                     mMainHandler.obtainMessage(
    515                             MainHandler.MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER,
    516                             AccessibilityEvent.obtain(event)).sendToTarget();
    517                 }
    518             }
    519         }
    520 
    521         if (dispatchEvent) {
    522             // Make sure clients receiving this event will be able to get the
    523             // current state of the windows as the window manager may be delaying
    524             // the computation for performance reasons.
    525             if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
    526                     && mWindowsForAccessibilityCallback != null) {
    527                 WindowManagerInternal wm = LocalServices.getService(WindowManagerInternal.class);
    528                 wm.computeWindowsForAccessibility();
    529             }
    530             synchronized (mLock) {
    531                 notifyAccessibilityServicesDelayedLocked(event, false);
    532                 notifyAccessibilityServicesDelayedLocked(event, true);
    533             }
    534         }
    535 
    536         if (OWN_PROCESS_ID != Binder.getCallingPid()) {
    537             event.recycle();
    538         }
    539     }
    540 
    541     @Override
    542     public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) {
    543         synchronized (mLock) {
    544             // We treat calls from a profile as if made by its parent as profiles
    545             // share the accessibility state of the parent. The call below
    546             // performs the current profile parent resolution.
    547             final int resolvedUserId = mSecurityPolicy
    548                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    549             // The automation service is a fake one and should not be reported
    550             // to clients as being installed - it really is not.
    551             UserState userState = getUserStateLocked(resolvedUserId);
    552             if (userState.mUiAutomationService != null) {
    553                 List<AccessibilityServiceInfo> installedServices = new ArrayList<>();
    554                 installedServices.addAll(userState.mInstalledServices);
    555                 installedServices.remove(userState.mUiAutomationService.mAccessibilityServiceInfo);
    556                 return installedServices;
    557             }
    558             return userState.mInstalledServices;
    559         }
    560     }
    561 
    562     @Override
    563     public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType,
    564             int userId) {
    565         synchronized (mLock) {
    566             // We treat calls from a profile as if made by its parent as profiles
    567             // share the accessibility state of the parent. The call below
    568             // performs the current profile parent resolution.
    569             final int resolvedUserId = mSecurityPolicy
    570                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    571 
    572             // The automation service can suppress other services.
    573             final UserState userState = getUserStateLocked(resolvedUserId);
    574             if (userState.isUiAutomationSuppressingOtherServices()) {
    575                 return Collections.emptyList();
    576             }
    577 
    578             final List<Service> services = userState.mBoundServices;
    579             final int serviceCount = services.size();
    580             final List<AccessibilityServiceInfo> result = new ArrayList<>(serviceCount);
    581             for (int i = 0; i < serviceCount; ++i) {
    582                 final Service service = services.get(i);
    583                 // Don't report the UIAutomation (fake service)
    584                 if (!sFakeAccessibilityServiceComponentName.equals(service.mComponentName)
    585                         && (service.mFeedbackType & feedbackType) != 0) {
    586                     result.add(service.mAccessibilityServiceInfo);
    587                 }
    588             }
    589             return result;
    590         }
    591     }
    592 
    593     @Override
    594     public void interrupt(int userId) {
    595         List<IAccessibilityServiceClient> interfacesToInterrupt;
    596         synchronized (mLock) {
    597             // We treat calls from a profile as if made by its parent as profiles
    598             // share the accessibility state of the parent. The call below
    599             // performs the current profile parent resolution.
    600             final int resolvedUserId = mSecurityPolicy
    601                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    602             // This method does nothing for a background user.
    603             if (resolvedUserId != mCurrentUserId) {
    604                 return;
    605             }
    606             List<Service> services = getUserStateLocked(resolvedUserId).mBoundServices;
    607             int numServices = services.size();
    608             interfacesToInterrupt = new ArrayList<>(numServices);
    609             for (int i = 0; i < numServices; i++) {
    610                 Service service = services.get(i);
    611                 IBinder a11yServiceBinder = service.mService;
    612                 IAccessibilityServiceClient a11yServiceInterface = service.mServiceInterface;
    613                 if ((a11yServiceBinder != null) && (a11yServiceInterface != null)) {
    614                     interfacesToInterrupt.add(a11yServiceInterface);
    615                 }
    616             }
    617         }
    618         for (int i = 0, count = interfacesToInterrupt.size(); i < count; i++) {
    619             try {
    620                 interfacesToInterrupt.get(i).onInterrupt();
    621             } catch (RemoteException re) {
    622                 Slog.e(LOG_TAG, "Error sending interrupt request to "
    623                         + interfacesToInterrupt.get(i), re);
    624             }
    625         }
    626     }
    627 
    628     @Override
    629     public int addAccessibilityInteractionConnection(IWindow windowToken,
    630             IAccessibilityInteractionConnection connection, int userId) throws RemoteException {
    631         synchronized (mLock) {
    632             // We treat calls from a profile as if made by its parent as profiles
    633             // share the accessibility state of the parent. The call below
    634             // performs the current profile parent resolution.
    635             final int resolvedUserId = mSecurityPolicy
    636                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    637             final int windowId = sNextWindowId++;
    638             // If the window is from a process that runs across users such as
    639             // the system UI or the system we add it to the global state that
    640             // is shared across users.
    641             if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
    642                 AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
    643                         windowId, connection, UserHandle.USER_ALL);
    644                 wrapper.linkToDeath();
    645                 mGlobalInteractionConnections.put(windowId, wrapper);
    646                 mGlobalWindowTokens.put(windowId, windowToken.asBinder());
    647                 if (DEBUG) {
    648                     Slog.i(LOG_TAG, "Added global connection for pid:" + Binder.getCallingPid()
    649                             + " with windowId: " + windowId + " and  token: " + windowToken.asBinder());
    650                 }
    651             } else {
    652                 AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
    653                         windowId, connection, resolvedUserId);
    654                 wrapper.linkToDeath();
    655                 UserState userState = getUserStateLocked(resolvedUserId);
    656                 userState.mInteractionConnections.put(windowId, wrapper);
    657                 userState.mWindowTokens.put(windowId, windowToken.asBinder());
    658                 if (DEBUG) {
    659                     Slog.i(LOG_TAG, "Added user connection for pid:" + Binder.getCallingPid()
    660                             + " with windowId: " + windowId + " and userId:" + mCurrentUserId
    661                             + " and  token: " + windowToken.asBinder());
    662                 }
    663             }
    664             return windowId;
    665         }
    666     }
    667 
    668     @Override
    669     public void removeAccessibilityInteractionConnection(IWindow window) {
    670         synchronized (mLock) {
    671             // We treat calls from a profile as if made by its parent as profiles
    672             // share the accessibility state of the parent. The call below
    673             // performs the current profile parent resolution.
    674             mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
    675                     UserHandle.getCallingUserId());
    676             IBinder token = window.asBinder();
    677             final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
    678                     token, mGlobalWindowTokens, mGlobalInteractionConnections);
    679             if (removedWindowId >= 0) {
    680                 if (DEBUG) {
    681                     Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
    682                             + " with windowId: " + removedWindowId + " and token: " + window.asBinder());
    683                 }
    684                 return;
    685             }
    686             final int userCount = mUserStates.size();
    687             for (int i = 0; i < userCount; i++) {
    688                 UserState userState = mUserStates.valueAt(i);
    689                 final int removedWindowIdForUser =
    690                         removeAccessibilityInteractionConnectionInternalLocked(
    691                         token, userState.mWindowTokens, userState.mInteractionConnections);
    692                 if (removedWindowIdForUser >= 0) {
    693                     if (DEBUG) {
    694                         Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
    695                                 + " with windowId: " + removedWindowIdForUser + " and userId:"
    696                                 + mUserStates.keyAt(i) + " and token: " + window.asBinder());
    697                     }
    698                     return;
    699                 }
    700             }
    701         }
    702     }
    703 
    704     private int removeAccessibilityInteractionConnectionInternalLocked(IBinder windowToken,
    705             SparseArray<IBinder> windowTokens,
    706             SparseArray<AccessibilityConnectionWrapper> interactionConnections) {
    707         final int count = windowTokens.size();
    708         for (int i = 0; i < count; i++) {
    709             if (windowTokens.valueAt(i) == windowToken) {
    710                 final int windowId = windowTokens.keyAt(i);
    711                 windowTokens.removeAt(i);
    712                 AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId);
    713                 wrapper.unlinkToDeath();
    714                 interactionConnections.remove(windowId);
    715                 return windowId;
    716             }
    717         }
    718         return -1;
    719     }
    720 
    721     @Override
    722     public void setPictureInPictureActionReplacingConnection(
    723             IAccessibilityInteractionConnection connection) throws RemoteException {
    724         mSecurityPolicy.enforceCallingPermission(Manifest.permission.MODIFY_ACCESSIBILITY_DATA,
    725                 SET_PIP_ACTION_REPLACEMENT);
    726         synchronized (mLock) {
    727             if (mPictureInPictureActionReplacingConnection != null) {
    728                 mPictureInPictureActionReplacingConnection.unlinkToDeath();
    729                 mPictureInPictureActionReplacingConnection = null;
    730             }
    731             if (connection != null) {
    732                 AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
    733                         AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID,
    734                         connection, UserHandle.USER_ALL);
    735                 mPictureInPictureActionReplacingConnection = wrapper;
    736                 wrapper.linkToDeath();
    737             }
    738             mSecurityPolicy.notifyWindowsChanged();
    739         }
    740     }
    741 
    742     @Override
    743     public void registerUiTestAutomationService(IBinder owner,
    744             IAccessibilityServiceClient serviceClient,
    745             AccessibilityServiceInfo accessibilityServiceInfo,
    746             int flags) {
    747         mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
    748                 FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE);
    749 
    750         accessibilityServiceInfo.setComponentName(sFakeAccessibilityServiceComponentName);
    751 
    752         synchronized (mLock) {
    753             UserState userState = getCurrentUserStateLocked();
    754 
    755             if (userState.mUiAutomationService != null) {
    756                 throw new IllegalStateException("UiAutomationService " + serviceClient
    757                         + "already registered!");
    758             }
    759 
    760             try {
    761                 owner.linkToDeath(userState.mUiAutomationSerivceOnwerDeathRecipient, 0);
    762             } catch (RemoteException re) {
    763                 Slog.e(LOG_TAG, "Couldn't register for the death of a"
    764                         + " UiTestAutomationService!", re);
    765                 return;
    766             }
    767 
    768             userState.mUiAutomationServiceOwner = owner;
    769             userState.mUiAutomationServiceClient = serviceClient;
    770             userState.mUiAutomationFlags = flags;
    771             userState.mInstalledServices.add(accessibilityServiceInfo);
    772             if ((flags & UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0) {
    773                 // Set the temporary state, and use it instead of settings
    774                 userState.mIsTouchExplorationEnabled = false;
    775                 userState.mIsDisplayMagnificationEnabled = false;
    776                 userState.mIsNavBarMagnificationEnabled = false;
    777                 userState.mIsAutoclickEnabled = false;
    778                 userState.mEnabledServices.clear();
    779             }
    780             userState.mEnabledServices.add(sFakeAccessibilityServiceComponentName);
    781             userState.mTouchExplorationGrantedServices.add(sFakeAccessibilityServiceComponentName);
    782 
    783             // Use the new state instead of settings.
    784             onUserStateChangedLocked(userState);
    785         }
    786     }
    787 
    788     @Override
    789     public void unregisterUiTestAutomationService(IAccessibilityServiceClient serviceClient) {
    790         synchronized (mLock) {
    791             UserState userState = getCurrentUserStateLocked();
    792             // Automation service is not bound, so pretend it died to perform clean up.
    793             if (userState.mUiAutomationService != null
    794                     && serviceClient != null
    795                     && userState.mUiAutomationService.mServiceInterface != null
    796                     && userState.mUiAutomationService.mServiceInterface.asBinder()
    797                     == serviceClient.asBinder()) {
    798                 userState.mUiAutomationService.binderDied();
    799             } else {
    800                 throw new IllegalStateException("UiAutomationService " + serviceClient
    801                         + " not registered!");
    802             }
    803         }
    804     }
    805 
    806     @Override
    807     public void temporaryEnableAccessibilityStateUntilKeyguardRemoved(
    808             ComponentName service, boolean touchExplorationEnabled) {
    809         mSecurityPolicy.enforceCallingPermission(
    810                 Manifest.permission.TEMPORARY_ENABLE_ACCESSIBILITY,
    811                 TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED);
    812         if (!mWindowManagerService.isKeyguardLocked()) {
    813             return;
    814         }
    815         synchronized (mLock) {
    816             // Set the temporary state.
    817             UserState userState = getCurrentUserStateLocked();
    818 
    819             // This is a nop if UI automation is enabled.
    820             if (userState.isUiAutomationSuppressingOtherServices()) {
    821                 return;
    822             }
    823 
    824             userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
    825             userState.mIsDisplayMagnificationEnabled = false;
    826             userState.mIsNavBarMagnificationEnabled = false;
    827             userState.mIsAutoclickEnabled = false;
    828             userState.mEnabledServices.clear();
    829             userState.mEnabledServices.add(service);
    830             userState.mBindingServices.clear();
    831             userState.mTouchExplorationGrantedServices.clear();
    832             userState.mTouchExplorationGrantedServices.add(service);
    833 
    834             // User the current state instead settings.
    835             onUserStateChangedLocked(userState);
    836         }
    837     }
    838 
    839     @Override
    840     public IBinder getWindowToken(int windowId, int userId) {
    841         mSecurityPolicy.enforceCallingPermission(
    842                 Manifest.permission.RETRIEVE_WINDOW_TOKEN,
    843                 GET_WINDOW_TOKEN);
    844         synchronized (mLock) {
    845             // We treat calls from a profile as if made by its parent as profiles
    846             // share the accessibility state of the parent. The call below
    847             // performs the current profile parent resolution.
    848             final int resolvedUserId = mSecurityPolicy
    849                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
    850             if (resolvedUserId != mCurrentUserId) {
    851                 return null;
    852             }
    853             if (mSecurityPolicy.findA11yWindowInfoById(windowId) == null) {
    854                 return null;
    855             }
    856             IBinder token = mGlobalWindowTokens.get(windowId);
    857             if (token != null) {
    858                 return token;
    859             }
    860             return getCurrentUserStateLocked().mWindowTokens.get(windowId);
    861         }
    862     }
    863 
    864     /**
    865      * Invoked remotely over AIDL by SysUi when the accessibility button within the system's
    866      * navigation area has been clicked.
    867      */
    868     @Override
    869     public void notifyAccessibilityButtonClicked() {
    870         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
    871                 != PackageManager.PERMISSION_GRANTED) {
    872             throw new SecurityException("Caller does not hold permission "
    873                     + android.Manifest.permission.STATUS_BAR_SERVICE);
    874         }
    875         synchronized (mLock) {
    876             notifyAccessibilityButtonClickedLocked();
    877         }
    878     }
    879 
    880     /**
    881      * Invoked remotely over AIDL by SysUi when the visibility of the accessibility
    882      * button within the system's navigation area has changed.
    883      *
    884      * @param shown {@code true} if the accessibility button is shown to the
    885      *                  user, {@code false} otherwise
    886      */
    887     @Override
    888     public void notifyAccessibilityButtonVisibilityChanged(boolean shown) {
    889         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
    890                 != PackageManager.PERMISSION_GRANTED) {
    891             throw new SecurityException("Caller does not hold permission "
    892                     + android.Manifest.permission.STATUS_BAR_SERVICE);
    893         }
    894         synchronized (mLock) {
    895             notifyAccessibilityButtonVisibilityChangedLocked(shown);
    896         }
    897     }
    898 
    899 
    900     boolean onGesture(int gestureId) {
    901         synchronized (mLock) {
    902             boolean handled = notifyGestureLocked(gestureId, false);
    903             if (!handled) {
    904                 handled = notifyGestureLocked(gestureId, true);
    905             }
    906             return handled;
    907         }
    908     }
    909 
    910     @VisibleForTesting
    911     public boolean notifyKeyEvent(KeyEvent event, int policyFlags) {
    912         synchronized (mLock) {
    913             List<Service> boundServices = getCurrentUserStateLocked().mBoundServices;
    914             if (boundServices.isEmpty()) {
    915                 return false;
    916             }
    917             return getKeyEventDispatcher().notifyKeyEventLocked(event, policyFlags, boundServices);
    918         }
    919     }
    920 
    921     /**
    922      * Called by the MagnificationController when the state of display
    923      * magnification changes.
    924      *
    925      * @param region the new magnified region, may be empty if
    926      *               magnification is not enabled (e.g. scale is 1)
    927      * @param scale the new scale
    928      * @param centerX the new screen-relative center X coordinate
    929      * @param centerY the new screen-relative center Y coordinate
    930      */
    931     public void notifyMagnificationChanged(@NonNull Region region,
    932             float scale, float centerX, float centerY) {
    933         synchronized (mLock) {
    934             notifyClearAccessibilityCacheLocked();
    935             notifyMagnificationChangedLocked(region, scale, centerX, centerY);
    936         }
    937     }
    938 
    939     /**
    940      * Called by AccessibilityInputFilter when it creates or destroys the motionEventInjector.
    941      * Not using a getter because the AccessibilityInputFilter isn't thread-safe
    942      *
    943      * @param motionEventInjector The new value of the motionEventInjector. May be null.
    944      */
    945     void setMotionEventInjector(MotionEventInjector motionEventInjector) {
    946         synchronized (mLock) {
    947             mMotionEventInjector = motionEventInjector;
    948             // We may be waiting on this object being set
    949             mLock.notifyAll();
    950         }
    951     }
    952 
    953     /**
    954      * Gets a point within the accessibility focused node where we can send down
    955      * and up events to perform a click.
    956      *
    957      * @param outPoint The click point to populate.
    958      * @return Whether accessibility a click point was found and set.
    959      */
    960     // TODO: (multi-display) Make sure this works for multiple displays.
    961     boolean getAccessibilityFocusClickPointInScreen(Point outPoint) {
    962         return getInteractionBridge().getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
    963     }
    964 
    965     /**
    966      * Perform an accessibility action on the view that currently has accessibility focus.
    967      * Has no effect if no item has accessibility focus, if the item with accessibility
    968      * focus does not expose the specified action, or if the action fails.
    969      *
    970      * @param actionId The id of the action to perform.
    971      *
    972      * @return {@code true} if the action was performed. {@code false} if it was not.
    973      */
    974     public boolean performActionOnAccessibilityFocusedItem(
    975             AccessibilityNodeInfo.AccessibilityAction action) {
    976         return getInteractionBridge().performActionOnAccessibilityFocusedItemNotLocked(action);
    977     }
    978 
    979     /**
    980      * Gets the bounds of a window.
    981      *
    982      * @param outBounds The output to which to write the bounds.
    983      */
    984     boolean getWindowBounds(int windowId, Rect outBounds) {
    985         IBinder token;
    986         synchronized (mLock) {
    987             token = mGlobalWindowTokens.get(windowId);
    988             if (token == null) {
    989                 token = getCurrentUserStateLocked().mWindowTokens.get(windowId);
    990             }
    991         }
    992         mWindowManagerService.getWindowFrame(token, outBounds);
    993         if (!outBounds.isEmpty()) {
    994             return true;
    995         }
    996         return false;
    997     }
    998 
    999     boolean accessibilityFocusOnlyInActiveWindow() {
   1000         synchronized (mLock) {
   1001             return mWindowsForAccessibilityCallback == null;
   1002         }
   1003     }
   1004 
   1005     int getActiveWindowId() {
   1006         return mSecurityPolicy.getActiveWindowId();
   1007     }
   1008 
   1009     void onTouchInteractionStart() {
   1010         mSecurityPolicy.onTouchInteractionStart();
   1011     }
   1012 
   1013     void onTouchInteractionEnd() {
   1014         mSecurityPolicy.onTouchInteractionEnd();
   1015     }
   1016 
   1017     private void switchUser(int userId) {
   1018         synchronized (mLock) {
   1019             if (mCurrentUserId == userId && mInitialized) {
   1020                 return;
   1021             }
   1022 
   1023             // Disconnect from services for the old user.
   1024             UserState oldUserState = getCurrentUserStateLocked();
   1025             oldUserState.onSwitchToAnotherUser();
   1026 
   1027             // Disable the local managers for the old user.
   1028             if (oldUserState.mUserClients.getRegisteredCallbackCount() > 0) {
   1029                 mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
   1030                         oldUserState.mUserId, 0).sendToTarget();
   1031             }
   1032 
   1033             // Announce user changes only if more that one exist.
   1034             UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
   1035             final boolean announceNewUser = userManager.getUsers().size() > 1;
   1036 
   1037             // The user changed.
   1038             mCurrentUserId = userId;
   1039 
   1040             UserState userState = getCurrentUserStateLocked();
   1041             if (userState.mUiAutomationService != null) {
   1042                 // Switching users disables the UI automation service.
   1043                 userState.mUiAutomationService.binderDied();
   1044             }
   1045 
   1046             readConfigurationForUserStateLocked(userState);
   1047             // Even if reading did not yield change, we have to update
   1048             // the state since the context in which the current user
   1049             // state was used has changed since it was inactive.
   1050             onUserStateChangedLocked(userState);
   1051 
   1052             if (announceNewUser) {
   1053                 // Schedule announcement of the current user if needed.
   1054                 mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
   1055                         WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
   1056             }
   1057         }
   1058     }
   1059 
   1060     private void unlockUser(int userId) {
   1061         synchronized (mLock) {
   1062             int parentUserId = mSecurityPolicy.resolveProfileParentLocked(userId);
   1063             if (parentUserId == mCurrentUserId) {
   1064                 UserState userState = getUserStateLocked(mCurrentUserId);
   1065                 onUserStateChangedLocked(userState);
   1066             }
   1067         }
   1068     }
   1069 
   1070     private void removeUser(int userId) {
   1071         synchronized (mLock) {
   1072             mUserStates.remove(userId);
   1073         }
   1074     }
   1075 
   1076     // Called only during settings restore; currently supports only the owner user
   1077     // TODO: http://b/22388012
   1078     void restoreEnabledAccessibilityServicesLocked(String oldSetting, String newSetting) {
   1079         readComponentNamesFromStringLocked(oldSetting, mTempComponentNameSet, false);
   1080         readComponentNamesFromStringLocked(newSetting, mTempComponentNameSet, true);
   1081 
   1082         UserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
   1083         userState.mEnabledServices.clear();
   1084         userState.mEnabledServices.addAll(mTempComponentNameSet);
   1085         persistComponentNamesToSettingLocked(
   1086                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
   1087                 userState.mEnabledServices,
   1088                 UserHandle.USER_SYSTEM);
   1089         onUserStateChangedLocked(userState);
   1090     }
   1091 
   1092     private InteractionBridge getInteractionBridge() {
   1093         synchronized (mLock) {
   1094             if (mInteractionBridge == null) {
   1095                 mInteractionBridge = new InteractionBridge();
   1096             }
   1097             return mInteractionBridge;
   1098         }
   1099     }
   1100 
   1101     private boolean notifyGestureLocked(int gestureId, boolean isDefault) {
   1102         // TODO: Now we are giving the gestures to the last enabled
   1103         //       service that can handle them which is the last one
   1104         //       in our list since we write the last enabled as the
   1105         //       last record in the enabled services setting. Ideally,
   1106         //       the user should make the call which service handles
   1107         //       gestures. However, only one service should handle
   1108         //       gestures to avoid user frustration when different
   1109         //       behavior is observed from different combinations of
   1110         //       enabled accessibility services.
   1111         UserState state = getCurrentUserStateLocked();
   1112         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1113             Service service = state.mBoundServices.get(i);
   1114             if (service.mRequestTouchExplorationMode && service.mIsDefault == isDefault) {
   1115                 service.notifyGesture(gestureId);
   1116                 return true;
   1117             }
   1118         }
   1119         return false;
   1120     }
   1121 
   1122     private void notifyClearAccessibilityCacheLocked() {
   1123         UserState state = getCurrentUserStateLocked();
   1124         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1125             Service service = state.mBoundServices.get(i);
   1126             service.notifyClearAccessibilityNodeInfoCache();
   1127         }
   1128     }
   1129 
   1130     private void notifyMagnificationChangedLocked(@NonNull Region region,
   1131             float scale, float centerX, float centerY) {
   1132         final UserState state = getCurrentUserStateLocked();
   1133         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1134             final Service service = state.mBoundServices.get(i);
   1135             service.notifyMagnificationChangedLocked(region, scale, centerX, centerY);
   1136         }
   1137     }
   1138 
   1139     private void notifySoftKeyboardShowModeChangedLocked(int showMode) {
   1140         final UserState state = getCurrentUserStateLocked();
   1141         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1142             final Service service = state.mBoundServices.get(i);
   1143             service.notifySoftKeyboardShowModeChangedLocked(showMode);
   1144         }
   1145     }
   1146 
   1147     private void notifyAccessibilityButtonClickedLocked() {
   1148         final UserState state = getCurrentUserStateLocked();
   1149 
   1150         int potentialTargets = state.mIsNavBarMagnificationEnabled ? 1 : 0;
   1151         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1152             final Service service = state.mBoundServices.get(i);
   1153             if (service.mRequestAccessibilityButton) {
   1154                 potentialTargets++;
   1155             }
   1156         }
   1157 
   1158         if (potentialTargets == 0) {
   1159             return;
   1160         }
   1161         if (potentialTargets == 1) {
   1162             if (state.mIsNavBarMagnificationEnabled) {
   1163                 mMainHandler.obtainMessage(
   1164                         MainHandler.MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER).sendToTarget();
   1165                 return;
   1166             } else {
   1167                 for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1168                     final Service service = state.mBoundServices.get(i);
   1169                     if (service.mRequestAccessibilityButton) {
   1170                         service.notifyAccessibilityButtonClickedLocked();
   1171                         return;
   1172                     }
   1173                 }
   1174             }
   1175         } else {
   1176             if (state.mServiceAssignedToAccessibilityButton == null
   1177                     && !state.mIsNavBarMagnificationAssignedToAccessibilityButton) {
   1178                 mMainHandler.obtainMessage(
   1179                         MainHandler.MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER).sendToTarget();
   1180             } else if (state.mIsNavBarMagnificationEnabled
   1181                     && state.mIsNavBarMagnificationAssignedToAccessibilityButton) {
   1182                 mMainHandler.obtainMessage(
   1183                         MainHandler.MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER).sendToTarget();
   1184                 return;
   1185             } else {
   1186                 for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1187                     final Service service = state.mBoundServices.get(i);
   1188                     if (service.mRequestAccessibilityButton && (service.mComponentName.equals(
   1189                             state.mServiceAssignedToAccessibilityButton))) {
   1190                         service.notifyAccessibilityButtonClickedLocked();
   1191                         return;
   1192                     }
   1193                 }
   1194             }
   1195             // The user may have turned off the assigned service or feature
   1196             mMainHandler.obtainMessage(
   1197                     MainHandler.MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER).sendToTarget();
   1198         }
   1199     }
   1200 
   1201     private void notifyAccessibilityButtonVisibilityChangedLocked(boolean available) {
   1202         final UserState state = getCurrentUserStateLocked();
   1203         mIsAccessibilityButtonShown = available;
   1204         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
   1205             final Service service = state.mBoundServices.get(i);
   1206             if (service.mRequestAccessibilityButton) {
   1207                 service.notifyAccessibilityButtonAvailabilityChangedLocked(
   1208                         service.isAccessibilityButtonAvailableLocked(state));
   1209             }
   1210         }
   1211     }
   1212 
   1213     /**
   1214      * Removes an AccessibilityInteractionConnection.
   1215      *
   1216      * @param windowId The id of the window to which the connection is targeted.
   1217      * @param userId The id of the user owning the connection. UserHandle.USER_ALL
   1218      *     if global.
   1219      */
   1220     private void removeAccessibilityInteractionConnectionLocked(int windowId, int userId) {
   1221         if (userId == UserHandle.USER_ALL) {
   1222             mGlobalWindowTokens.remove(windowId);
   1223             mGlobalInteractionConnections.remove(windowId);
   1224         } else {
   1225             UserState userState = getCurrentUserStateLocked();
   1226             userState.mWindowTokens.remove(windowId);
   1227             userState.mInteractionConnections.remove(windowId);
   1228         }
   1229         if (DEBUG) {
   1230             Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
   1231         }
   1232     }
   1233 
   1234     private boolean readInstalledAccessibilityServiceLocked(UserState userState) {
   1235         mTempAccessibilityServiceInfoList.clear();
   1236 
   1237         List<ResolveInfo> installedServices = mPackageManager.queryIntentServicesAsUser(
   1238                 new Intent(AccessibilityService.SERVICE_INTERFACE),
   1239                 PackageManager.GET_SERVICES
   1240                         | PackageManager.GET_META_DATA
   1241                         | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
   1242                         | PackageManager.MATCH_DIRECT_BOOT_AWARE
   1243                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
   1244                 mCurrentUserId);
   1245 
   1246         for (int i = 0, count = installedServices.size(); i < count; i++) {
   1247             ResolveInfo resolveInfo = installedServices.get(i);
   1248             ServiceInfo serviceInfo = resolveInfo.serviceInfo;
   1249             if (!android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE.equals(
   1250                     serviceInfo.permission)) {
   1251                 Slog.w(LOG_TAG, "Skipping accessibilty service " + new ComponentName(
   1252                         serviceInfo.packageName, serviceInfo.name).flattenToShortString()
   1253                         + ": it does not require the permission "
   1254                         + android.Manifest.permission.BIND_ACCESSIBILITY_SERVICE);
   1255                 continue;
   1256             }
   1257             AccessibilityServiceInfo accessibilityServiceInfo;
   1258             try {
   1259                 accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
   1260                 mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo);
   1261             } catch (XmlPullParserException | IOException xppe) {
   1262                 Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe);
   1263             }
   1264         }
   1265 
   1266         if (!mTempAccessibilityServiceInfoList.equals(userState.mInstalledServices)) {
   1267             userState.mInstalledServices.clear();
   1268             userState.mInstalledServices.addAll(mTempAccessibilityServiceInfoList);
   1269             mTempAccessibilityServiceInfoList.clear();
   1270             return true;
   1271         }
   1272 
   1273         mTempAccessibilityServiceInfoList.clear();
   1274         return false;
   1275     }
   1276 
   1277     private boolean readEnabledAccessibilityServicesLocked(UserState userState) {
   1278         mTempComponentNameSet.clear();
   1279         readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
   1280                 userState.mUserId, mTempComponentNameSet);
   1281         if (!mTempComponentNameSet.equals(userState.mEnabledServices)) {
   1282             userState.mEnabledServices.clear();
   1283             userState.mEnabledServices.addAll(mTempComponentNameSet);
   1284             if (userState.mUiAutomationService != null) {
   1285                 userState.mEnabledServices.add(sFakeAccessibilityServiceComponentName);
   1286             }
   1287             mTempComponentNameSet.clear();
   1288             return true;
   1289         }
   1290         mTempComponentNameSet.clear();
   1291         return false;
   1292     }
   1293 
   1294     private boolean readTouchExplorationGrantedAccessibilityServicesLocked(
   1295             UserState userState) {
   1296         mTempComponentNameSet.clear();
   1297         readComponentNamesFromSettingLocked(
   1298                 Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
   1299                 userState.mUserId, mTempComponentNameSet);
   1300         if (!mTempComponentNameSet.equals(userState.mTouchExplorationGrantedServices)) {
   1301             userState.mTouchExplorationGrantedServices.clear();
   1302             userState.mTouchExplorationGrantedServices.addAll(mTempComponentNameSet);
   1303             mTempComponentNameSet.clear();
   1304             return true;
   1305         }
   1306         mTempComponentNameSet.clear();
   1307         return false;
   1308     }
   1309 
   1310     /**
   1311      * Performs {@link AccessibilityService}s delayed notification. The delay is configurable
   1312      * and denotes the period after the last event before notifying the service.
   1313      *
   1314      * @param event The event.
   1315      * @param isDefault True to notify default listeners, not default services.
   1316      */
   1317     private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event,
   1318             boolean isDefault) {
   1319         try {
   1320             UserState state = getCurrentUserStateLocked();
   1321             for (int i = 0, count = state.mBoundServices.size(); i < count; i++) {
   1322                 Service service = state.mBoundServices.get(i);
   1323 
   1324                 if (service.mIsDefault == isDefault) {
   1325                     if (doesServiceWantEventLocked(service, event)) {
   1326                         service.notifyAccessibilityEvent(event, true);
   1327                     } else if (service.mUsesAccessibilityCache
   1328                             && (AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK
   1329                                 & event.getEventType()) != 0) {
   1330                         service.notifyAccessibilityEvent(event, false);
   1331                     }
   1332                 }
   1333             }
   1334         } catch (IndexOutOfBoundsException oobe) {
   1335             // An out of bounds exception can happen if services are going away
   1336             // as the for loop is running. If that happens, just bail because
   1337             // there are no more services to notify.
   1338         }
   1339     }
   1340 
   1341     private void addServiceLocked(Service service, UserState userState) {
   1342         try {
   1343             if (!userState.mBoundServices.contains(service)) {
   1344                 service.onAdded();
   1345                 userState.mBoundServices.add(service);
   1346                 userState.mComponentNameToServiceMap.put(service.mComponentName, service);
   1347                 scheduleNotifyClientsOfServicesStateChange(userState);
   1348             }
   1349         } catch (RemoteException re) {
   1350             /* do nothing */
   1351         }
   1352     }
   1353 
   1354     /**
   1355      * Removes a service.
   1356      *
   1357      * @param service The service.
   1358      */
   1359     private void removeServiceLocked(Service service, UserState userState) {
   1360         userState.mBoundServices.remove(service);
   1361         service.onRemoved();
   1362         // It may be possible to bind a service twice, which confuses the map. Rebuild the map
   1363         // to make sure we can still reach a service
   1364         userState.mComponentNameToServiceMap.clear();
   1365         for (int i = 0; i < userState.mBoundServices.size(); i++) {
   1366             Service boundService = userState.mBoundServices.get(i);
   1367             userState.mComponentNameToServiceMap.put(boundService.mComponentName, boundService);
   1368         }
   1369         scheduleNotifyClientsOfServicesStateChange(userState);
   1370     }
   1371 
   1372     private void updateRelevantEventsLocked(UserState userState) {
   1373         int relevantEventTypes = AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK;
   1374         for (Service service : userState.mBoundServices) {
   1375             relevantEventTypes |= service.mEventTypes;
   1376         }
   1377         int finalRelevantEventTypes = relevantEventTypes;
   1378 
   1379         if (userState.mLastSentRelevantEventTypes != finalRelevantEventTypes) {
   1380             userState.mLastSentRelevantEventTypes = finalRelevantEventTypes;
   1381             mMainHandler.obtainMessage(MainHandler.MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS,
   1382                     userState.mUserId, finalRelevantEventTypes);
   1383             mMainHandler.post(() -> {
   1384                 broadcastToClients(userState, (client) -> {
   1385                     try {
   1386                         client.setRelevantEventTypes(finalRelevantEventTypes);
   1387                     } catch (RemoteException re) {
   1388                         /* ignore */
   1389                     }
   1390                 });
   1391             });
   1392         }
   1393     }
   1394 
   1395     private void broadcastToClients(
   1396             UserState userState, Consumer<IAccessibilityManagerClient> clientAction) {
   1397         mGlobalClients.broadcast(clientAction);
   1398         userState.mUserClients.broadcast(clientAction);
   1399     }
   1400 
   1401     /**
   1402      * Determines if given event can be dispatched to a service based on the package of the
   1403      * event source. Specifically, a service is notified if it is interested in events from the
   1404      * package.
   1405      *
   1406      * @param service The potential receiver.
   1407      * @param event The event.
   1408      * @return True if the listener should be notified, false otherwise.
   1409      */
   1410     private boolean doesServiceWantEventLocked(Service service, AccessibilityEvent event) {
   1411 
   1412         if (!service.canReceiveEventsLocked()) {
   1413             return false;
   1414         }
   1415 
   1416         if ((event.getWindowId() != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)
   1417                 && !event.isImportantForAccessibility()
   1418                 && (service.mFetchFlags & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS)
   1419                         == 0) {
   1420             return false;
   1421         }
   1422 
   1423         int eventType = event.getEventType();
   1424         if ((service.mEventTypes & eventType) != eventType) {
   1425             return false;
   1426         }
   1427 
   1428         Set<String> packageNames = service.mPackageNames;
   1429         String packageName = (event.getPackageName() != null)
   1430                 ? event.getPackageName().toString() : null;
   1431 
   1432         return (packageNames.isEmpty() || packageNames.contains(packageName));
   1433     }
   1434 
   1435     private void unbindAllServicesLocked(UserState userState) {
   1436         List<Service> services = userState.mBoundServices;
   1437         for (int i = 0, count = services.size(); i < count; i++) {
   1438             Service service = services.get(i);
   1439             if (service.unbindLocked()) {
   1440                 i--;
   1441                 count--;
   1442             }
   1443         }
   1444     }
   1445 
   1446     /**
   1447      * Populates a set with the {@link ComponentName}s stored in a colon
   1448      * separated value setting for a given user.
   1449      *
   1450      * @param settingName The setting to parse.
   1451      * @param userId The user id.
   1452      * @param outComponentNames The output component names.
   1453      */
   1454     private void readComponentNamesFromSettingLocked(String settingName, int userId,
   1455             Set<ComponentName> outComponentNames) {
   1456         String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
   1457                 settingName, userId);
   1458         readComponentNamesFromStringLocked(settingValue, outComponentNames, false);
   1459     }
   1460 
   1461     /**
   1462      * Populates a set with the {@link ComponentName}s contained in a colon-delimited string.
   1463      *
   1464      * @param names The colon-delimited string to parse.
   1465      * @param outComponentNames The set of component names to be populated based on
   1466      *    the contents of the <code>names</code> string.
   1467      * @param doMerge If true, the parsed component names will be merged into the output
   1468      *    set, rather than replacing the set's existing contents entirely.
   1469      */
   1470     private void readComponentNamesFromStringLocked(String names,
   1471             Set<ComponentName> outComponentNames,
   1472             boolean doMerge) {
   1473         if (!doMerge) {
   1474             outComponentNames.clear();
   1475         }
   1476         if (names != null) {
   1477             TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
   1478             splitter.setString(names);
   1479             while (splitter.hasNext()) {
   1480                 String str = splitter.next();
   1481                 if (str == null || str.length() <= 0) {
   1482                     continue;
   1483                 }
   1484                 ComponentName enabledService = ComponentName.unflattenFromString(str);
   1485                 if (enabledService != null) {
   1486                     outComponentNames.add(enabledService);
   1487                 }
   1488             }
   1489         }
   1490     }
   1491 
   1492     /**
   1493      * Persists the component names in the specified setting in a
   1494      * colon separated fashion.
   1495      *
   1496      * @param settingName The setting name.
   1497      * @param componentNames The component names.
   1498      */
   1499     private void persistComponentNamesToSettingLocked(String settingName,
   1500             Set<ComponentName> componentNames, int userId) {
   1501         StringBuilder builder = new StringBuilder();
   1502         for (ComponentName componentName : componentNames) {
   1503             if (builder.length() > 0) {
   1504                 builder.append(COMPONENT_NAME_SEPARATOR);
   1505             }
   1506             builder.append(componentName.flattenToShortString());
   1507         }
   1508         final long identity = Binder.clearCallingIdentity();
   1509         try {
   1510             Settings.Secure.putStringForUser(mContext.getContentResolver(),
   1511                     settingName, builder.toString(), userId);
   1512         } finally {
   1513             Binder.restoreCallingIdentity(identity);
   1514         }
   1515     }
   1516 
   1517     private void updateServicesLocked(UserState userState) {
   1518         Map<ComponentName, Service> componentNameToServiceMap =
   1519                 userState.mComponentNameToServiceMap;
   1520         boolean isUnlockingOrUnlocked = LocalServices.getService(UserManagerInternal.class)
   1521                     .isUserUnlockingOrUnlocked(userState.mUserId);
   1522 
   1523         for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) {
   1524             AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i);
   1525             ComponentName componentName = ComponentName.unflattenFromString(
   1526                     installedService.getId());
   1527 
   1528             Service service = componentNameToServiceMap.get(componentName);
   1529 
   1530             // Ignore non-encryption-aware services until user is unlocked
   1531             if (!isUnlockingOrUnlocked && !installedService.isDirectBootAware()) {
   1532                 Slog.d(LOG_TAG, "Ignoring non-encryption-aware service " + componentName);
   1533                 continue;
   1534             }
   1535 
   1536             // Wait for the binding if it is in process.
   1537             if (userState.mBindingServices.contains(componentName)) {
   1538                 continue;
   1539             }
   1540             if (userState.mEnabledServices.contains(componentName)) {
   1541                 if (service == null) {
   1542                     service = new Service(userState.mUserId, componentName, installedService);
   1543                 } else if (userState.mBoundServices.contains(service)) {
   1544                     continue;
   1545                 }
   1546                 service.bindLocked();
   1547             } else {
   1548                 if (service != null) {
   1549                     service.unbindLocked();
   1550                 }
   1551             }
   1552         }
   1553 
   1554         final int count = userState.mBoundServices.size();
   1555         mTempIntArray.clear();
   1556         for (int i = 0; i < count; i++) {
   1557             final ResolveInfo resolveInfo =
   1558                     userState.mBoundServices.get(i).mAccessibilityServiceInfo.getResolveInfo();
   1559             if (resolveInfo != null) {
   1560                 mTempIntArray.add(resolveInfo.serviceInfo.applicationInfo.uid);
   1561             }
   1562         }
   1563         // Calling out with lock held, but to a lower-level service
   1564         final AudioManagerInternal audioManager =
   1565                 LocalServices.getService(AudioManagerInternal.class);
   1566         if (audioManager != null) {
   1567             audioManager.setAccessibilityServiceUids(mTempIntArray);
   1568         }
   1569         updateAccessibilityEnabledSetting(userState);
   1570     }
   1571 
   1572     private void scheduleUpdateClientsIfNeededLocked(UserState userState) {
   1573         final int clientState = userState.getClientState();
   1574         if (userState.mLastSentClientState != clientState
   1575                 && (mGlobalClients.getRegisteredCallbackCount() > 0
   1576                         || userState.mUserClients.getRegisteredCallbackCount() > 0)) {
   1577             userState.mLastSentClientState = clientState;
   1578             mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
   1579                     clientState, userState.mUserId).sendToTarget();
   1580         }
   1581     }
   1582 
   1583     private void showAccessibilityButtonTargetSelection() {
   1584         Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
   1585         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
   1586         mContext.startActivityAsUser(intent, UserHandle.of(mCurrentUserId));
   1587     }
   1588 
   1589     private void scheduleNotifyClientsOfServicesStateChange(UserState userState) {
   1590         mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS,
   1591                 userState.mUserId).sendToTarget();
   1592     }
   1593 
   1594     private void scheduleUpdateInputFilter(UserState userState) {
   1595         mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_INPUT_FILTER, userState).sendToTarget();
   1596     }
   1597 
   1598     private void scheduleUpdateFingerprintGestureHandling(UserState userState) {
   1599         mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_FINGERPRINT, userState).sendToTarget();
   1600     }
   1601 
   1602     private void updateInputFilter(UserState userState) {
   1603         boolean setInputFilter = false;
   1604         AccessibilityInputFilter inputFilter = null;
   1605         synchronized (mLock) {
   1606             int flags = 0;
   1607             if (userState.mIsDisplayMagnificationEnabled) {
   1608                 flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
   1609             }
   1610             if (userState.mIsNavBarMagnificationEnabled) {
   1611                 flags |= AccessibilityInputFilter.FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER;
   1612             }
   1613             if (userHasMagnificationServicesLocked(userState)) {
   1614                 flags |= AccessibilityInputFilter.FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER;
   1615             }
   1616             // Touch exploration without accessibility makes no sense.
   1617             if (userState.isHandlingAccessibilityEvents()
   1618                     && userState.mIsTouchExplorationEnabled) {
   1619                 flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
   1620             }
   1621             if (userState.mIsFilterKeyEventsEnabled) {
   1622                 flags |= AccessibilityInputFilter.FLAG_FEATURE_FILTER_KEY_EVENTS;
   1623             }
   1624             if (userState.mIsAutoclickEnabled) {
   1625                 flags |= AccessibilityInputFilter.FLAG_FEATURE_AUTOCLICK;
   1626             }
   1627             if (userState.mIsPerformGesturesEnabled) {
   1628                 flags |= AccessibilityInputFilter.FLAG_FEATURE_INJECT_MOTION_EVENTS;
   1629             }
   1630             if (flags != 0) {
   1631                 if (!mHasInputFilter) {
   1632                     mHasInputFilter = true;
   1633                     if (mInputFilter == null) {
   1634                         mInputFilter = new AccessibilityInputFilter(mContext,
   1635                                 AccessibilityManagerService.this);
   1636                     }
   1637                     inputFilter = mInputFilter;
   1638                     setInputFilter = true;
   1639                 }
   1640                 mInputFilter.setUserAndEnabledFeatures(userState.mUserId, flags);
   1641             } else {
   1642                 if (mHasInputFilter) {
   1643                     mHasInputFilter = false;
   1644                     mInputFilter.setUserAndEnabledFeatures(userState.mUserId, 0);
   1645                     inputFilter = null;
   1646                     setInputFilter = true;
   1647                 }
   1648             }
   1649         }
   1650         if (setInputFilter) {
   1651             mWindowManagerService.setInputFilter(inputFilter);
   1652         }
   1653     }
   1654 
   1655     private void showEnableTouchExplorationDialog(final Service service) {
   1656         synchronized (mLock) {
   1657             String label = service.mResolveInfo.loadLabel(
   1658             mContext.getPackageManager()).toString();
   1659 
   1660             final UserState state = getCurrentUserStateLocked();
   1661             if (state.mIsTouchExplorationEnabled) {
   1662                 return;
   1663             }
   1664             if (mEnableTouchExplorationDialog != null
   1665                     && mEnableTouchExplorationDialog.isShowing()) {
   1666                 return;
   1667             }
   1668             mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
   1669                 .setIconAttribute(android.R.attr.alertDialogIcon)
   1670                 .setPositiveButton(android.R.string.ok, new OnClickListener() {
   1671                      @Override
   1672                      public void onClick(DialogInterface dialog, int which) {
   1673                          // The user allowed the service to toggle touch exploration.
   1674                          state.mTouchExplorationGrantedServices.add(service.mComponentName);
   1675                          persistComponentNamesToSettingLocked(
   1676                                  Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
   1677                                  state.mTouchExplorationGrantedServices, state.mUserId);
   1678                          // Enable touch exploration.
   1679                          UserState userState = getUserStateLocked(service.mUserId);
   1680                          userState.mIsTouchExplorationEnabled = true;
   1681                          final long identity = Binder.clearCallingIdentity();
   1682                          try {
   1683                              Settings.Secure.putIntForUser(mContext.getContentResolver(),
   1684                                      Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
   1685                                      service.mUserId);
   1686                          } finally {
   1687                              Binder.restoreCallingIdentity(identity);
   1688                          }
   1689                          onUserStateChangedLocked(userState);
   1690                      }
   1691                  })
   1692                  .setNegativeButton(android.R.string.cancel, new OnClickListener() {
   1693                      @Override
   1694                      public void onClick(DialogInterface dialog, int which) {
   1695                          dialog.dismiss();
   1696                      }
   1697                  })
   1698                  .setTitle(R.string.enable_explore_by_touch_warning_title)
   1699                  .setMessage(mContext.getString(
   1700                          R.string.enable_explore_by_touch_warning_message, label))
   1701                  .create();
   1702              mEnableTouchExplorationDialog.getWindow().setType(
   1703                      WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
   1704              mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags
   1705                      |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   1706              mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
   1707              mEnableTouchExplorationDialog.show();
   1708         }
   1709     }
   1710 
   1711     /**
   1712      * Called when any property of the user state has changed.
   1713      *
   1714      * @param userState the new user state
   1715      */
   1716     private void onUserStateChangedLocked(UserState userState) {
   1717         // TODO: Remove this hack
   1718         mInitialized = true;
   1719         updateLegacyCapabilitiesLocked(userState);
   1720         updateServicesLocked(userState);
   1721         updateAccessibilityShortcutLocked(userState);
   1722         updateWindowsForAccessibilityCallbackLocked(userState);
   1723         updateAccessibilityFocusBehaviorLocked(userState);
   1724         updateFilterKeyEventsLocked(userState);
   1725         updateTouchExplorationLocked(userState);
   1726         updatePerformGesturesLocked(userState);
   1727         updateDisplayDaltonizerLocked(userState);
   1728         updateDisplayInversionLocked(userState);
   1729         updateMagnificationLocked(userState);
   1730         updateSoftKeyboardShowModeLocked(userState);
   1731         scheduleUpdateFingerprintGestureHandling(userState);
   1732         scheduleUpdateInputFilter(userState);
   1733         scheduleUpdateClientsIfNeededLocked(userState);
   1734         updateRelevantEventsLocked(userState);
   1735         updateAccessibilityButtonTargetsLocked(userState);
   1736     }
   1737 
   1738     private void updateAccessibilityFocusBehaviorLocked(UserState userState) {
   1739         // If there is no service that can operate with interactive windows
   1740         // then we keep the old behavior where a window loses accessibility
   1741         // focus if it is no longer active. This still changes the behavior
   1742         // for services that do not operate with interactive windows and run
   1743         // at the same time as the one(s) which does. In practice however,
   1744         // there is only one service that uses accessibility focus and it
   1745         // is typically the one that operates with interactive windows, So,
   1746         // this is fine. Note that to allow a service to work across windows
   1747         // we have to allow accessibility focus stay in any of them. Sigh...
   1748         List<Service> boundServices = userState.mBoundServices;
   1749         final int boundServiceCount = boundServices.size();
   1750         for (int i = 0; i < boundServiceCount; i++) {
   1751             Service boundService = boundServices.get(i);
   1752             if (boundService.canRetrieveInteractiveWindowsLocked()) {
   1753                 userState.mAccessibilityFocusOnlyInActiveWindow = false;
   1754                 return;
   1755             }
   1756         }
   1757         userState.mAccessibilityFocusOnlyInActiveWindow = true;
   1758     }
   1759 
   1760     private void updateWindowsForAccessibilityCallbackLocked(UserState userState) {
   1761         // We observe windows for accessibility only if there is at least
   1762         // one bound service that can retrieve window content that specified
   1763         // it is interested in accessing such windows. For services that are
   1764         // binding we do an update pass after each bind event, so we run this
   1765         // code and register the callback if needed.
   1766 
   1767         List<Service> boundServices = userState.mBoundServices;
   1768         final int boundServiceCount = boundServices.size();
   1769         for (int i = 0; i < boundServiceCount; i++) {
   1770             Service boundService = boundServices.get(i);
   1771             if (boundService.canRetrieveInteractiveWindowsLocked()) {
   1772                 if (mWindowsForAccessibilityCallback == null) {
   1773                     mWindowsForAccessibilityCallback = new WindowsForAccessibilityCallback();
   1774                     mWindowManagerService.setWindowsForAccessibilityCallback(
   1775                             mWindowsForAccessibilityCallback);
   1776                 }
   1777                 return;
   1778             }
   1779         }
   1780 
   1781         if (mWindowsForAccessibilityCallback != null) {
   1782             mWindowsForAccessibilityCallback = null;
   1783             mWindowManagerService.setWindowsForAccessibilityCallback(null);
   1784             // Drop all windows we know about.
   1785             mSecurityPolicy.clearWindowsLocked();
   1786         }
   1787     }
   1788 
   1789     private void updateLegacyCapabilitiesLocked(UserState userState) {
   1790         // Up to JB-MR1 we had a white list with services that can enable touch
   1791         // exploration. When a service is first started we show a dialog to the
   1792         // use to get a permission to white list the service.
   1793         final int installedServiceCount = userState.mInstalledServices.size();
   1794         for (int i = 0; i < installedServiceCount; i++) {
   1795             AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i);
   1796             ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
   1797             if ((serviceInfo.getCapabilities()
   1798                         & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) == 0
   1799                     && resolveInfo.serviceInfo.applicationInfo.targetSdkVersion
   1800                         <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
   1801                 ComponentName componentName = new ComponentName(
   1802                         resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
   1803                 if (userState.mTouchExplorationGrantedServices.contains(componentName)) {
   1804                     serviceInfo.setCapabilities(serviceInfo.getCapabilities()
   1805                             | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION);
   1806                 }
   1807             }
   1808         }
   1809     }
   1810 
   1811     private void updatePerformGesturesLocked(UserState userState) {
   1812         final int serviceCount = userState.mBoundServices.size();
   1813         for (int i = 0; i < serviceCount; i++) {
   1814             Service service = userState.mBoundServices.get(i);
   1815             if ((service.mAccessibilityServiceInfo.getCapabilities()
   1816                     & AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES) != 0) {
   1817                 userState.mIsPerformGesturesEnabled = true;
   1818                 return;
   1819             }
   1820         }
   1821         userState.mIsPerformGesturesEnabled = false;
   1822     }
   1823 
   1824     private void updateFilterKeyEventsLocked(UserState userState) {
   1825         final int serviceCount = userState.mBoundServices.size();
   1826         for (int i = 0; i < serviceCount; i++) {
   1827             Service service = userState.mBoundServices.get(i);
   1828             if (service.mRequestFilterKeyEvents
   1829                     && (service.mAccessibilityServiceInfo.getCapabilities()
   1830                             & AccessibilityServiceInfo
   1831                             .CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) != 0) {
   1832                 userState.mIsFilterKeyEventsEnabled = true;
   1833                 return;
   1834             }
   1835         }
   1836         userState.mIsFilterKeyEventsEnabled = false;
   1837     }
   1838 
   1839     private boolean readConfigurationForUserStateLocked(UserState userState) {
   1840         boolean somethingChanged = readInstalledAccessibilityServiceLocked(userState);
   1841         somethingChanged |= readEnabledAccessibilityServicesLocked(userState);
   1842         somethingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
   1843         somethingChanged |= readTouchExplorationEnabledSettingLocked(userState);
   1844         somethingChanged |= readHighTextContrastEnabledSettingLocked(userState);
   1845         somethingChanged |= readMagnificationEnabledSettingsLocked(userState);
   1846         somethingChanged |= readAutoclickEnabledSettingLocked(userState);
   1847         somethingChanged |= readAccessibilityShortcutSettingLocked(userState);
   1848         somethingChanged |= readAccessibilityButtonSettingsLocked(userState);
   1849         return somethingChanged;
   1850     }
   1851 
   1852     private void updateAccessibilityEnabledSetting(UserState userState) {
   1853         final long identity = Binder.clearCallingIdentity();
   1854         try {
   1855             Settings.Secure.putIntForUser(mContext.getContentResolver(),
   1856                     Settings.Secure.ACCESSIBILITY_ENABLED,
   1857                     userState.isHandlingAccessibilityEvents() ? 1 : 0,
   1858                     userState.mUserId);
   1859         } finally {
   1860             Binder.restoreCallingIdentity(identity);
   1861         }
   1862     }
   1863 
   1864     private boolean readTouchExplorationEnabledSettingLocked(UserState userState) {
   1865         final boolean touchExplorationEnabled = Settings.Secure.getIntForUser(
   1866                 mContext.getContentResolver(),
   1867                 Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId) == 1;
   1868         if (touchExplorationEnabled != userState.mIsTouchExplorationEnabled) {
   1869             userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
   1870             return true;
   1871         }
   1872         return false;
   1873     }
   1874 
   1875     private boolean readMagnificationEnabledSettingsLocked(UserState userState) {
   1876         final boolean displayMagnificationEnabled = Settings.Secure.getIntForUser(
   1877                 mContext.getContentResolver(),
   1878                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
   1879                 0, userState.mUserId) == 1;
   1880         final boolean navBarMagnificationEnabled = Settings.Secure.getIntForUser(
   1881                 mContext.getContentResolver(),
   1882                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
   1883                 0, userState.mUserId) == 1;
   1884         if ((displayMagnificationEnabled != userState.mIsDisplayMagnificationEnabled)
   1885                 || (navBarMagnificationEnabled != userState.mIsNavBarMagnificationEnabled)) {
   1886             userState.mIsDisplayMagnificationEnabled = displayMagnificationEnabled;
   1887             userState.mIsNavBarMagnificationEnabled = navBarMagnificationEnabled;
   1888             return true;
   1889         }
   1890         return false;
   1891     }
   1892 
   1893     private boolean readAutoclickEnabledSettingLocked(UserState userState) {
   1894         final boolean autoclickEnabled = Settings.Secure.getIntForUser(
   1895                 mContext.getContentResolver(),
   1896                 Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED,
   1897                 0, userState.mUserId) == 1;
   1898         if (autoclickEnabled != userState.mIsAutoclickEnabled) {
   1899             userState.mIsAutoclickEnabled = autoclickEnabled;
   1900             return true;
   1901         }
   1902         return false;
   1903     }
   1904 
   1905     private boolean readHighTextContrastEnabledSettingLocked(UserState userState) {
   1906         final boolean highTextContrastEnabled = Settings.Secure.getIntForUser(
   1907                 mContext.getContentResolver(),
   1908                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0,
   1909                 userState.mUserId) == 1;
   1910         if (highTextContrastEnabled != userState.mIsTextHighContrastEnabled) {
   1911             userState.mIsTextHighContrastEnabled = highTextContrastEnabled;
   1912             return true;
   1913         }
   1914         return false;
   1915     }
   1916 
   1917     private boolean readSoftKeyboardShowModeChangedLocked(UserState userState) {
   1918         final int softKeyboardShowMode = Settings.Secure.getIntForUser(
   1919                 mContext.getContentResolver(),
   1920                 Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0,
   1921                 userState.mUserId);
   1922         if (softKeyboardShowMode != userState.mSoftKeyboardShowMode) {
   1923             userState.mSoftKeyboardShowMode = softKeyboardShowMode;
   1924             return true;
   1925         }
   1926         return false;
   1927     }
   1928 
   1929     private void updateTouchExplorationLocked(UserState userState) {
   1930         boolean enabled = false;
   1931         final int serviceCount = userState.mBoundServices.size();
   1932         for (int i = 0; i < serviceCount; i++) {
   1933             Service service = userState.mBoundServices.get(i);
   1934             if (canRequestAndRequestsTouchExplorationLocked(service)) {
   1935                 enabled = true;
   1936                 break;
   1937             }
   1938         }
   1939         if (enabled != userState.mIsTouchExplorationEnabled) {
   1940             userState.mIsTouchExplorationEnabled = enabled;
   1941             final long identity = Binder.clearCallingIdentity();
   1942             try {
   1943                 Settings.Secure.putIntForUser(mContext.getContentResolver(),
   1944                         Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0,
   1945                         userState.mUserId);
   1946             } finally {
   1947                 Binder.restoreCallingIdentity(identity);
   1948             }
   1949         }
   1950     }
   1951 
   1952     private boolean readAccessibilityShortcutSettingLocked(UserState userState) {
   1953         String componentNameToEnableString = AccessibilityShortcutController
   1954                 .getTargetServiceComponentNameString(mContext, userState.mUserId);
   1955         if ((componentNameToEnableString == null) || componentNameToEnableString.isEmpty()) {
   1956             if (userState.mServiceToEnableWithShortcut == null) {
   1957                 return false;
   1958             }
   1959             userState.mServiceToEnableWithShortcut = null;
   1960             return true;
   1961         }
   1962         ComponentName componentNameToEnable =
   1963             ComponentName.unflattenFromString(componentNameToEnableString);
   1964         if ((componentNameToEnable != null)
   1965                 && componentNameToEnable.equals(userState.mServiceToEnableWithShortcut)) {
   1966             return false;
   1967         }
   1968         userState.mServiceToEnableWithShortcut = componentNameToEnable;
   1969         return true;
   1970     }
   1971 
   1972     private boolean readAccessibilityButtonSettingsLocked(UserState userState) {
   1973         String componentId = Settings.Secure.getStringForUser(mContext.getContentResolver(),
   1974                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT, userState.mUserId);
   1975         if (TextUtils.isEmpty(componentId)) {
   1976             if ((userState.mServiceAssignedToAccessibilityButton == null)
   1977                     && !userState.mIsNavBarMagnificationAssignedToAccessibilityButton) {
   1978                 return false;
   1979             }
   1980             userState.mServiceAssignedToAccessibilityButton = null;
   1981             userState.mIsNavBarMagnificationAssignedToAccessibilityButton = false;
   1982             return true;
   1983         }
   1984 
   1985         if (componentId.equals(MagnificationController.class.getName())) {
   1986             if (userState.mIsNavBarMagnificationAssignedToAccessibilityButton) {
   1987                 return false;
   1988             }
   1989             userState.mServiceAssignedToAccessibilityButton = null;
   1990             userState.mIsNavBarMagnificationAssignedToAccessibilityButton = true;
   1991             return true;
   1992         }
   1993 
   1994         ComponentName componentName = ComponentName.unflattenFromString(componentId);
   1995         if (componentName.equals(userState.mServiceAssignedToAccessibilityButton)) {
   1996             return false;
   1997         }
   1998         userState.mServiceAssignedToAccessibilityButton = componentName;
   1999         userState.mIsNavBarMagnificationAssignedToAccessibilityButton = false;
   2000         return true;
   2001     }
   2002 
   2003     /**
   2004      * Check if the service that will be enabled by the shortcut is installed. If it isn't,
   2005      * clear the value and the associated setting so a sideloaded service can't spoof the
   2006      * package name of the default service.
   2007      *
   2008      * @param userState
   2009      */
   2010     private void updateAccessibilityShortcutLocked(UserState userState) {
   2011         if (userState.mServiceToEnableWithShortcut == null) {
   2012             return;
   2013         }
   2014         boolean shortcutServiceIsInstalled = false;
   2015         for (int i = 0; i < userState.mInstalledServices.size(); i++) {
   2016             if (userState.mInstalledServices.get(i).getComponentName()
   2017                     .equals(userState.mServiceToEnableWithShortcut)) {
   2018                 shortcutServiceIsInstalled = true;
   2019             }
   2020         }
   2021         if (!shortcutServiceIsInstalled) {
   2022             userState.mServiceToEnableWithShortcut = null;
   2023             final long identity = Binder.clearCallingIdentity();
   2024             try {
   2025                 Settings.Secure.putStringForUser(mContext.getContentResolver(),
   2026                         Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null, userState.mUserId);
   2027 
   2028                 Settings.Secure.putIntForUser(mContext.getContentResolver(),
   2029                         Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0, userState.mUserId);
   2030             } finally {
   2031                 Binder.restoreCallingIdentity(identity);
   2032             }
   2033         }
   2034     }
   2035 
   2036     private boolean canRequestAndRequestsTouchExplorationLocked(Service service) {
   2037         // Service not ready or cannot request the feature - well nothing to do.
   2038         if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) {
   2039             return false;
   2040         }
   2041         // UI test automation service can always enable it.
   2042         if (service.mIsAutomation) {
   2043             return true;
   2044         }
   2045         if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion
   2046                 <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
   2047             // Up to JB-MR1 we had a white list with services that can enable touch
   2048             // exploration. When a service is first started we show a dialog to the
   2049             // use to get a permission to white list the service.
   2050             UserState userState = getUserStateLocked(service.mUserId);
   2051             if (userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) {
   2052                 return true;
   2053             } else if (mEnableTouchExplorationDialog == null
   2054                     || !mEnableTouchExplorationDialog.isShowing()) {
   2055                 mMainHandler.obtainMessage(
   2056                         MainHandler.MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG,
   2057                         service).sendToTarget();
   2058             }
   2059         } else {
   2060             // Starting in JB-MR2 we request an accessibility service to declare
   2061             // certain capabilities in its meta-data to allow it to enable the
   2062             // corresponding features.
   2063             if ((service.mAccessibilityServiceInfo.getCapabilities()
   2064                     & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) != 0) {
   2065                 return true;
   2066             }
   2067         }
   2068         return false;
   2069     }
   2070 
   2071     private void updateDisplayDaltonizerLocked(UserState userState) {
   2072         DisplayAdjustmentUtils.applyDaltonizerSetting(mContext, userState.mUserId);
   2073     }
   2074 
   2075     private void updateDisplayInversionLocked(UserState userState) {
   2076         DisplayAdjustmentUtils.applyInversionSetting(mContext, userState.mUserId);
   2077     }
   2078 
   2079     private void updateMagnificationLocked(UserState userState) {
   2080         if (userState.mUserId != mCurrentUserId) {
   2081             return;
   2082         }
   2083 
   2084         if (userState.mIsDisplayMagnificationEnabled || userState.mIsNavBarMagnificationEnabled
   2085                 || userHasListeningMagnificationServicesLocked(userState)) {
   2086             // Initialize the magnification controller if necessary
   2087             getMagnificationController();
   2088             mMagnificationController.register();
   2089         } else if (mMagnificationController != null) {
   2090             mMagnificationController.unregister();
   2091         }
   2092     }
   2093 
   2094     /**
   2095      * Returns whether the specified user has any services that are capable of
   2096      * controlling magnification.
   2097      */
   2098     private boolean userHasMagnificationServicesLocked(UserState userState) {
   2099         final List<Service> services = userState.mBoundServices;
   2100         for (int i = 0, count = services.size(); i < count; i++) {
   2101             final Service service = services.get(i);
   2102             if (mSecurityPolicy.canControlMagnification(service)) {
   2103                 return true;
   2104             }
   2105         }
   2106         return false;
   2107     }
   2108 
   2109     /**
   2110      * Returns whether the specified user has any services that are capable of
   2111      * controlling magnification and are actively listening for magnification updates.
   2112      */
   2113     private boolean userHasListeningMagnificationServicesLocked(UserState userState) {
   2114         final List<Service> services = userState.mBoundServices;
   2115         for (int i = 0, count = services.size(); i < count; i++) {
   2116             final Service service = services.get(i);
   2117             if (mSecurityPolicy.canControlMagnification(service)
   2118                     && service.mInvocationHandler.mIsMagnificationCallbackEnabled) {
   2119                 return true;
   2120             }
   2121         }
   2122         return false;
   2123     }
   2124 
   2125     private void updateSoftKeyboardShowModeLocked(UserState userState) {
   2126         final int userId = userState.mUserId;
   2127         // Only check whether we need to reset the soft keyboard mode if it is not set to the
   2128         // default.
   2129         if ((userId == mCurrentUserId) && (userState.mSoftKeyboardShowMode != 0)) {
   2130             // Check whether the last Accessibility Service that changed the soft keyboard mode to
   2131             // something other than the default is still enabled and, if not, remove flag and
   2132             // reset to the default soft keyboard behavior.
   2133             boolean serviceChangingSoftKeyboardModeIsEnabled =
   2134                     userState.mEnabledServices.contains(userState.mServiceChangingSoftKeyboardMode);
   2135 
   2136             if (!serviceChangingSoftKeyboardModeIsEnabled) {
   2137                 final long identity = Binder.clearCallingIdentity();
   2138                 try {
   2139                     Settings.Secure.putIntForUser(mContext.getContentResolver(),
   2140                             Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
   2141                             0,
   2142                             userState.mUserId);
   2143                 } finally {
   2144                     Binder.restoreCallingIdentity(identity);
   2145                 }
   2146                 userState.mSoftKeyboardShowMode = 0;
   2147                 userState.mServiceChangingSoftKeyboardMode = null;
   2148                 notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
   2149             }
   2150         }
   2151     }
   2152 
   2153     private void updateFingerprintGestureHandling(UserState userState) {
   2154         final List<Service> services;
   2155         synchronized (mLock) {
   2156             services = userState.mBoundServices;
   2157             if ((mFingerprintGestureDispatcher == null)
   2158                     &&  mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
   2159                 // Only create the controller when a service wants to use the feature
   2160                 int numServices = services.size();
   2161                 for (int i = 0; i < numServices; i++) {
   2162                     if (services.get(i).isCapturingFingerprintGestures()) {
   2163                         final long identity = Binder.clearCallingIdentity();
   2164                         IFingerprintService service = null;
   2165                         try {
   2166                             service = IFingerprintService.Stub.asInterface(
   2167                                     ServiceManager.getService(Context.FINGERPRINT_SERVICE));
   2168                         } finally {
   2169                             Binder.restoreCallingIdentity(identity);
   2170                         }
   2171                         if (service != null) {
   2172                             mFingerprintGestureDispatcher = new FingerprintGestureDispatcher(
   2173                                     service, mLock);
   2174                             break;
   2175                         }
   2176                     }
   2177                 }
   2178             }
   2179         }
   2180         if (mFingerprintGestureDispatcher != null) {
   2181             mFingerprintGestureDispatcher.updateClientList(services);
   2182         }
   2183     }
   2184 
   2185     private void updateAccessibilityButtonTargetsLocked(UserState userState) {
   2186         for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
   2187             final Service service = userState.mBoundServices.get(i);
   2188             if (service.mRequestAccessibilityButton) {
   2189                 service.notifyAccessibilityButtonAvailabilityChangedLocked(
   2190                         service.isAccessibilityButtonAvailableLocked(userState));
   2191             }
   2192         }
   2193     }
   2194 
   2195     @GuardedBy("mLock")
   2196     private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
   2197         IBinder windowToken = mGlobalWindowTokens.get(windowId);
   2198         if (windowToken == null) {
   2199             windowToken = getCurrentUserStateLocked().mWindowTokens.get(windowId);
   2200         }
   2201         if (windowToken != null) {
   2202             return mWindowManagerService.getCompatibleMagnificationSpecForWindow(
   2203                     windowToken);
   2204         }
   2205         return null;
   2206     }
   2207 
   2208     private KeyEventDispatcher getKeyEventDispatcher() {
   2209         if (mKeyEventDispatcher == null) {
   2210             mKeyEventDispatcher = new KeyEventDispatcher(
   2211                     mMainHandler, MainHandler.MSG_SEND_KEY_EVENT_TO_INPUT_FILTER, mLock,
   2212                     mPowerManager);
   2213         }
   2214         return mKeyEventDispatcher;
   2215     }
   2216 
   2217     /**
   2218      * AIDL-exposed method to be called when the accessibility shortcut is enabled. Requires
   2219      * permission to write secure settings, since someone with that permission can enable
   2220      * accessibility services themselves.
   2221      */
   2222     public void performAccessibilityShortcut() {
   2223         if ((UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID)
   2224                 && (mContext.checkCallingPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
   2225                 != PackageManager.PERMISSION_GRANTED)) {
   2226             throw new SecurityException(
   2227                     "performAccessibilityShortcut requires the WRITE_SECURE_SETTINGS permission");
   2228         }
   2229         synchronized(mLock) {
   2230             UserState userState = getUserStateLocked(mCurrentUserId);
   2231             ComponentName serviceName = userState.mServiceToEnableWithShortcut;
   2232             if (serviceName == null) {
   2233                 return;
   2234             }
   2235             final long identity = Binder.clearCallingIdentity();
   2236             try {
   2237                 if (userState.mComponentNameToServiceMap.get(serviceName) == null) {
   2238                     enableAccessibilityServiceLocked(serviceName, mCurrentUserId);
   2239                 } else {
   2240                     disableAccessibilityServiceLocked(serviceName, mCurrentUserId);
   2241                 }
   2242             } finally {
   2243                 Binder.restoreCallingIdentity(identity);
   2244             }
   2245         }
   2246     };
   2247 
   2248     /**
   2249      * Enables accessibility service specified by {@param componentName} for the {@param userId}.
   2250      */
   2251     private void enableAccessibilityServiceLocked(ComponentName componentName, int userId) {
   2252         final SettingStringHelper setting =
   2253                 new SettingStringHelper(
   2254                         mContext.getContentResolver(),
   2255                         Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
   2256                         userId);
   2257         setting.write(ComponentNameSet.add(setting.read(), componentName));
   2258 
   2259         UserState userState = getUserStateLocked(userId);
   2260         if (userState.mEnabledServices.add(componentName)) {
   2261             onUserStateChangedLocked(userState);
   2262         }
   2263     }
   2264 
   2265     /**
   2266      * Disables accessibility service specified by {@param componentName} for the {@param userId}.
   2267      */
   2268     private void disableAccessibilityServiceLocked(ComponentName componentName, int userId) {
   2269         final SettingsStringUtil.SettingStringHelper setting =
   2270                 new SettingStringHelper(
   2271                         mContext.getContentResolver(),
   2272                         Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
   2273                         userId);
   2274         setting.write(ComponentNameSet.remove(setting.read(), componentName));
   2275 
   2276         UserState userState = getUserStateLocked(userId);
   2277         if (userState.mEnabledServices.remove(componentName)) {
   2278             onUserStateChangedLocked(userState);
   2279         }
   2280     }
   2281 
   2282     /**
   2283      * AIDL-exposed method. System only.
   2284      * Inform accessibility that a fingerprint gesture was performed
   2285      *
   2286      * @param gestureKeyCode The key code corresponding to the fingerprint gesture.
   2287      * @return {@code true} if accessibility consumes the fingerprint gesture, {@code false} if it
   2288      * doesn't.
   2289      */
   2290     @Override
   2291     public boolean sendFingerprintGesture(int gestureKeyCode) {
   2292         synchronized(mLock) {
   2293             if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
   2294                 throw new SecurityException("Only SYSTEM can call sendFingerprintGesture");
   2295             }
   2296         }
   2297         if (mFingerprintGestureDispatcher == null) {
   2298             return false;
   2299         }
   2300         return mFingerprintGestureDispatcher.onFingerprintGesture(gestureKeyCode);
   2301     }
   2302 
   2303     @Override
   2304     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
   2305         if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
   2306         synchronized (mLock) {
   2307             pw.println("ACCESSIBILITY MANAGER (dumpsys accessibility)");
   2308             pw.println();
   2309             final int userCount = mUserStates.size();
   2310             for (int i = 0; i < userCount; i++) {
   2311                 UserState userState = mUserStates.valueAt(i);
   2312                 pw.append("User state[attributes:{id=" + userState.mUserId);
   2313                 pw.append(", currentUser=" + (userState.mUserId == mCurrentUserId));
   2314                 pw.append(", touchExplorationEnabled=" + userState.mIsTouchExplorationEnabled);
   2315                 pw.append(", displayMagnificationEnabled="
   2316                         + userState.mIsDisplayMagnificationEnabled);
   2317                 pw.append(", navBarMagnificationEnabled="
   2318                         + userState.mIsNavBarMagnificationEnabled);
   2319                 pw.append(", autoclickEnabled=" + userState.mIsAutoclickEnabled);
   2320                 if (userState.mUiAutomationService != null) {
   2321                     pw.append(", ");
   2322                     userState.mUiAutomationService.dump(fd, pw, args);
   2323                     pw.println();
   2324                 }
   2325                 pw.append("}");
   2326                 pw.println();
   2327                 pw.append("           services:{");
   2328                 final int serviceCount = userState.mBoundServices.size();
   2329                 for (int j = 0; j < serviceCount; j++) {
   2330                     if (j > 0) {
   2331                         pw.append(", ");
   2332                         pw.println();
   2333                         pw.append("                     ");
   2334                     }
   2335                     Service service = userState.mBoundServices.get(j);
   2336                     service.dump(fd, pw, args);
   2337                 }
   2338                 pw.println("}]");
   2339                 pw.println();
   2340             }
   2341             if (mSecurityPolicy.mWindows != null) {
   2342                 final int windowCount = mSecurityPolicy.mWindows.size();
   2343                 for (int j = 0; j < windowCount; j++) {
   2344                     if (j > 0) {
   2345                         pw.append(',');
   2346                         pw.println();
   2347                     }
   2348                     pw.append("Window[");
   2349                     AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(j);
   2350                     pw.append(window.toString());
   2351                     pw.append(']');
   2352                 }
   2353             }
   2354         }
   2355     }
   2356 
   2357     private class AccessibilityConnectionWrapper implements DeathRecipient {
   2358         private final int mWindowId;
   2359         private final int mUserId;
   2360         private final IAccessibilityInteractionConnection mConnection;
   2361 
   2362         public AccessibilityConnectionWrapper(int windowId,
   2363                 IAccessibilityInteractionConnection connection, int userId) {
   2364             mWindowId = windowId;
   2365             mUserId = userId;
   2366             mConnection = connection;
   2367         }
   2368 
   2369         public void linkToDeath() throws RemoteException {
   2370             mConnection.asBinder().linkToDeath(this, 0);
   2371         }
   2372 
   2373         public void unlinkToDeath() {
   2374             mConnection.asBinder().unlinkToDeath(this, 0);
   2375         }
   2376 
   2377         @Override
   2378         public void binderDied() {
   2379             unlinkToDeath();
   2380             synchronized (mLock) {
   2381                 removeAccessibilityInteractionConnectionLocked(mWindowId, mUserId);
   2382             }
   2383         }
   2384     }
   2385 
   2386     private final class MainHandler extends Handler {
   2387         public static final int MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER = 1;
   2388         public static final int MSG_SEND_STATE_TO_CLIENTS = 2;
   2389         public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3;
   2390         public static final int MSG_ANNOUNCE_NEW_USER_IF_NEEDED = 5;
   2391         public static final int MSG_UPDATE_INPUT_FILTER = 6;
   2392         public static final int MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG = 7;
   2393         public static final int MSG_SEND_KEY_EVENT_TO_INPUT_FILTER = 8;
   2394         public static final int MSG_CLEAR_ACCESSIBILITY_FOCUS = 9;
   2395         public static final int MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS = 10;
   2396         public static final int MSG_UPDATE_FINGERPRINT = 11;
   2397         public static final int MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS = 12;
   2398         public static final int MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER = 13;
   2399         public static final int MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER = 14;
   2400         public static final int MSG_INIT_SERVICE = 15;
   2401 
   2402         public MainHandler(Looper looper) {
   2403             super(looper);
   2404         }
   2405 
   2406         @Override
   2407         public void handleMessage(Message msg) {
   2408             final int type = msg.what;
   2409             switch (type) {
   2410                 case MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER: {
   2411                     AccessibilityEvent event = (AccessibilityEvent) msg.obj;
   2412                     synchronized (mLock) {
   2413                         if (mHasInputFilter && mInputFilter != null) {
   2414                             mInputFilter.notifyAccessibilityEvent(event);
   2415                         }
   2416                     }
   2417                     event.recycle();
   2418                 } break;
   2419 
   2420                 case MSG_SEND_KEY_EVENT_TO_INPUT_FILTER: {
   2421                     KeyEvent event = (KeyEvent) msg.obj;
   2422                     final int policyFlags = msg.arg1;
   2423                     synchronized (mLock) {
   2424                         if (mHasInputFilter && mInputFilter != null) {
   2425                             mInputFilter.sendInputEvent(event, policyFlags);
   2426                         }
   2427                     }
   2428                     event.recycle();
   2429                 } break;
   2430 
   2431                 case MSG_SEND_STATE_TO_CLIENTS: {
   2432                     final int clientState = msg.arg1;
   2433                     final int userId = msg.arg2;
   2434                     sendStateToClients(clientState, mGlobalClients);
   2435                     sendStateToClients(clientState, getUserClientsForId(userId));
   2436                 } break;
   2437 
   2438                 case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
   2439                     final int userId = msg.arg1;
   2440                     sendStateToClients(0, getUserClientsForId(userId));
   2441                 } break;
   2442 
   2443                 case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
   2444                     announceNewUserIfNeeded();
   2445                 } break;
   2446 
   2447                 case MSG_UPDATE_INPUT_FILTER: {
   2448                     UserState userState = (UserState) msg.obj;
   2449                     updateInputFilter(userState);
   2450                 } break;
   2451 
   2452                 case MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG: {
   2453                     Service service = (Service) msg.obj;
   2454                     showEnableTouchExplorationDialog(service);
   2455                 } break;
   2456 
   2457                 case MSG_CLEAR_ACCESSIBILITY_FOCUS: {
   2458                     final int windowId = msg.arg1;
   2459                     getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
   2460                 } break;
   2461 
   2462                 case MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS: {
   2463                     final int userId = msg.arg1;
   2464                     notifyClientsOfServicesStateChange(mGlobalClients);
   2465                     notifyClientsOfServicesStateChange(getUserClientsForId(userId));
   2466                 } break;
   2467 
   2468                 case MSG_UPDATE_FINGERPRINT: {
   2469                     updateFingerprintGestureHandling((UserState) msg.obj);
   2470                 } break;
   2471 
   2472                 case MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS: {
   2473                     final int userId = msg.arg1;
   2474                     final int relevantEventTypes = msg.arg2;
   2475                     final UserState userState;
   2476                     synchronized (mLock) {
   2477                         userState = getUserStateLocked(userId);
   2478                     }
   2479                     broadcastToClients(userState, (client) -> {
   2480                         try {
   2481                             client.setRelevantEventTypes(relevantEventTypes);
   2482                         } catch (RemoteException re) {
   2483                             /* ignore */
   2484                         }
   2485                     });
   2486                 } break;
   2487 
   2488                case MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER: {
   2489                     synchronized (mLock) {
   2490                         if (mHasInputFilter && mInputFilter != null) {
   2491                             mInputFilter.notifyAccessibilityButtonClicked();
   2492                         }
   2493                     }
   2494                 } break;
   2495 
   2496                 case MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER: {
   2497                     showAccessibilityButtonTargetSelection();
   2498                 } break;
   2499 
   2500                 case MSG_INIT_SERVICE: {
   2501                     final Service service = (Service) msg.obj;
   2502                     service.initializeService();
   2503                 } break;
   2504             }
   2505         }
   2506 
   2507         private void announceNewUserIfNeeded() {
   2508             synchronized (mLock) {
   2509                 UserState userState = getCurrentUserStateLocked();
   2510                 if (userState.isHandlingAccessibilityEvents()) {
   2511                     UserManager userManager = (UserManager) mContext.getSystemService(
   2512                             Context.USER_SERVICE);
   2513                     String message = mContext.getString(R.string.user_switched,
   2514                             userManager.getUserInfo(mCurrentUserId).name);
   2515                     AccessibilityEvent event = AccessibilityEvent.obtain(
   2516                             AccessibilityEvent.TYPE_ANNOUNCEMENT);
   2517                     event.getText().add(message);
   2518                     sendAccessibilityEvent(event, mCurrentUserId);
   2519                 }
   2520             }
   2521         }
   2522 
   2523         private RemoteCallbackList<IAccessibilityManagerClient> getUserClientsForId(int userId) {
   2524             final UserState userState;
   2525             synchronized (mLock) {
   2526                 userState = getUserStateLocked(userId);
   2527             }
   2528             return userState.mUserClients;
   2529         }
   2530 
   2531         private void sendStateToClients(int clientState,
   2532                 RemoteCallbackList<IAccessibilityManagerClient> clients) {
   2533             clients.broadcast((client) -> {
   2534                 try {
   2535                     client.setState(clientState);
   2536                 } catch (RemoteException re) {
   2537                     /* ignore */
   2538                 }
   2539             });
   2540         }
   2541 
   2542         private void notifyClientsOfServicesStateChange(
   2543                 RemoteCallbackList<IAccessibilityManagerClient> clients) {
   2544             try {
   2545                 final int userClientCount = clients.beginBroadcast();
   2546                 for (int i = 0; i < userClientCount; i++) {
   2547                     IAccessibilityManagerClient client = clients.getBroadcastItem(i);
   2548                     try {
   2549                         client.notifyServicesStateChanged();
   2550                     } catch (RemoteException re) {
   2551                         /* ignore */
   2552                     }
   2553                 }
   2554             } finally {
   2555                 clients.finishBroadcast();
   2556             }
   2557         }
   2558     }
   2559 
   2560     private int findWindowIdLocked(IBinder token) {
   2561         final int globalIndex = mGlobalWindowTokens.indexOfValue(token);
   2562         if (globalIndex >= 0) {
   2563             return mGlobalWindowTokens.keyAt(globalIndex);
   2564         }
   2565         UserState userState = getCurrentUserStateLocked();
   2566         final int userIndex = userState.mWindowTokens.indexOfValue(token);
   2567         if (userIndex >= 0) {
   2568             return userState.mWindowTokens.keyAt(userIndex);
   2569         }
   2570         return -1;
   2571     }
   2572 
   2573     private void ensureWindowsAvailableTimed() {
   2574         synchronized (mLock) {
   2575             if (mSecurityPolicy.mWindows != null) {
   2576                 return;
   2577             }
   2578             // If we have no registered callback, update the state we
   2579             // we may have to register one but it didn't happen yet.
   2580             if (mWindowsForAccessibilityCallback == null) {
   2581                 UserState userState = getCurrentUserStateLocked();
   2582                 onUserStateChangedLocked(userState);
   2583             }
   2584             // We have no windows but do not care about them, done.
   2585             if (mWindowsForAccessibilityCallback == null) {
   2586                 return;
   2587             }
   2588 
   2589             // Wait for the windows with a timeout.
   2590             final long startMillis = SystemClock.uptimeMillis();
   2591             while (mSecurityPolicy.mWindows == null) {
   2592                 final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
   2593                 final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
   2594                 if (remainMillis <= 0) {
   2595                     return;
   2596                 }
   2597                 try {
   2598                     mLock.wait(remainMillis);
   2599                 } catch (InterruptedException ie) {
   2600                     /* ignore */
   2601                 }
   2602             }
   2603         }
   2604     }
   2605 
   2606     MagnificationController getMagnificationController() {
   2607         synchronized (mLock) {
   2608             if (mMagnificationController == null) {
   2609                 mMagnificationController = new MagnificationController(mContext, this, mLock);
   2610                 mMagnificationController.setUserId(mCurrentUserId);
   2611             }
   2612             return mMagnificationController;
   2613         }
   2614     }
   2615 
   2616     /**
   2617      * This class represents an accessibility service. It stores all per service
   2618      * data required for the service management, provides API for starting/stopping the
   2619      * service and is responsible for adding/removing the service in the data structures
   2620      * for service management. The class also exposes configuration interface that is
   2621      * passed to the service it represents as soon it is bound. It also serves as the
   2622      * connection for the service.
   2623      */
   2624     class Service extends IAccessibilityServiceConnection.Stub
   2625             implements ServiceConnection, DeathRecipient, KeyEventDispatcher.KeyEventFilter,
   2626             FingerprintGestureDispatcher.FingerprintGestureClient {
   2627 
   2628         final int mUserId;
   2629 
   2630         int mId = 0;
   2631 
   2632         AccessibilityServiceInfo mAccessibilityServiceInfo;
   2633 
   2634         // The service that's bound to this instance. Whenever this value is non-null, this
   2635         // object is registered as a death recipient
   2636         IBinder mService;
   2637 
   2638         IAccessibilityServiceClient mServiceInterface;
   2639 
   2640         int mEventTypes;
   2641 
   2642         int mFeedbackType;
   2643 
   2644         Set<String> mPackageNames = new HashSet<>();
   2645 
   2646         boolean mIsDefault;
   2647 
   2648         boolean mRequestTouchExplorationMode;
   2649 
   2650         boolean mRequestFilterKeyEvents;
   2651 
   2652         boolean mRetrieveInteractiveWindows;
   2653 
   2654         boolean mCaptureFingerprintGestures;
   2655 
   2656         boolean mRequestAccessibilityButton;
   2657 
   2658         boolean mReceivedAccessibilityButtonCallbackSinceBind;
   2659 
   2660         boolean mLastAccessibilityButtonCallbackState;
   2661 
   2662         int mFetchFlags;
   2663 
   2664         long mNotificationTimeout;
   2665 
   2666         ComponentName mComponentName;
   2667 
   2668         Intent mIntent;
   2669 
   2670         boolean mIsAutomation;
   2671 
   2672         final ResolveInfo mResolveInfo;
   2673 
   2674         final IBinder mOverlayWindowToken = new Binder();
   2675 
   2676         // the events pending events to be dispatched to this service
   2677         final SparseArray<AccessibilityEvent> mPendingEvents =
   2678             new SparseArray<>();
   2679 
   2680         boolean mWasConnectedAndDied;
   2681 
   2682         /** Whether this service relies on its {@link AccessibilityCache} being up to date */
   2683         boolean mUsesAccessibilityCache = false;
   2684 
   2685         // Handler only for dispatching accessibility events since we use event
   2686         // types as message types allowing us to remove messages per event type.
   2687         public Handler mEventDispatchHandler = new Handler(mMainHandler.getLooper()) {
   2688             @Override
   2689             public void handleMessage(Message message) {
   2690                 final int eventType =  message.what;
   2691                 AccessibilityEvent event = (AccessibilityEvent) message.obj;
   2692                 boolean serviceWantsEvent = message.arg1 != 0;
   2693                 notifyAccessibilityEventInternal(eventType, event, serviceWantsEvent);
   2694             }
   2695         };
   2696 
   2697         // Handler for scheduling method invocations on the main thread.
   2698         public final InvocationHandler mInvocationHandler = new InvocationHandler(
   2699                 mMainHandler.getLooper());
   2700 
   2701         public Service(int userId, ComponentName componentName,
   2702                 AccessibilityServiceInfo accessibilityServiceInfo) {
   2703             mUserId = userId;
   2704             mResolveInfo = accessibilityServiceInfo.getResolveInfo();
   2705             mId = sIdCounter++;
   2706             mComponentName = componentName;
   2707             mAccessibilityServiceInfo = accessibilityServiceInfo;
   2708             mIsAutomation = (sFakeAccessibilityServiceComponentName.equals(componentName));
   2709             if (!mIsAutomation) {
   2710                 mIntent = new Intent().setComponent(mComponentName);
   2711                 mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
   2712                         com.android.internal.R.string.accessibility_binding_label);
   2713                 final long idendtity = Binder.clearCallingIdentity();
   2714                 try {
   2715                     mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
   2716                             mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
   2717                 } finally {
   2718                     Binder.restoreCallingIdentity(idendtity);
   2719                 }
   2720             }
   2721             setDynamicallyConfigurableProperties(accessibilityServiceInfo);
   2722         }
   2723 
   2724         @Override
   2725         public boolean onKeyEvent(KeyEvent keyEvent, int sequenceNumber) {
   2726             if (!mRequestFilterKeyEvents || (mServiceInterface == null)) {
   2727                 return false;
   2728             }
   2729             if((mAccessibilityServiceInfo.getCapabilities()
   2730                     & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) == 0) {
   2731                 return false;
   2732             }
   2733             try {
   2734                 mServiceInterface.onKeyEvent(keyEvent, sequenceNumber);
   2735             } catch (RemoteException e) {
   2736                 return false;
   2737             }
   2738             return true;
   2739         }
   2740 
   2741         @Override
   2742         public boolean isCapturingFingerprintGestures() {
   2743             return (mServiceInterface != null)
   2744                     && mSecurityPolicy.canCaptureFingerprintGestures(this)
   2745                     && mCaptureFingerprintGestures;
   2746         }
   2747 
   2748         @Override
   2749         public void onFingerprintGestureDetectionActiveChanged(boolean active) {
   2750             if (!isCapturingFingerprintGestures()) {
   2751                 return;
   2752             }
   2753             IAccessibilityServiceClient serviceInterface;
   2754             synchronized (mLock) {
   2755                 serviceInterface = mServiceInterface;
   2756             }
   2757             if (serviceInterface != null) {
   2758                 try {
   2759                     mServiceInterface.onFingerprintCapturingGesturesChanged(active);
   2760                 } catch (RemoteException e) {
   2761                 }
   2762             }
   2763         }
   2764 
   2765         @Override
   2766         public void onFingerprintGesture(int gesture) {
   2767             if (!isCapturingFingerprintGestures()) {
   2768                 return;
   2769             }
   2770             IAccessibilityServiceClient serviceInterface;
   2771             synchronized (mLock) {
   2772                 serviceInterface = mServiceInterface;
   2773             }
   2774             if (serviceInterface != null) {
   2775                 try {
   2776                     mServiceInterface.onFingerprintGesture(gesture);
   2777                 } catch (RemoteException e) {
   2778                 }
   2779             }
   2780         }
   2781 
   2782         public void setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) {
   2783             mEventTypes = info.eventTypes;
   2784             mFeedbackType = info.feedbackType;
   2785             String[] packageNames = info.packageNames;
   2786             if (packageNames != null) {
   2787                 mPackageNames.addAll(Arrays.asList(packageNames));
   2788             }
   2789             mNotificationTimeout = info.notificationTimeout;
   2790             mIsDefault = (info.flags & DEFAULT) != 0;
   2791 
   2792             if (mIsAutomation || info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion
   2793                     >= Build.VERSION_CODES.JELLY_BEAN) {
   2794                 if ((info.flags & AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0) {
   2795                     mFetchFlags |= AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
   2796                 } else {
   2797                     mFetchFlags &= ~AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
   2798                 }
   2799             }
   2800 
   2801             if ((info.flags & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0) {
   2802                 mFetchFlags |= AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
   2803             } else {
   2804                 mFetchFlags &= ~AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
   2805             }
   2806 
   2807             mRequestTouchExplorationMode = (info.flags
   2808                     & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
   2809             mRequestFilterKeyEvents = (info.flags
   2810                     & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
   2811             mRetrieveInteractiveWindows = (info.flags
   2812                     & AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
   2813             mCaptureFingerprintGestures = (info.flags
   2814                     & AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES) != 0;
   2815             mRequestAccessibilityButton = (info.flags
   2816                     & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
   2817         }
   2818 
   2819         /**
   2820          * Binds to the accessibility service.
   2821          *
   2822          * @return True if binding is successful.
   2823          */
   2824         public boolean bindLocked() {
   2825             UserState userState = getUserStateLocked(mUserId);
   2826             if (!mIsAutomation) {
   2827                 final long identity = Binder.clearCallingIdentity();
   2828                 try {
   2829                     if (mService == null && mContext.bindServiceAsUser(
   2830                             mIntent, this,
   2831                             Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
   2832                             new UserHandle(mUserId))) {
   2833                         userState.mBindingServices.add(mComponentName);
   2834                     }
   2835                 } finally {
   2836                     Binder.restoreCallingIdentity(identity);
   2837                 }
   2838             } else {
   2839                 userState.mBindingServices.add(mComponentName);
   2840                 mMainHandler.post(new Runnable() {
   2841                     @Override
   2842                     public void run() {
   2843                         // Simulate asynchronous connection since in onServiceConnected
   2844                         // we may modify the state data in case of an error but bind is
   2845                         // called while iterating over the data and bad things can happen.
   2846                         onServiceConnected(mComponentName,
   2847                                 userState.mUiAutomationServiceClient.asBinder());
   2848                     }
   2849                 });
   2850                 userState.mUiAutomationService = this;
   2851             }
   2852             return false;
   2853         }
   2854 
   2855         /**
   2856          * Unbinds from the accessibility service and removes it from the data
   2857          * structures for service management.
   2858          *
   2859          * @return True if unbinding is successful.
   2860          */
   2861         public boolean unbindLocked() {
   2862             UserState userState = getUserStateLocked(mUserId);
   2863             getKeyEventDispatcher().flush(this);
   2864             if (!mIsAutomation) {
   2865                 mContext.unbindService(this);
   2866             } else {
   2867                 userState.destroyUiAutomationService();
   2868             }
   2869             removeServiceLocked(this, userState);
   2870             resetLocked();
   2871             return true;
   2872         }
   2873 
   2874         @Override
   2875         public void disableSelf() {
   2876             synchronized(mLock) {
   2877                 UserState userState = getUserStateLocked(mUserId);
   2878                 if (userState.mEnabledServices.remove(mComponentName)) {
   2879                     final long identity = Binder.clearCallingIdentity();
   2880                     try {
   2881                         persistComponentNamesToSettingLocked(
   2882                                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
   2883                                 userState.mEnabledServices, mUserId);
   2884                     } finally {
   2885                         Binder.restoreCallingIdentity(identity);
   2886                     }
   2887                     onUserStateChangedLocked(userState);
   2888                 }
   2889             }
   2890         }
   2891 
   2892         public boolean canReceiveEventsLocked() {
   2893             return (mEventTypes != 0 && mFeedbackType != 0 && mService != null);
   2894         }
   2895 
   2896         @Override
   2897         public void setOnKeyEventResult(boolean handled, int sequence) {
   2898             getKeyEventDispatcher().setOnKeyEventResult(this, handled, sequence);
   2899         }
   2900 
   2901         @Override
   2902         public AccessibilityServiceInfo getServiceInfo() {
   2903             synchronized (mLock) {
   2904                 return mAccessibilityServiceInfo;
   2905             }
   2906         }
   2907 
   2908         public boolean canRetrieveInteractiveWindowsLocked() {
   2909             return mSecurityPolicy.canRetrieveWindowContentLocked(this)
   2910                     && mRetrieveInteractiveWindows;
   2911         }
   2912 
   2913         @Override
   2914         public void setServiceInfo(AccessibilityServiceInfo info) {
   2915             final long identity = Binder.clearCallingIdentity();
   2916             try {
   2917                 synchronized (mLock) {
   2918                     // If the XML manifest had data to configure the service its info
   2919                     // should be already set. In such a case update only the dynamically
   2920                     // configurable properties.
   2921                     AccessibilityServiceInfo oldInfo = mAccessibilityServiceInfo;
   2922                     if (oldInfo != null) {
   2923                         oldInfo.updateDynamicallyConfigurableProperties(info);
   2924                         setDynamicallyConfigurableProperties(oldInfo);
   2925                     } else {
   2926                         setDynamicallyConfigurableProperties(info);
   2927                     }
   2928                     UserState userState = getUserStateLocked(mUserId);
   2929                     onUserStateChangedLocked(userState);
   2930                     scheduleNotifyClientsOfServicesStateChange(userState);
   2931                 }
   2932             } finally {
   2933                 Binder.restoreCallingIdentity(identity);
   2934             }
   2935         }
   2936 
   2937         @Override
   2938         public void onServiceConnected(ComponentName componentName, IBinder service) {
   2939             synchronized (mLock) {
   2940                 if (mService != service) {
   2941                     if (mService != null) {
   2942                         mService.unlinkToDeath(this, 0);
   2943                     }
   2944                     mService = service;
   2945                     try {
   2946                         mService.linkToDeath(this, 0);
   2947                     } catch (RemoteException re) {
   2948                         Slog.e(LOG_TAG, "Failed registering death link");
   2949                         binderDied();
   2950                         return;
   2951                     }
   2952                 }
   2953                 mServiceInterface = IAccessibilityServiceClient.Stub.asInterface(service);
   2954                 UserState userState = getUserStateLocked(mUserId);
   2955                 addServiceLocked(this, userState);
   2956                 if (userState.mBindingServices.contains(mComponentName) || mWasConnectedAndDied) {
   2957                     userState.mBindingServices.remove(mComponentName);
   2958                     mWasConnectedAndDied = false;
   2959                     onUserStateChangedLocked(userState);
   2960                     // Initialize the service on the main handler after we're done setting up for
   2961                     // the new configuration (for example, initializing the input filter).
   2962                     mMainHandler.obtainMessage(MainHandler.MSG_INIT_SERVICE, this).sendToTarget();
   2963                 } else {
   2964                     binderDied();
   2965                 }
   2966             }
   2967         }
   2968 
   2969         private void initializeService() {
   2970             final IAccessibilityServiceClient serviceInterface;
   2971             synchronized (mLock) {
   2972                 serviceInterface = mServiceInterface;
   2973             }
   2974             if (serviceInterface == null) return;
   2975             try {
   2976                 serviceInterface.init(this, mId, mOverlayWindowToken);
   2977             } catch (RemoteException re) {
   2978                 Slog.w(LOG_TAG, "Error while setting connection for service: "
   2979                         + serviceInterface, re);
   2980                 binderDied();
   2981             }
   2982         }
   2983 
   2984         private boolean isCalledForCurrentUserLocked() {
   2985             // We treat calls from a profile as if made by its parent as profiles
   2986             // share the accessibility state of the parent. The call below
   2987             // performs the current profile parent resolution.
   2988             final int resolvedUserId = mSecurityPolicy
   2989                     .resolveCallingUserIdEnforcingPermissionsLocked(UserHandle.USER_CURRENT);
   2990             return resolvedUserId == mCurrentUserId;
   2991         }
   2992 
   2993         @Override
   2994         public List<AccessibilityWindowInfo> getWindows() {
   2995             ensureWindowsAvailableTimed();
   2996             synchronized (mLock) {
   2997                 if (!isCalledForCurrentUserLocked()) {
   2998                     return null;
   2999                 }
   3000                 final boolean permissionGranted =
   3001                         mSecurityPolicy.canRetrieveWindowsLocked(this);
   3002                 if (!permissionGranted) {
   3003                     return null;
   3004                 }
   3005                 if (mSecurityPolicy.mWindows == null) {
   3006                     return null;
   3007                 }
   3008                 List<AccessibilityWindowInfo> windows = new ArrayList<>();
   3009                 final int windowCount = mSecurityPolicy.mWindows.size();
   3010                 for (int i = 0; i < windowCount; i++) {
   3011                     AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(i);
   3012                     AccessibilityWindowInfo windowClone =
   3013                             AccessibilityWindowInfo.obtain(window);
   3014                     windowClone.setConnectionId(mId);
   3015                     windows.add(windowClone);
   3016                 }
   3017                 return windows;
   3018             }
   3019         }
   3020 
   3021         @Override
   3022         public AccessibilityWindowInfo getWindow(int windowId) {
   3023             ensureWindowsAvailableTimed();
   3024             synchronized (mLock) {
   3025                 if (!isCalledForCurrentUserLocked()) {
   3026                     return null;
   3027                 }
   3028                 final boolean permissionGranted =
   3029                         mSecurityPolicy.canRetrieveWindowsLocked(this);
   3030                 if (!permissionGranted) {
   3031                     return null;
   3032                 }
   3033                 AccessibilityWindowInfo window = mSecurityPolicy.findA11yWindowInfoById(windowId);
   3034                 if (window != null) {
   3035                     AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window);
   3036                     windowClone.setConnectionId(mId);
   3037                     return windowClone;
   3038                 }
   3039                 return null;
   3040             }
   3041         }
   3042 
   3043         @Override
   3044         public boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
   3045                 long accessibilityNodeId, String viewIdResName, int interactionId,
   3046                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
   3047                 throws RemoteException {
   3048             final int resolvedWindowId;
   3049             IAccessibilityInteractionConnection connection = null;
   3050             Region partialInteractiveRegion = Region.obtain();
   3051             MagnificationSpec spec;
   3052             synchronized (mLock) {
   3053                 mUsesAccessibilityCache = true;
   3054                 if (!isCalledForCurrentUserLocked()) {
   3055                     return false;
   3056                 }
   3057                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
   3058                 final boolean permissionGranted =
   3059                         mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
   3060                 if (!permissionGranted) {
   3061                     return false;
   3062                 } else {
   3063                     connection = getConnectionLocked(resolvedWindowId);
   3064                     if (connection == null) {
   3065                         return false;
   3066                     }
   3067                 }
   3068                 if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
   3069                         resolvedWindowId, partialInteractiveRegion)) {
   3070                     partialInteractiveRegion.recycle();
   3071                     partialInteractiveRegion = null;
   3072                 }
   3073                 spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
   3074             }
   3075             final int interrogatingPid = Binder.getCallingPid();
   3076             callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
   3077                     interrogatingPid, interrogatingTid);
   3078             final long identityToken = Binder.clearCallingIdentity();
   3079             try {
   3080                 connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName,
   3081                         partialInteractiveRegion, interactionId, callback, mFetchFlags,
   3082                         interrogatingPid, interrogatingTid, spec);
   3083                 return true;
   3084             } catch (RemoteException re) {
   3085                 if (DEBUG) {
   3086                     Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId().");
   3087                 }
   3088             } finally {
   3089                 Binder.restoreCallingIdentity(identityToken);
   3090                 // Recycle if passed to another process.
   3091                 if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
   3092                     partialInteractiveRegion.recycle();
   3093                 }
   3094             }
   3095             return false;
   3096         }
   3097 
   3098         @Override
   3099         public boolean findAccessibilityNodeInfosByText(int accessibilityWindowId,
   3100                 long accessibilityNodeId, String text, int interactionId,
   3101                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
   3102                 throws RemoteException {
   3103             final int resolvedWindowId;
   3104             IAccessibilityInteractionConnection connection = null;
   3105             Region partialInteractiveRegion = Region.obtain();
   3106             MagnificationSpec spec;
   3107             synchronized (mLock) {
   3108                 mUsesAccessibilityCache = true;
   3109                 if (!isCalledForCurrentUserLocked()) {
   3110                     return false;
   3111                 }
   3112                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
   3113                 final boolean permissionGranted =
   3114                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
   3115                 if (!permissionGranted) {
   3116                     return false;
   3117                 } else {
   3118                     connection = getConnectionLocked(resolvedWindowId);
   3119                     if (connection == null) {
   3120                         return false;
   3121                     }
   3122                 }
   3123                 if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
   3124                         resolvedWindowId, partialInteractiveRegion)) {
   3125                     partialInteractiveRegion.recycle();
   3126                     partialInteractiveRegion = null;
   3127                 }
   3128                 spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
   3129             }
   3130             final int interrogatingPid = Binder.getCallingPid();
   3131             callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
   3132                     interrogatingPid, interrogatingTid);
   3133             final long identityToken = Binder.clearCallingIdentity();
   3134             try {
   3135                 connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
   3136                         partialInteractiveRegion, interactionId, callback, mFetchFlags,
   3137                         interrogatingPid, interrogatingTid, spec);
   3138                 return true;
   3139             } catch (RemoteException re) {
   3140                 if (DEBUG) {
   3141                     Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()");
   3142                 }
   3143             } finally {
   3144                 Binder.restoreCallingIdentity(identityToken);
   3145                 // Recycle if passed to another process.
   3146                 if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
   3147                     partialInteractiveRegion.recycle();
   3148                 }
   3149             }
   3150             return false;
   3151         }
   3152 
   3153         @Override
   3154         public boolean findAccessibilityNodeInfoByAccessibilityId(
   3155                 int accessibilityWindowId, long accessibilityNodeId, int interactionId,
   3156                 IAccessibilityInteractionConnectionCallback callback, int flags,
   3157                 long interrogatingTid, Bundle arguments) throws RemoteException {
   3158             final int resolvedWindowId;
   3159             IAccessibilityInteractionConnection connection = null;
   3160             Region partialInteractiveRegion = Region.obtain();
   3161             MagnificationSpec spec;
   3162             synchronized (mLock) {
   3163                 mUsesAccessibilityCache = true;
   3164                 if (!isCalledForCurrentUserLocked()) {
   3165                     return false;
   3166                 }
   3167                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
   3168                 final boolean permissionGranted =
   3169                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
   3170                 if (!permissionGranted) {
   3171                     return false;
   3172                 } else {
   3173                     connection = getConnectionLocked(resolvedWindowId);
   3174                     if (connection == null) {
   3175                         return false;
   3176                     }
   3177                 }
   3178                 if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
   3179                         resolvedWindowId, partialInteractiveRegion)) {
   3180                     partialInteractiveRegion.recycle();
   3181                     partialInteractiveRegion = null;
   3182                 }
   3183                 spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
   3184             }
   3185             final int interrogatingPid = Binder.getCallingPid();
   3186             callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
   3187                     interrogatingPid, interrogatingTid);
   3188             final long identityToken = Binder.clearCallingIdentity();
   3189             try {
   3190                 connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
   3191                         partialInteractiveRegion, interactionId, callback, mFetchFlags | flags,
   3192                         interrogatingPid, interrogatingTid, spec, arguments);
   3193                 return true;
   3194             } catch (RemoteException re) {
   3195                 if (DEBUG) {
   3196                     Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
   3197                 }
   3198             } finally {
   3199                 Binder.restoreCallingIdentity(identityToken);
   3200                 // Recycle if passed to another process.
   3201                 if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
   3202                     partialInteractiveRegion.recycle();
   3203                 }
   3204             }
   3205             return false;
   3206         }
   3207 
   3208         @Override
   3209         public boolean findFocus(int accessibilityWindowId, long accessibilityNodeId,
   3210                 int focusType, int interactionId,
   3211                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
   3212                 throws RemoteException {
   3213             final int resolvedWindowId;
   3214             IAccessibilityInteractionConnection connection = null;
   3215             Region partialInteractiveRegion = Region.obtain();
   3216             MagnificationSpec spec;
   3217             synchronized (mLock) {
   3218                 if (!isCalledForCurrentUserLocked()) {
   3219                     return false;
   3220                 }
   3221                 resolvedWindowId = resolveAccessibilityWindowIdForFindFocusLocked(
   3222                         accessibilityWindowId, focusType);
   3223                 final boolean permissionGranted =
   3224                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
   3225                 if (!permissionGranted) {
   3226                     return false;
   3227                 } else {
   3228                     connection = getConnectionLocked(resolvedWindowId);
   3229                     if (connection == null) {
   3230                         return false;
   3231                     }
   3232                 }
   3233                 if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
   3234                         resolvedWindowId, partialInteractiveRegion)) {
   3235                     partialInteractiveRegion.recycle();
   3236                     partialInteractiveRegion = null;
   3237                 }
   3238                 spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
   3239             }
   3240             final int interrogatingPid = Binder.getCallingPid();
   3241             callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
   3242                     interrogatingPid, interrogatingTid);
   3243             final long identityToken = Binder.clearCallingIdentity();
   3244             try {
   3245                 connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion,
   3246                         interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
   3247                         spec);
   3248                 return true;
   3249             } catch (RemoteException re) {
   3250                 if (DEBUG) {
   3251                     Slog.e(LOG_TAG, "Error calling findFocus()");
   3252                 }
   3253             } finally {
   3254                 Binder.restoreCallingIdentity(identityToken);
   3255                 // Recycle if passed to another process.
   3256                 if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
   3257                     partialInteractiveRegion.recycle();
   3258                 }
   3259             }
   3260             return false;
   3261         }
   3262 
   3263         @Override
   3264         public boolean focusSearch(int accessibilityWindowId, long accessibilityNodeId,
   3265                 int direction, int interactionId,
   3266                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
   3267                 throws RemoteException {
   3268             final int resolvedWindowId;
   3269             IAccessibilityInteractionConnection connection = null;
   3270             Region partialInteractiveRegion = Region.obtain();
   3271             MagnificationSpec spec;
   3272             synchronized (mLock) {
   3273                 if (!isCalledForCurrentUserLocked()) {
   3274                     return false;
   3275                 }
   3276                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
   3277                 final boolean permissionGranted =
   3278                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
   3279                 if (!permissionGranted) {
   3280                     return false;
   3281                 } else {
   3282                     connection = getConnectionLocked(resolvedWindowId);
   3283                     if (connection == null) {
   3284                         return false;
   3285                     }
   3286                 }
   3287                 if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
   3288                         resolvedWindowId, partialInteractiveRegion)) {
   3289                     partialInteractiveRegion.recycle();
   3290                     partialInteractiveRegion = null;
   3291                 }
   3292                 spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
   3293             }
   3294             final int interrogatingPid = Binder.getCallingPid();
   3295             callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
   3296                     interrogatingPid, interrogatingTid);
   3297             final long identityToken = Binder.clearCallingIdentity();
   3298             try {
   3299                 connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion,
   3300                         interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
   3301                         spec);
   3302                 return true;
   3303             } catch (RemoteException re) {
   3304                 if (DEBUG) {
   3305                     Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()");
   3306                 }
   3307             } finally {
   3308                 Binder.restoreCallingIdentity(identityToken);
   3309                 // Recycle if passed to another process.
   3310                 if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
   3311                     partialInteractiveRegion.recycle();
   3312                 }
   3313             }
   3314             return false;
   3315         }
   3316 
   3317         @Override
   3318         public void sendGesture(int sequence, ParceledListSlice gestureSteps) {
   3319             synchronized (mLock) {
   3320                 if (mSecurityPolicy.canPerformGestures(this)) {
   3321                     final long endMillis =
   3322                             SystemClock.uptimeMillis() + WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS;
   3323                     while ((mMotionEventInjector == null)
   3324                             && (SystemClock.uptimeMillis() < endMillis)) {
   3325                         try {
   3326                             mLock.wait(endMillis - SystemClock.uptimeMillis());
   3327                         } catch (InterruptedException ie) {
   3328                             /* ignore */
   3329                         }
   3330                     }
   3331                     if (mMotionEventInjector != null) {
   3332                         List<GestureDescription.GestureStep> steps = gestureSteps.getList();
   3333                         mMotionEventInjector.injectEvents(steps, mServiceInterface, sequence);
   3334                         return;
   3335                     } else {
   3336                         Slog.e(LOG_TAG, "MotionEventInjector installation timed out");
   3337                     }
   3338                 }
   3339             }
   3340             try {
   3341                 mServiceInterface.onPerformGestureResult(sequence, false);
   3342             } catch (RemoteException re) {
   3343                 Slog.e(LOG_TAG, "Error sending motion event injection failure to "
   3344                         + mServiceInterface, re);
   3345             }
   3346         }
   3347 
   3348         @Override
   3349         public boolean performAccessibilityAction(int accessibilityWindowId,
   3350                 long accessibilityNodeId, int action, Bundle arguments, int interactionId,
   3351                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
   3352                 throws RemoteException {
   3353             final int resolvedWindowId;
   3354             IAccessibilityInteractionConnection connection = null;
   3355             IBinder activityToken = null;
   3356             synchronized (mLock) {
   3357                 if (!isCalledForCurrentUserLocked()) {
   3358                     return false;
   3359                 }
   3360                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
   3361                 if (!mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId)) {
   3362                     return false;
   3363                 }
   3364                 connection = getConnectionLocked(resolvedWindowId);
   3365                 if (connection == null) return false;
   3366                 final boolean isA11yFocusAction = (action == ACTION_ACCESSIBILITY_FOCUS)
   3367                         || (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS);
   3368                 final AccessibilityWindowInfo a11yWindowInfo =
   3369                         mSecurityPolicy.findA11yWindowInfoById(resolvedWindowId);
   3370                 if (!isA11yFocusAction) {
   3371                     final WindowInfo windowInfo =
   3372                             mSecurityPolicy.findWindowInfoById(resolvedWindowId);
   3373                     if (windowInfo != null) activityToken = windowInfo.activityToken;
   3374                 }
   3375                 if ((a11yWindowInfo != null) && a11yWindowInfo.inPictureInPicture()) {
   3376                     if ((mPictureInPictureActionReplacingConnection != null)
   3377                             && !isA11yFocusAction) {
   3378                         connection = mPictureInPictureActionReplacingConnection.mConnection;
   3379                     }
   3380                 }
   3381             }
   3382             final int interrogatingPid = Binder.getCallingPid();
   3383             final long identityToken = Binder.clearCallingIdentity();
   3384             try {
   3385                 // Regardless of whether or not the action succeeds, it was generated by an
   3386                 // accessibility service that is driven by user actions, so note user activity.
   3387                 mPowerManager.userActivity(SystemClock.uptimeMillis(),
   3388                         PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY, 0);
   3389 
   3390                 if (activityToken != null) {
   3391                     LocalServices.getService(ActivityManagerInternal.class)
   3392                             .setFocusedActivity(activityToken);
   3393                 }
   3394                 connection.performAccessibilityAction(accessibilityNodeId, action, arguments,
   3395                         interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid);
   3396             } catch (RemoteException re) {
   3397                 if (DEBUG) {
   3398                     Slog.e(LOG_TAG, "Error calling performAccessibilityAction()");
   3399                 }
   3400             } finally {
   3401                 Binder.restoreCallingIdentity(identityToken);
   3402             }
   3403             return true;
   3404         }
   3405 
   3406         @Override
   3407         public boolean performGlobalAction(int action) {
   3408             synchronized (mLock) {
   3409                 if (!isCalledForCurrentUserLocked()) {
   3410                     return false;
   3411                 }
   3412             }
   3413             final long identity = Binder.clearCallingIdentity();
   3414             try {
   3415                 mPowerManager.userActivity(SystemClock.uptimeMillis(),
   3416                         PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY, 0);
   3417                 switch (action) {
   3418                     case AccessibilityService.GLOBAL_ACTION_BACK: {
   3419                         sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK);
   3420                     } return true;
   3421                     case AccessibilityService.GLOBAL_ACTION_HOME: {
   3422                         sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME);
   3423                     } return true;
   3424                     case AccessibilityService.GLOBAL_ACTION_RECENTS: {
   3425                         return openRecents();
   3426                     }
   3427                     case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: {
   3428                         expandNotifications();
   3429                     } return true;
   3430                     case AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS: {
   3431                         expandQuickSettings();
   3432                     } return true;
   3433                     case AccessibilityService.GLOBAL_ACTION_POWER_DIALOG: {
   3434                         showGlobalActions();
   3435                     } return true;
   3436                     case AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN: {
   3437                         toggleSplitScreen();
   3438                     } return true;
   3439                 }
   3440                 return false;
   3441             } finally {
   3442                 Binder.restoreCallingIdentity(identity);
   3443             }
   3444         }
   3445 
   3446         @Override
   3447         public boolean isFingerprintGestureDetectionAvailable() {
   3448             return isCapturingFingerprintGestures()
   3449                     && (mFingerprintGestureDispatcher != null)
   3450                     && mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable();
   3451         }
   3452 
   3453         @Override
   3454         public float getMagnificationScale() {
   3455             synchronized (mLock) {
   3456                 if (!isCalledForCurrentUserLocked()) {
   3457                     return 1.0f;
   3458                 }
   3459             }
   3460             final long identity = Binder.clearCallingIdentity();
   3461             try {
   3462                 return getMagnificationController().getScale();
   3463             } finally {
   3464                 Binder.restoreCallingIdentity(identity);
   3465             }
   3466         }
   3467 
   3468         @Override
   3469         public Region getMagnificationRegion() {
   3470             synchronized (mLock) {
   3471                 final Region region = Region.obtain();
   3472                 if (!isCalledForCurrentUserLocked()) {
   3473                     return region;
   3474                 }
   3475                 MagnificationController magnificationController = getMagnificationController();
   3476                 boolean registeredJustForThisCall =
   3477                         registerMagnificationIfNeeded(magnificationController);
   3478                 final long identity = Binder.clearCallingIdentity();
   3479                 try {
   3480                     magnificationController.getMagnificationRegion(region);
   3481                     return region;
   3482                 } finally {
   3483                     Binder.restoreCallingIdentity(identity);
   3484                     if (registeredJustForThisCall) {
   3485                         magnificationController.unregister();
   3486                     }
   3487                 }
   3488             }
   3489         }
   3490 
   3491         @Override
   3492         public float getMagnificationCenterX() {
   3493             synchronized (mLock) {
   3494                 if (!isCalledForCurrentUserLocked()) {
   3495                     return 0.0f;
   3496                 }
   3497             }
   3498             MagnificationController magnificationController = getMagnificationController();
   3499             boolean registeredJustForThisCall =
   3500                     registerMagnificationIfNeeded(magnificationController);
   3501             final long identity = Binder.clearCallingIdentity();
   3502             try {
   3503                 return magnificationController.getCenterX();
   3504             } finally {
   3505                 Binder.restoreCallingIdentity(identity);
   3506                 if (registeredJustForThisCall) {
   3507                     magnificationController.unregister();
   3508                 }
   3509             }
   3510         }
   3511 
   3512         @Override
   3513         public float getMagnificationCenterY() {
   3514             synchronized (mLock) {
   3515                 if (!isCalledForCurrentUserLocked()) {
   3516                     return 0.0f;
   3517                 }
   3518             }
   3519             MagnificationController magnificationController = getMagnificationController();
   3520             boolean registeredJustForThisCall =
   3521                     registerMagnificationIfNeeded(magnificationController);
   3522             final long identity = Binder.clearCallingIdentity();
   3523             try {
   3524                 return magnificationController.getCenterY();
   3525             } finally {
   3526                 Binder.restoreCallingIdentity(identity);
   3527                 if (registeredJustForThisCall) {
   3528                     magnificationController.unregister();
   3529                 }
   3530             }
   3531         }
   3532 
   3533         private boolean registerMagnificationIfNeeded(
   3534                 MagnificationController magnificationController) {
   3535             if (!magnificationController.isRegisteredLocked()
   3536                     && mSecurityPolicy.canControlMagnification(this)) {
   3537                 magnificationController.register();
   3538                 return true;
   3539             }
   3540             return false;
   3541         }
   3542 
   3543         @Override
   3544         public boolean resetMagnification(boolean animate) {
   3545             synchronized (mLock) {
   3546                 if (!isCalledForCurrentUserLocked()) {
   3547                     return false;
   3548                 }
   3549                 final boolean permissionGranted = mSecurityPolicy.canControlMagnification(this);
   3550                 if (!permissionGranted) {
   3551                     return false;
   3552                 }
   3553             }
   3554             final long identity = Binder.clearCallingIdentity();
   3555             try {
   3556                 return getMagnificationController().reset(animate);
   3557             } finally {
   3558                 Binder.restoreCallingIdentity(identity);
   3559             }
   3560         }
   3561 
   3562         @Override
   3563         public boolean setMagnificationScaleAndCenter(float scale, float centerX, float centerY,
   3564                 boolean animate) {
   3565             synchronized (mLock) {
   3566                 if (!isCalledForCurrentUserLocked()) {
   3567                     return false;
   3568                 }
   3569                 final boolean permissionGranted = mSecurityPolicy.canControlMagnification(this);
   3570                 if (!permissionGranted) {
   3571                     return false;
   3572                 }
   3573                 final long identity = Binder.clearCallingIdentity();
   3574                 try {
   3575                     MagnificationController magnificationController = getMagnificationController();
   3576                     if (!magnificationController.isRegisteredLocked()) {
   3577                         magnificationController.register();
   3578                     }
   3579                     return magnificationController
   3580                             .setScaleAndCenter(scale, centerX, centerY, animate, mId);
   3581                 } finally {
   3582                     Binder.restoreCallingIdentity(identity);
   3583                 }
   3584             }
   3585         }
   3586 
   3587         @Override
   3588         public void setMagnificationCallbackEnabled(boolean enabled) {
   3589             mInvocationHandler.setMagnificationCallbackEnabled(enabled);
   3590         }
   3591 
   3592         @Override
   3593         public boolean setSoftKeyboardShowMode(int showMode) {
   3594             final UserState userState;
   3595             synchronized (mLock) {
   3596                 if (!isCalledForCurrentUserLocked()) {
   3597                     return false;
   3598                 }
   3599 
   3600                 userState = getCurrentUserStateLocked();
   3601             }
   3602 
   3603             final long identity = Binder.clearCallingIdentity();
   3604             try {
   3605                 // Keep track of the last service to request a non-default show mode. The show mode
   3606                 // should be restored to default should this service be disabled.
   3607                 if (showMode == Settings.Secure.SHOW_MODE_AUTO) {
   3608                     userState.mServiceChangingSoftKeyboardMode = null;
   3609                 } else {
   3610                     userState.mServiceChangingSoftKeyboardMode = mComponentName;
   3611                 }
   3612 
   3613                 Settings.Secure.putIntForUser(mContext.getContentResolver(),
   3614                         Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, showMode,
   3615                         userState.mUserId);
   3616             } finally {
   3617                 Binder.restoreCallingIdentity(identity);
   3618             }
   3619             return true;
   3620         }
   3621 
   3622         @Override
   3623         public void setSoftKeyboardCallbackEnabled(boolean enabled) {
   3624             mInvocationHandler.setSoftKeyboardCallbackEnabled(enabled);
   3625         }
   3626 
   3627         @Override
   3628         public boolean isAccessibilityButtonAvailable() {
   3629             final UserState userState;
   3630             synchronized (mLock) {
   3631                 if (!isCalledForCurrentUserLocked()) {
   3632                     return false;
   3633                 }
   3634                 userState = getCurrentUserStateLocked();
   3635                 return isAccessibilityButtonAvailableLocked(userState);
   3636             }
   3637         }
   3638 
   3639         @Override
   3640         public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
   3641             if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
   3642             synchronized (mLock) {
   3643                 pw.append("Service[label=" + mAccessibilityServiceInfo.getResolveInfo()
   3644                         .loadLabel(mContext.getPackageManager()));
   3645                 pw.append(", feedbackType"
   3646                         + AccessibilityServiceInfo.feedbackTypeToString(mFeedbackType));
   3647                 pw.append(", capabilities=" + mAccessibilityServiceInfo.getCapabilities());
   3648                 pw.append(", eventTypes="
   3649                         + AccessibilityEvent.eventTypeToString(mEventTypes));
   3650                 pw.append(", notificationTimeout=" + mNotificationTimeout);
   3651                 pw.append("]");
   3652             }
   3653         }
   3654 
   3655         @Override
   3656         public void onServiceDisconnected(ComponentName componentName) {
   3657             binderDied();
   3658         }
   3659 
   3660         public void onAdded() throws RemoteException {
   3661             final long identity = Binder.clearCallingIdentity();
   3662             try {
   3663                 mWindowManagerService.addWindowToken(mOverlayWindowToken,
   3664                         TYPE_ACCESSIBILITY_OVERLAY, DEFAULT_DISPLAY);
   3665             } finally {
   3666                 Binder.restoreCallingIdentity(identity);
   3667             }
   3668         }
   3669 
   3670         public void onRemoved() {
   3671             final long identity = Binder.clearCallingIdentity();
   3672             try {
   3673                 mWindowManagerService.removeWindowToken(mOverlayWindowToken, true, DEFAULT_DISPLAY);
   3674             } finally {
   3675                 Binder.restoreCallingIdentity(identity);
   3676             }
   3677         }
   3678 
   3679         public void resetLocked() {
   3680             try {
   3681                 // Clear the proxy in the other process so this
   3682                 // IAccessibilityServiceConnection can be garbage collected.
   3683                 if (mServiceInterface != null) {
   3684                     mServiceInterface.init(null, mId, null);
   3685                 }
   3686             } catch (RemoteException re) {
   3687                 /* ignore */
   3688             }
   3689             if (mService != null) {
   3690                 mService.unlinkToDeath(this, 0);
   3691                 mService = null;
   3692             }
   3693             mServiceInterface = null;
   3694             mReceivedAccessibilityButtonCallbackSinceBind = false;
   3695         }
   3696 
   3697         public boolean isConnectedLocked() {
   3698             return (mService != null);
   3699         }
   3700 
   3701         public void binderDied() {
   3702             synchronized (mLock) {
   3703                 // It is possible that this service's package was force stopped during
   3704                 // whose handling the death recipient is unlinked and still get a call
   3705                 // on binderDied since the call was made before we unlink but was
   3706                 // waiting on the lock we held during the force stop handling.
   3707                 if (!isConnectedLocked()) {
   3708                     return;
   3709                 }
   3710                 mWasConnectedAndDied = true;
   3711                 getKeyEventDispatcher().flush(this);
   3712                 UserState userState = getUserStateLocked(mUserId);
   3713                 resetLocked();
   3714                 if (mIsAutomation) {
   3715                     // This is typically done when unbinding, but UiAutomation isn't bound.
   3716                     removeServiceLocked(this, userState);
   3717                     // We no longer have an automation service, so restore
   3718                     // the state based on values in the settings database.
   3719                     userState.mInstalledServices.remove(mAccessibilityServiceInfo);
   3720                     userState.mEnabledServices.remove(mComponentName);
   3721                     userState.destroyUiAutomationService();
   3722                     readConfigurationForUserStateLocked(userState);
   3723                 }
   3724                 if (mId == getMagnificationController().getIdOfLastServiceToMagnify()) {
   3725                     getMagnificationController().resetIfNeeded(true);
   3726                 }
   3727                 onUserStateChangedLocked(userState);
   3728             }
   3729         }
   3730 
   3731         /**
   3732          * Performs a notification for an {@link AccessibilityEvent}.
   3733          *
   3734          * @param event The event.
   3735          * @param serviceWantsEvent whether the event should be received by
   3736          *  {@link AccessibilityService#onAccessibilityEvent} (true),
   3737          *  as opposed to just {@link AccessibilityInteractionClient#onAccessibilityEvent} (false)
   3738          */
   3739         public void notifyAccessibilityEvent(AccessibilityEvent event, boolean serviceWantsEvent) {
   3740             synchronized (mLock) {
   3741                 final int eventType = event.getEventType();
   3742                 // Make a copy since during dispatch it is possible the event to
   3743                 // be modified to remove its source if the receiving service does
   3744                 // not have permission to access the window content.
   3745                 AccessibilityEvent newEvent = AccessibilityEvent.obtain(event);
   3746                 Message message;
   3747                 if ((mNotificationTimeout > 0)
   3748                         && (eventType != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)) {
   3749                     // Allow at most one pending event
   3750                     final AccessibilityEvent oldEvent = mPendingEvents.get(eventType);
   3751                     mPendingEvents.put(eventType, newEvent);
   3752                     if (oldEvent != null) {
   3753                         mEventDispatchHandler.removeMessages(eventType);
   3754                         oldEvent.recycle();
   3755                     }
   3756                     message = mEventDispatchHandler.obtainMessage(eventType);
   3757                 } else {
   3758                     // Send all messages, bypassing mPendingEvents
   3759                     message = mEventDispatchHandler.obtainMessage(eventType, newEvent);
   3760                 }
   3761                 message.arg1 = serviceWantsEvent ? 1 : 0;
   3762 
   3763                 mEventDispatchHandler.sendMessageDelayed(message, mNotificationTimeout);
   3764             }
   3765         }
   3766 
   3767         private boolean isAccessibilityButtonAvailableLocked(UserState userState) {
   3768             // If the service does not request the accessibility button, it isn't available
   3769             if (!mRequestAccessibilityButton) {
   3770                 return false;
   3771             }
   3772 
   3773             // If the accessibility button isn't currently shown, it cannot be available to services
   3774             if (!mIsAccessibilityButtonShown) {
   3775                 return false;
   3776             }
   3777 
   3778             // If magnification is on and assigned to the accessibility button, services cannot be
   3779             if (userState.mIsNavBarMagnificationEnabled
   3780                     && userState.mIsNavBarMagnificationAssignedToAccessibilityButton) {
   3781                 return false;
   3782             }
   3783 
   3784             int requestingServices = 0;
   3785             for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
   3786                 final Service service = userState.mBoundServices.get(i);
   3787                 if (service.mRequestAccessibilityButton) {
   3788                     requestingServices++;
   3789                 }
   3790             }
   3791 
   3792             if (requestingServices == 1) {
   3793                 // If only a single service is requesting, it must be this service, and the
   3794                 // accessibility button is available to it
   3795                 return true;
   3796             } else {
   3797                 // With more than one active service, we derive the target from the user's settings
   3798                 if (userState.mServiceAssignedToAccessibilityButton == null) {
   3799                     // If the user has not made an assignment, we treat the button as available to
   3800                     // all services until the user interacts with the button to make an assignment
   3801                     return true;
   3802                 } else {
   3803                     // If an assignment was made, it defines availability
   3804                     return mComponentName.equals(userState.mServiceAssignedToAccessibilityButton);
   3805                 }
   3806             }
   3807         }
   3808 
   3809         /**
   3810          * Notifies an accessibility service client for a scheduled event given the event type.
   3811          *
   3812          * @param eventType The type of the event to dispatch.
   3813          */
   3814         private void notifyAccessibilityEventInternal(
   3815                 int eventType,
   3816                 AccessibilityEvent event,
   3817                 boolean serviceWantsEvent) {
   3818             IAccessibilityServiceClient listener;
   3819 
   3820             synchronized (mLock) {
   3821                 listener = mServiceInterface;
   3822 
   3823                 // If the service died/was disabled while the message for dispatching
   3824                 // the accessibility event was propagating the listener may be null.
   3825                 if (listener == null) {
   3826                     return;
   3827                 }
   3828 
   3829                 // There are two ways we notify for events, throttled and non-throttled. If we
   3830                 // are not throttling, then messages come with events, which we handle with
   3831                 // minimal fuss.
   3832                 if (event == null) {
   3833                     // We are throttling events, so we'll send the event for this type in
   3834                     // mPendingEvents as long as it it's null. It can only null due to a race
   3835                     // condition:
   3836                     //
   3837                     //   1) A binder thread calls notifyAccessibilityServiceDelayedLocked
   3838                     //      which posts a message for dispatching an event and stores the event
   3839                     //      in mPendingEvents.
   3840                     //   2) The message is pulled from the queue by the handler on the service
   3841                     //      thread and this method is just about to acquire the lock.
   3842                     //   3) Another binder thread acquires the lock in notifyAccessibilityEvent
   3843                     //   4) notifyAccessibilityEvent recycles the event that this method was about
   3844                     //      to process, replaces it with a new one, and posts a second message
   3845                     //   5) This method grabs the new event, processes it, and removes it from
   3846                     //      mPendingEvents
   3847                     //   6) The second message dispatched in (4) arrives, but the event has been
   3848                     //      remvoved in (5).
   3849                     event = mPendingEvents.get(eventType);
   3850                     if (event == null) {
   3851                         return;
   3852                     }
   3853                     mPendingEvents.remove(eventType);
   3854                 }
   3855                 if (mSecurityPolicy.canRetrieveWindowContentLocked(this)) {
   3856                     event.setConnectionId(mId);
   3857                 } else {
   3858                     event.setSource((View) null);
   3859                 }
   3860                 event.setSealed(true);
   3861             }
   3862 
   3863             try {
   3864                 listener.onAccessibilityEvent(event, serviceWantsEvent);
   3865                 if (DEBUG) {
   3866                     Slog.i(LOG_TAG, "Event " + event + " sent to " + listener);
   3867                 }
   3868             } catch (RemoteException re) {
   3869                 Slog.e(LOG_TAG, "Error during sending " + event + " to " + listener, re);
   3870             } finally {
   3871                 event.recycle();
   3872             }
   3873         }
   3874 
   3875         public void notifyGesture(int gestureId) {
   3876             mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_GESTURE,
   3877                     gestureId, 0).sendToTarget();
   3878         }
   3879 
   3880         public void notifyClearAccessibilityNodeInfoCache() {
   3881             mInvocationHandler.sendEmptyMessage(
   3882                     InvocationHandler.MSG_CLEAR_ACCESSIBILITY_CACHE);
   3883         }
   3884 
   3885         public void notifyMagnificationChangedLocked(@NonNull Region region,
   3886                 float scale, float centerX, float centerY) {
   3887             mInvocationHandler
   3888                     .notifyMagnificationChangedLocked(region, scale, centerX, centerY);
   3889         }
   3890 
   3891         public void notifySoftKeyboardShowModeChangedLocked(int showState) {
   3892             mInvocationHandler.notifySoftKeyboardShowModeChangedLocked(showState);
   3893         }
   3894 
   3895         public void notifyAccessibilityButtonClickedLocked() {
   3896             mInvocationHandler.notifyAccessibilityButtonClickedLocked();
   3897         }
   3898 
   3899         public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
   3900             mInvocationHandler.notifyAccessibilityButtonAvailabilityChangedLocked(available);
   3901         }
   3902 
   3903         /**
   3904          * Called by the invocation handler to notify the service that the
   3905          * state of magnification has changed.
   3906          */
   3907         private void notifyMagnificationChangedInternal(@NonNull Region region,
   3908                 float scale, float centerX, float centerY) {
   3909             final IAccessibilityServiceClient listener;
   3910             synchronized (mLock) {
   3911                 listener = mServiceInterface;
   3912             }
   3913             if (listener != null) {
   3914                 try {
   3915                     listener.onMagnificationChanged(region, scale, centerX, centerY);
   3916                 } catch (RemoteException re) {
   3917                     Slog.e(LOG_TAG, "Error sending magnification changes to " + mService, re);
   3918                 }
   3919             }
   3920         }
   3921 
   3922         /**
   3923          * Called by the invocation handler to notify the service that the state of the soft
   3924          * keyboard show mode has changed.
   3925          */
   3926         private void notifySoftKeyboardShowModeChangedInternal(int showState) {
   3927             final IAccessibilityServiceClient listener;
   3928             synchronized (mLock) {
   3929                 listener = mServiceInterface;
   3930             }
   3931             if (listener != null) {
   3932                 try {
   3933                     listener.onSoftKeyboardShowModeChanged(showState);
   3934                 } catch (RemoteException re) {
   3935                     Slog.e(LOG_TAG, "Error sending soft keyboard show mode changes to " + mService,
   3936                             re);
   3937                 }
   3938             }
   3939         }
   3940 
   3941         private void notifyAccessibilityButtonClickedInternal() {
   3942             final IAccessibilityServiceClient listener;
   3943             synchronized (mLock) {
   3944                 listener = mServiceInterface;
   3945             }
   3946             if (listener != null) {
   3947                 try {
   3948                     listener.onAccessibilityButtonClicked();
   3949                 } catch (RemoteException re) {
   3950                     Slog.e(LOG_TAG, "Error sending accessibility button click to " + mService, re);
   3951                 }
   3952             }
   3953         }
   3954 
   3955         private void notifyAccessibilityButtonAvailabilityChangedInternal(boolean available) {
   3956             // Only notify the service if it's not been notified or the state has changed
   3957             if (mReceivedAccessibilityButtonCallbackSinceBind
   3958                     && (mLastAccessibilityButtonCallbackState == available)) {
   3959                 return;
   3960             }
   3961             mReceivedAccessibilityButtonCallbackSinceBind = true;
   3962             mLastAccessibilityButtonCallbackState = available;
   3963             final IAccessibilityServiceClient listener;
   3964             synchronized (mLock) {
   3965                 listener = mServiceInterface;
   3966             }
   3967             if (listener != null) {
   3968                 try {
   3969                     listener.onAccessibilityButtonAvailabilityChanged(available);
   3970                 } catch (RemoteException re) {
   3971                     Slog.e(LOG_TAG,
   3972                             "Error sending accessibility button availability change to " + mService,
   3973                             re);
   3974                 }
   3975             }
   3976         }
   3977 
   3978         private void notifyGestureInternal(int gestureId) {
   3979             final IAccessibilityServiceClient listener;
   3980             synchronized (mLock) {
   3981                 listener = mServiceInterface;
   3982             }
   3983             if (listener != null) {
   3984                 try {
   3985                     listener.onGesture(gestureId);
   3986                 } catch (RemoteException re) {
   3987                     Slog.e(LOG_TAG, "Error during sending gesture " + gestureId
   3988                             + " to " + mService, re);
   3989                 }
   3990             }
   3991         }
   3992 
   3993         private void notifyClearAccessibilityCacheInternal() {
   3994             final IAccessibilityServiceClient listener;
   3995             synchronized (mLock) {
   3996                 listener = mServiceInterface;
   3997             }
   3998             if (listener != null) {
   3999                 try {
   4000                     listener.clearAccessibilityCache();
   4001                 } catch (RemoteException re) {
   4002                     Slog.e(LOG_TAG, "Error during requesting accessibility info cache"
   4003                             + " to be cleared.", re);
   4004                 }
   4005             }
   4006         }
   4007 
   4008         private void sendDownAndUpKeyEvents(int keyCode) {
   4009             final long token = Binder.clearCallingIdentity();
   4010 
   4011             // Inject down.
   4012             final long downTime = SystemClock.uptimeMillis();
   4013             KeyEvent down = KeyEvent.obtain(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
   4014                     KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
   4015                     InputDevice.SOURCE_KEYBOARD, null);
   4016             InputManager.getInstance().injectInputEvent(down,
   4017                     InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
   4018             down.recycle();
   4019 
   4020             // Inject up.
   4021             final long upTime = SystemClock.uptimeMillis();
   4022             KeyEvent up = KeyEvent.obtain(downTime, upTime, KeyEvent.ACTION_UP, keyCode, 0, 0,
   4023                     KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
   4024                     InputDevice.SOURCE_KEYBOARD, null);
   4025             InputManager.getInstance().injectInputEvent(up,
   4026                     InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
   4027             up.recycle();
   4028 
   4029             Binder.restoreCallingIdentity(token);
   4030         }
   4031 
   4032         private void expandNotifications() {
   4033             final long token = Binder.clearCallingIdentity();
   4034 
   4035             StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService(
   4036                     android.app.Service.STATUS_BAR_SERVICE);
   4037             statusBarManager.expandNotificationsPanel();
   4038 
   4039             Binder.restoreCallingIdentity(token);
   4040         }
   4041 
   4042         private void expandQuickSettings() {
   4043             final long token = Binder.clearCallingIdentity();
   4044 
   4045             StatusBarManager statusBarManager = (StatusBarManager) mContext.getSystemService(
   4046                     android.app.Service.STATUS_BAR_SERVICE);
   4047             statusBarManager.expandSettingsPanel();
   4048 
   4049             Binder.restoreCallingIdentity(token);
   4050         }
   4051 
   4052         private boolean openRecents() {
   4053             final long token = Binder.clearCallingIdentity();
   4054             try {
   4055                 StatusBarManagerInternal statusBarService = LocalServices.getService(
   4056                         StatusBarManagerInternal.class);
   4057                 if (statusBarService == null) {
   4058                     return false;
   4059                 }
   4060                 statusBarService.toggleRecentApps();
   4061             } finally {
   4062                 Binder.restoreCallingIdentity(token);
   4063             }
   4064             return true;
   4065         }
   4066 
   4067         private void showGlobalActions() {
   4068             mWindowManagerService.showGlobalActions();
   4069         }
   4070 
   4071         private void toggleSplitScreen() {
   4072             LocalServices.getService(StatusBarManagerInternal.class).toggleSplitScreen();
   4073         }
   4074 
   4075         private IAccessibilityInteractionConnection getConnectionLocked(int windowId) {
   4076             if (DEBUG) {
   4077                 Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId);
   4078             }
   4079             AccessibilityConnectionWrapper wrapper = mGlobalInteractionConnections.get(windowId);
   4080             if (wrapper == null) {
   4081                 wrapper = getCurrentUserStateLocked().mInteractionConnections.get(windowId);
   4082             }
   4083             if (wrapper != null && wrapper.mConnection != null) {
   4084                 return wrapper.mConnection;
   4085             }
   4086             if (DEBUG) {
   4087                 Slog.e(LOG_TAG, "No interaction connection to window: " + windowId);
   4088             }
   4089             return null;
   4090         }
   4091 
   4092         private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) {
   4093             if (accessibilityWindowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) {
   4094                 return mSecurityPolicy.getActiveWindowId();
   4095             }
   4096             return accessibilityWindowId;
   4097         }
   4098 
   4099         private int resolveAccessibilityWindowIdForFindFocusLocked(int windowId, int focusType) {
   4100             if (windowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) {
   4101                 return mSecurityPolicy.mActiveWindowId;
   4102             }
   4103             if (windowId == AccessibilityWindowInfo.ANY_WINDOW_ID) {
   4104                 if (focusType == AccessibilityNodeInfo.FOCUS_INPUT) {
   4105                     return mSecurityPolicy.mFocusedWindowId;
   4106                 } else if (focusType == AccessibilityNodeInfo.FOCUS_ACCESSIBILITY) {
   4107                     return mSecurityPolicy.mAccessibilityFocusedWindowId;
   4108                 }
   4109             }
   4110             return windowId;
   4111         }
   4112 
   4113         private IAccessibilityInteractionConnectionCallback replaceCallbackIfNeeded(
   4114                 IAccessibilityInteractionConnectionCallback originalCallback,
   4115                 int resolvedWindowId, int interactionId, int interrogatingPid,
   4116                 long interrogatingTid) {
   4117             AccessibilityWindowInfo windowInfo =
   4118                     mSecurityPolicy.findA11yWindowInfoById(resolvedWindowId);
   4119             if ((windowInfo == null) || !windowInfo.inPictureInPicture()
   4120                     || (mPictureInPictureActionReplacingConnection == null)) {
   4121                 return originalCallback;
   4122             }
   4123             return new ActionReplacingCallback(originalCallback,
   4124                     mPictureInPictureActionReplacingConnection.mConnection, interactionId,
   4125                     interrogatingPid, interrogatingTid);
   4126         }
   4127 
   4128         private final class InvocationHandler extends Handler {
   4129             public static final int MSG_ON_GESTURE = 1;
   4130             public static final int MSG_CLEAR_ACCESSIBILITY_CACHE = 2;
   4131 
   4132             private static final int MSG_ON_MAGNIFICATION_CHANGED = 5;
   4133             private static final int MSG_ON_SOFT_KEYBOARD_STATE_CHANGED = 6;
   4134             private static final int MSG_ON_ACCESSIBILITY_BUTTON_CLICKED = 7;
   4135             private static final int MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 8;
   4136 
   4137             private boolean mIsMagnificationCallbackEnabled = false;
   4138             private boolean mIsSoftKeyboardCallbackEnabled = false;
   4139 
   4140             public InvocationHandler(Looper looper) {
   4141                 super(looper, null, true);
   4142             }
   4143 
   4144             @Override
   4145             public void handleMessage(Message message) {
   4146                 final int type = message.what;
   4147                 switch (type) {
   4148                     case MSG_ON_GESTURE: {
   4149                         final int gestureId = message.arg1;
   4150                         notifyGestureInternal(gestureId);
   4151                     } break;
   4152 
   4153                     case MSG_CLEAR_ACCESSIBILITY_CACHE: {
   4154                         notifyClearAccessibilityCacheInternal();
   4155                     } break;
   4156 
   4157                     case MSG_ON_MAGNIFICATION_CHANGED: {
   4158                         final SomeArgs args = (SomeArgs) message.obj;
   4159                         final Region region = (Region) args.arg1;
   4160                         final float scale = (float) args.arg2;
   4161                         final float centerX = (float) args.arg3;
   4162                         final float centerY = (float) args.arg4;
   4163                         notifyMagnificationChangedInternal(region, scale, centerX, centerY);
   4164                     } break;
   4165 
   4166                     case MSG_ON_SOFT_KEYBOARD_STATE_CHANGED: {
   4167                         final int showState = (int) message.arg1;
   4168                         notifySoftKeyboardShowModeChangedInternal(showState);
   4169                     } break;
   4170 
   4171                     case MSG_ON_ACCESSIBILITY_BUTTON_CLICKED: {
   4172                         notifyAccessibilityButtonClickedInternal();
   4173                     } break;
   4174 
   4175                     case MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED: {
   4176                         final boolean available = (message.arg1 != 0);
   4177                         notifyAccessibilityButtonAvailabilityChangedInternal(available);
   4178                     } break;
   4179 
   4180                     default: {
   4181                         throw new IllegalArgumentException("Unknown message: " + type);
   4182                     }
   4183                 }
   4184             }
   4185 
   4186             public void notifyMagnificationChangedLocked(@NonNull Region region, float scale,
   4187                     float centerX, float centerY) {
   4188                 if (!mIsMagnificationCallbackEnabled) {
   4189                     // Callback is disabled, don't bother packing args.
   4190                     return;
   4191                 }
   4192 
   4193                 final SomeArgs args = SomeArgs.obtain();
   4194                 args.arg1 = region;
   4195                 args.arg2 = scale;
   4196                 args.arg3 = centerX;
   4197                 args.arg4 = centerY;
   4198 
   4199                 final Message msg = obtainMessage(MSG_ON_MAGNIFICATION_CHANGED, args);
   4200                 msg.sendToTarget();
   4201             }
   4202 
   4203             public void setMagnificationCallbackEnabled(boolean enabled) {
   4204                 mIsMagnificationCallbackEnabled = enabled;
   4205             }
   4206 
   4207             public void notifySoftKeyboardShowModeChangedLocked(int showState) {
   4208                 if (!mIsSoftKeyboardCallbackEnabled) {
   4209                     return;
   4210                 }
   4211 
   4212                 final Message msg = obtainMessage(MSG_ON_SOFT_KEYBOARD_STATE_CHANGED, showState, 0);
   4213                 msg.sendToTarget();
   4214             }
   4215 
   4216             public void setSoftKeyboardCallbackEnabled(boolean enabled) {
   4217                 mIsSoftKeyboardCallbackEnabled = enabled;
   4218             }
   4219 
   4220             public void notifyAccessibilityButtonClickedLocked() {
   4221                 final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_CLICKED);
   4222                 msg.sendToTarget();
   4223             }
   4224 
   4225             public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
   4226                 final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED,
   4227                         (available ? 1 : 0), 0);
   4228                 msg.sendToTarget();
   4229             }
   4230         }
   4231     }
   4232 
   4233     final class WindowsForAccessibilityCallback implements
   4234             WindowManagerInternal.WindowsForAccessibilityCallback {
   4235 
   4236         @Override
   4237         public void onWindowsForAccessibilityChanged(List<WindowInfo> windows) {
   4238             synchronized (mLock) {
   4239                 if (DEBUG) {
   4240                     Slog.i(LOG_TAG, "Windows changed: " + windows);
   4241                 }
   4242 
   4243                 // Let the policy update the focused and active windows.
   4244                 mSecurityPolicy.updateWindowsLocked(windows);
   4245 
   4246                 // Someone may be waiting for the windows - advertise it.
   4247                 mLock.notifyAll();
   4248             }
   4249         }
   4250 
   4251         private AccessibilityWindowInfo populateReportedWindow(WindowInfo window) {
   4252             final int windowId = findWindowIdLocked(window.token);
   4253             if (windowId < 0) {
   4254                 return null;
   4255             }
   4256 
   4257             AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
   4258 
   4259             reportedWindow.setId(windowId);
   4260             reportedWindow.setType(getTypeForWindowManagerWindowType(window.type));
   4261             reportedWindow.setLayer(window.layer);
   4262             reportedWindow.setFocused(window.focused);
   4263             reportedWindow.setBoundsInScreen(window.boundsInScreen);
   4264             reportedWindow.setTitle(window.title);
   4265             reportedWindow.setAnchorId(window.accessibilityIdOfAnchor);
   4266             reportedWindow.setPictureInPicture(window.inPictureInPicture);
   4267 
   4268             final int parentId = findWindowIdLocked(window.parentToken);
   4269             if (parentId >= 0) {
   4270                 reportedWindow.setParentId(parentId);
   4271             }
   4272 
   4273             if (window.childTokens != null) {
   4274                 final int childCount = window.childTokens.size();
   4275                 for (int i = 0; i < childCount; i++) {
   4276                     IBinder childToken = window.childTokens.get(i);
   4277                     final int childId = findWindowIdLocked(childToken);
   4278                     if (childId >= 0) {
   4279                         reportedWindow.addChild(childId);
   4280                     }
   4281                 }
   4282             }
   4283 
   4284             return reportedWindow;
   4285         }
   4286 
   4287         private int getTypeForWindowManagerWindowType(int windowType) {
   4288             switch (windowType) {
   4289                 case WindowManager.LayoutParams.TYPE_APPLICATION:
   4290                 case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
   4291                 case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
   4292                 case WindowManager.LayoutParams.TYPE_APPLICATION_STARTING:
   4293                 case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
   4294                 case WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL:
   4295                 case WindowManager.LayoutParams.TYPE_BASE_APPLICATION:
   4296                 case WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION:
   4297                 case WindowManager.LayoutParams.TYPE_PHONE:
   4298                 case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
   4299                 case WindowManager.LayoutParams.TYPE_TOAST:
   4300                 case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG: {
   4301                     return AccessibilityWindowInfo.TYPE_APPLICATION;
   4302                 }
   4303 
   4304                 case WindowManager.LayoutParams.TYPE_INPUT_METHOD:
   4305                 case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: {
   4306                     return AccessibilityWindowInfo.TYPE_INPUT_METHOD;
   4307                 }
   4308 
   4309                 case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
   4310                 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR:
   4311                 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
   4312                 case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
   4313                 case WindowManager.LayoutParams.TYPE_STATUS_BAR:
   4314                 case WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL:
   4315                 case WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL:
   4316                 case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
   4317                 case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
   4318                 case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
   4319                 case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
   4320                 case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
   4321                 case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
   4322                 case WindowManager.LayoutParams.TYPE_SCREENSHOT: {
   4323                     return AccessibilityWindowInfo.TYPE_SYSTEM;
   4324                 }
   4325 
   4326                 case WindowManager.LayoutParams.TYPE_DOCK_DIVIDER: {
   4327                     return AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER;
   4328                 }
   4329 
   4330                 case TYPE_ACCESSIBILITY_OVERLAY: {
   4331                     return AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY;
   4332                 }
   4333 
   4334                 default: {
   4335                     return -1;
   4336                 }
   4337             }
   4338         }
   4339     }
   4340 
   4341     private final class InteractionBridge {
   4342         private final Display mDefaultDisplay;
   4343         private final int mConnectionId;
   4344         private final AccessibilityInteractionClient mClient;
   4345 
   4346         public InteractionBridge() {
   4347             AccessibilityServiceInfo info = new AccessibilityServiceInfo();
   4348             info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
   4349             info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
   4350             info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
   4351             Service service = new Service(UserHandle.USER_NULL,
   4352                     sFakeAccessibilityServiceComponentName, info);
   4353 
   4354             mConnectionId = service.mId;
   4355 
   4356             mClient = AccessibilityInteractionClient.getInstance();
   4357             mClient.addConnection(mConnectionId, service);
   4358 
   4359             //TODO: (multi-display) We need to support multiple displays.
   4360             DisplayManager displayManager = (DisplayManager)
   4361                     mContext.getSystemService(Context.DISPLAY_SERVICE);
   4362             mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
   4363         }
   4364 
   4365         public void clearAccessibilityFocusNotLocked(int windowId) {
   4366             AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked(windowId);
   4367             if (focus != null) {
   4368                 focus.performAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
   4369             }
   4370         }
   4371 
   4372         /**
   4373          * Perform an accessibility action on the view that currently has accessibility focus.
   4374          * Has no effect if no item has accessibility focus, if the item with accessibility
   4375          * focus does not expose the specified action, or if the action fails.
   4376          *
   4377          * @param actionId The id of the action to perform.
   4378          *
   4379          * @return {@code true} if the action was performed. {@code false} if it was not.
   4380          */
   4381         public boolean performActionOnAccessibilityFocusedItemNotLocked(
   4382                 AccessibilityNodeInfo.AccessibilityAction action) {
   4383             AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked();
   4384             if ((focus == null) || !focus.getActionList().contains(action)) {
   4385                 return false;
   4386             }
   4387             return focus.performAction(action.getId());
   4388         }
   4389 
   4390         public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) {
   4391             AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked();
   4392             if (focus == null) {
   4393                 return false;
   4394             }
   4395 
   4396             synchronized (mLock) {
   4397                 Rect boundsInScreen = mTempRect;
   4398                 focus.getBoundsInScreen(boundsInScreen);
   4399 
   4400                 // Apply magnification if needed.
   4401                 MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId());
   4402                 if (spec != null && !spec.isNop()) {
   4403                     boundsInScreen.offset((int) -spec.offsetX, (int) -spec.offsetY);
   4404                     boundsInScreen.scale(1 / spec.scale);
   4405                 }
   4406 
   4407                 // Clip to the window bounds.
   4408                 Rect windowBounds = mTempRect1;
   4409                 getWindowBounds(focus.getWindowId(), windowBounds);
   4410                 if (!boundsInScreen.intersect(windowBounds)) {
   4411                     return false;
   4412                 }
   4413 
   4414                 // Clip to the screen bounds.
   4415                 Point screenSize = mTempPoint;
   4416                 mDefaultDisplay.getRealSize(screenSize);
   4417                 if (!boundsInScreen.intersect(0, 0, screenSize.x, screenSize.y)) {
   4418                     return false;
   4419                 }
   4420 
   4421                 outPoint.set(boundsInScreen.centerX(), boundsInScreen.centerY());
   4422             }
   4423 
   4424             return true;
   4425         }
   4426 
   4427         private AccessibilityNodeInfo getAccessibilityFocusNotLocked() {
   4428             final int focusedWindowId;
   4429             synchronized (mLock) {
   4430                 focusedWindowId = mSecurityPolicy.mAccessibilityFocusedWindowId;
   4431                 if (focusedWindowId == SecurityPolicy.INVALID_WINDOW_ID) {
   4432                     return null;
   4433                 }
   4434             }
   4435             return getAccessibilityFocusNotLocked(focusedWindowId);
   4436         }
   4437 
   4438         private AccessibilityNodeInfo getAccessibilityFocusNotLocked(int windowId) {
   4439             return mClient.findFocus(mConnectionId,
   4440                     windowId, AccessibilityNodeInfo.ROOT_NODE_ID,
   4441                     AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
   4442         }
   4443     }
   4444 
   4445     final class SecurityPolicy {
   4446         public static final int INVALID_WINDOW_ID = -1;
   4447 
   4448         private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
   4449             AccessibilityEvent.TYPE_VIEW_CLICKED
   4450             | AccessibilityEvent.TYPE_VIEW_FOCUSED
   4451             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
   4452             | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
   4453             | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
   4454             | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
   4455             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
   4456             | AccessibilityEvent.TYPE_VIEW_SELECTED
   4457             | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
   4458             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
   4459             | AccessibilityEvent.TYPE_VIEW_SCROLLED
   4460             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
   4461             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
   4462             | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
   4463 
   4464         // In Z order
   4465         public List<AccessibilityWindowInfo> mWindows;
   4466         public SparseArray<AccessibilityWindowInfo> mA11yWindowInfoById = new SparseArray<>();
   4467         public SparseArray<WindowInfo> mWindowInfoById = new SparseArray<>();
   4468 
   4469         public int mActiveWindowId = INVALID_WINDOW_ID;
   4470         public int mFocusedWindowId = INVALID_WINDOW_ID;
   4471         public int mAccessibilityFocusedWindowId = INVALID_WINDOW_ID;
   4472         public long mAccessibilityFocusNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
   4473 
   4474         private boolean mTouchInteractionInProgress;
   4475 
   4476         private boolean canDispatchAccessibilityEventLocked(AccessibilityEvent event) {
   4477             final int eventType = event.getEventType();
   4478             switch (eventType) {
   4479                 // All events that are for changes in a global window
   4480                 // state should *always* be dispatched.
   4481                 case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
   4482                 case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
   4483                 case AccessibilityEvent.TYPE_ANNOUNCEMENT:
   4484                 // All events generated by the user touching the
   4485                 // screen should *always* be dispatched.
   4486                 case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
   4487                 case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
   4488                 case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
   4489                 case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
   4490                 case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START:
   4491                 case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
   4492                 case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
   4493                 case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
   4494                 // Also always dispatch the event that assist is reading context.
   4495                 case AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT:
   4496                 // Also windows changing should always be anounced.
   4497                 case AccessibilityEvent.TYPE_WINDOWS_CHANGED: {
   4498                     return true;
   4499                 }
   4500                 // All events for changes in window content should be
   4501                 // dispatched *only* if this window is one of the windows
   4502                 // the accessibility layer reports which are windows
   4503                 // that a sighted user can touch.
   4504                 default: {
   4505                     return isRetrievalAllowingWindow(event.getWindowId());
   4506                 }
   4507             }
   4508         }
   4509 
   4510         public void clearWindowsLocked() {
   4511             List<WindowInfo> windows = Collections.emptyList();
   4512             final int activeWindowId = mActiveWindowId;
   4513             updateWindowsLocked(windows);
   4514             mActiveWindowId = activeWindowId;
   4515             mWindows = null;
   4516         }
   4517 
   4518         public void updateWindowsLocked(List<WindowInfo> windows) {
   4519             if (mWindows == null) {
   4520                 mWindows = new ArrayList<>();
   4521             }
   4522 
   4523             final int oldWindowCount = mWindows.size();
   4524             for (int i = oldWindowCount - 1; i >= 0; i--) {
   4525                 mWindows.remove(i).recycle();
   4526             }
   4527             mA11yWindowInfoById.clear();
   4528 
   4529             for (int i = 0; i < mWindowInfoById.size(); i++) {
   4530                 mWindowInfoById.valueAt(i).recycle();
   4531             }
   4532             mWindowInfoById.clear();
   4533 
   4534             mFocusedWindowId = INVALID_WINDOW_ID;
   4535             if (!mTouchInteractionInProgress) {
   4536                 mActiveWindowId = INVALID_WINDOW_ID;
   4537             }
   4538 
   4539             // If the active window goes away while the user is touch exploring we
   4540             // reset the active window id and wait for the next hover event from
   4541             // under the user's finger to determine which one is the new one. It
   4542             // is possible that the finger is not moving and the input system
   4543             // filters out such events.
   4544             boolean activeWindowGone = true;
   4545 
   4546             final int windowCount = windows.size();
   4547             if (windowCount > 0) {
   4548                 for (int i = 0; i < windowCount; i++) {
   4549                     WindowInfo windowInfo = windows.get(i);
   4550                     AccessibilityWindowInfo window = (mWindowsForAccessibilityCallback != null)
   4551                             ? mWindowsForAccessibilityCallback.populateReportedWindow(windowInfo)
   4552                             : null;
   4553                     if (window != null) {
   4554                         final int windowId = window.getId();
   4555                         if (window.isFocused()) {
   4556                             mFocusedWindowId = windowId;
   4557                             if (!mTouchInteractionInProgress) {
   4558                                 mActiveWindowId = windowId;
   4559                                 window.setActive(true);
   4560                             } else if (windowId == mActiveWindowId) {
   4561                                 activeWindowGone = false;
   4562                             }
   4563                         }
   4564                         mWindows.add(window);
   4565                         mA11yWindowInfoById.put(windowId, window);
   4566                         mWindowInfoById.put(windowId, WindowInfo.obtain(windowInfo));
   4567                     }
   4568                 }
   4569 
   4570                 if (mTouchInteractionInProgress && activeWindowGone) {
   4571                     mActiveWindowId = mFocusedWindowId;
   4572                 }
   4573 
   4574                 // Focused window may change the active one, so set the
   4575                 // active window once we decided which it is.
   4576                 final int accessibilityWindowCount = mWindows.size();
   4577                 for (int i = 0; i < accessibilityWindowCount; i++) {
   4578                     AccessibilityWindowInfo window = mWindows.get(i);
   4579                     if (window.getId() == mActiveWindowId) {
   4580                         window.setActive(true);
   4581                     }
   4582                     if (window.getId() == mAccessibilityFocusedWindowId) {
   4583                         window.setAccessibilityFocused(true);
   4584                     }
   4585                 }
   4586             }
   4587 
   4588             notifyWindowsChanged();
   4589         }
   4590 
   4591         public boolean computePartialInteractiveRegionForWindowLocked(int windowId,
   4592                 Region outRegion) {
   4593             if (mWindows == null) {
   4594                 return false;
   4595             }
   4596 
   4597             // Windows are ordered in z order so start from the bottom and find
   4598             // the window of interest. After that all windows that cover it should
   4599             // be subtracted from the resulting region. Note that for accessibility
   4600             // we are returning only interactive windows.
   4601             Region windowInteractiveRegion = null;
   4602             boolean windowInteractiveRegionChanged = false;
   4603 
   4604             final int windowCount = mWindows.size();
   4605             for (int i = windowCount - 1; i >= 0; i--) {
   4606                 AccessibilityWindowInfo currentWindow = mWindows.get(i);
   4607                 if (windowInteractiveRegion == null) {
   4608                     if (currentWindow.getId() == windowId) {
   4609                         Rect currentWindowBounds = mTempRect;
   4610                         currentWindow.getBoundsInScreen(currentWindowBounds);
   4611                         outRegion.set(currentWindowBounds);
   4612                         windowInteractiveRegion = outRegion;
   4613                         continue;
   4614                     }
   4615                 } else if (currentWindow.getType()
   4616                         != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
   4617                     Rect currentWindowBounds = mTempRect;
   4618                     currentWindow.getBoundsInScreen(currentWindowBounds);
   4619                     if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
   4620                         windowInteractiveRegionChanged = true;
   4621                     }
   4622                 }
   4623             }
   4624 
   4625             return windowInteractiveRegionChanged;
   4626         }
   4627 
   4628         public void updateEventSourceLocked(AccessibilityEvent event) {
   4629             if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) {
   4630                 event.setSource((View) null);
   4631             }
   4632         }
   4633 
   4634         public void updateActiveAndAccessibilityFocusedWindowLocked(int windowId, long nodeId,
   4635                 int eventType, int eventAction) {
   4636             // The active window is either the window that has input focus or
   4637             // the window that the user is currently touching. If the user is
   4638             // touching a window that does not have input focus as soon as the
   4639             // the user stops touching that window the focused window becomes
   4640             // the active one. Here we detect the touched window and make it
   4641             // active. In updateWindowsLocked() we update the focused window
   4642             // and if the user is not touching the screen, we make the focused
   4643             // window the active one.
   4644             switch (eventType) {
   4645                 case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
   4646                     // If no service has the capability to introspect screen,
   4647                     // we do not register callback in the window manager for
   4648                     // window changes, so we have to ask the window manager
   4649                     // what the focused window is to update the active one.
   4650                     // The active window also determined events from which
   4651                     // windows are delivered.
   4652                     synchronized (mLock) {
   4653                         if (mWindowsForAccessibilityCallback == null) {
   4654                             mFocusedWindowId = getFocusedWindowId();
   4655                             if (windowId == mFocusedWindowId) {
   4656                                 mActiveWindowId = windowId;
   4657                             }
   4658                         }
   4659                     }
   4660                 } break;
   4661 
   4662                 case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: {
   4663                     // Do not allow delayed hover events to confuse us
   4664                     // which the active window is.
   4665                     synchronized (mLock) {
   4666                         if (mTouchInteractionInProgress && mActiveWindowId != windowId) {
   4667                             setActiveWindowLocked(windowId);
   4668                         }
   4669                     }
   4670                 } break;
   4671 
   4672                 case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
   4673                     synchronized (mLock) {
   4674                         if (mAccessibilityFocusedWindowId != windowId) {
   4675                             mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
   4676                                     mAccessibilityFocusedWindowId, 0).sendToTarget();
   4677                             mSecurityPolicy.setAccessibilityFocusedWindowLocked(windowId);
   4678                             mAccessibilityFocusNodeId = nodeId;
   4679                         }
   4680                     }
   4681                 } break;
   4682 
   4683                 case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
   4684                     synchronized (mLock) {
   4685                         if (mAccessibilityFocusNodeId == nodeId) {
   4686                             mAccessibilityFocusNodeId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
   4687                         }
   4688                         // Clear the window with focus if it no longer has focus and we aren't
   4689                         // just moving focus from one view to the other in the same window
   4690                         if ((mAccessibilityFocusNodeId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
   4691                                 && (mAccessibilityFocusedWindowId == windowId)
   4692                                 && (eventAction != AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS)
   4693                                 ) {
   4694                             mAccessibilityFocusedWindowId = INVALID_WINDOW_ID;
   4695                         }
   4696                     }
   4697                 } break;
   4698             }
   4699         }
   4700 
   4701         public void onTouchInteractionStart() {
   4702             synchronized (mLock) {
   4703                 mTouchInteractionInProgress = true;
   4704             }
   4705         }
   4706 
   4707         public void onTouchInteractionEnd() {
   4708             synchronized (mLock) {
   4709                 mTouchInteractionInProgress = false;
   4710                 // We want to set the active window to be current immediately
   4711                 // after the user has stopped touching the screen since if the
   4712                 // user types with the IME he should get a feedback for the
   4713                 // letter typed in the text view which is in the input focused
   4714                 // window. Note that we always deliver hover accessibility events
   4715                 // (they are a result of user touching the screen) so change of
   4716                 // the active window before all hover accessibility events from
   4717                 // the touched window are delivered is fine.
   4718                 final int oldActiveWindow = mSecurityPolicy.mActiveWindowId;
   4719                 setActiveWindowLocked(mFocusedWindowId);
   4720 
   4721                 // If there is no service that can operate with active windows
   4722                 // we keep accessibility focus behavior to constrain it only in
   4723                 // the active window. Look at updateAccessibilityFocusBehaviorLocked
   4724                 // for details.
   4725                 if (oldActiveWindow != mSecurityPolicy.mActiveWindowId
   4726                         && mAccessibilityFocusedWindowId == oldActiveWindow
   4727                         && getCurrentUserStateLocked().mAccessibilityFocusOnlyInActiveWindow) {
   4728                     mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
   4729                             oldActiveWindow, 0).sendToTarget();
   4730                 }
   4731             }
   4732         }
   4733 
   4734         public int getActiveWindowId() {
   4735             if (mActiveWindowId == INVALID_WINDOW_ID && !mTouchInteractionInProgress) {
   4736                 mActiveWindowId = getFocusedWindowId();
   4737             }
   4738             return mActiveWindowId;
   4739         }
   4740 
   4741         private void setActiveWindowLocked(int windowId) {
   4742             if (mActiveWindowId != windowId) {
   4743                 mActiveWindowId = windowId;
   4744                 if (mWindows != null) {
   4745                     final int windowCount = mWindows.size();
   4746                     for (int i = 0; i < windowCount; i++) {
   4747                         AccessibilityWindowInfo window = mWindows.get(i);
   4748                         window.setActive(window.getId() == windowId);
   4749                     }
   4750                 }
   4751                 notifyWindowsChanged();
   4752             }
   4753         }
   4754 
   4755         private void setAccessibilityFocusedWindowLocked(int windowId) {
   4756             if (mAccessibilityFocusedWindowId != windowId) {
   4757                 mAccessibilityFocusedWindowId = windowId;
   4758                 if (mWindows != null) {
   4759                     final int windowCount = mWindows.size();
   4760                     for (int i = 0; i < windowCount; i++) {
   4761                         AccessibilityWindowInfo window = mWindows.get(i);
   4762                         window.setAccessibilityFocused(window.getId() == windowId);
   4763                     }
   4764                 }
   4765 
   4766                 notifyWindowsChanged();
   4767             }
   4768         }
   4769 
   4770         public void notifyWindowsChanged() {
   4771             if (mWindowsForAccessibilityCallback == null) {
   4772                 return;
   4773             }
   4774             final long identity = Binder.clearCallingIdentity();
   4775             try {
   4776                 // Let the client know the windows changed.
   4777                 AccessibilityEvent event = AccessibilityEvent.obtain(
   4778                         AccessibilityEvent.TYPE_WINDOWS_CHANGED);
   4779                 event.setEventTime(SystemClock.uptimeMillis());
   4780                 sendAccessibilityEvent(event, mCurrentUserId);
   4781             } finally {
   4782                 Binder.restoreCallingIdentity(identity);
   4783             }
   4784         }
   4785 
   4786         public boolean canGetAccessibilityNodeInfoLocked(Service service, int windowId) {
   4787             return canRetrieveWindowContentLocked(service) && isRetrievalAllowingWindow(windowId);
   4788         }
   4789 
   4790         public boolean canRetrieveWindowsLocked(Service service) {
   4791             return canRetrieveWindowContentLocked(service) && service.mRetrieveInteractiveWindows;
   4792         }
   4793 
   4794         public boolean canRetrieveWindowContentLocked(Service service) {
   4795             return (service.mAccessibilityServiceInfo.getCapabilities()
   4796                     & AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
   4797         }
   4798 
   4799         public boolean canControlMagnification(Service service) {
   4800             return (service.mAccessibilityServiceInfo.getCapabilities()
   4801                     & AccessibilityServiceInfo.CAPABILITY_CAN_CONTROL_MAGNIFICATION) != 0;
   4802         }
   4803 
   4804         public boolean canPerformGestures(Service service) {
   4805             return (service.mAccessibilityServiceInfo.getCapabilities()
   4806                     & AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES) != 0;
   4807         }
   4808 
   4809         public boolean canCaptureFingerprintGestures(Service service) {
   4810             return (service.mAccessibilityServiceInfo.getCapabilities()
   4811                     & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES) != 0;
   4812         }
   4813 
   4814         private int resolveProfileParentLocked(int userId) {
   4815             if (userId != mCurrentUserId) {
   4816                 final long identity = Binder.clearCallingIdentity();
   4817                 try {
   4818                     UserInfo parent = mUserManager.getProfileParent(userId);
   4819                     if (parent != null) {
   4820                         return parent.getUserHandle().getIdentifier();
   4821                     }
   4822                 } finally {
   4823                     Binder.restoreCallingIdentity(identity);
   4824                 }
   4825             }
   4826             return userId;
   4827         }
   4828 
   4829         public int resolveCallingUserIdEnforcingPermissionsLocked(int userId) {
   4830             final int callingUid = Binder.getCallingUid();
   4831             if (callingUid == 0
   4832                     || callingUid == Process.SYSTEM_UID
   4833                     || callingUid == Process.SHELL_UID) {
   4834                 if (userId == UserHandle.USER_CURRENT
   4835                         || userId == UserHandle.USER_CURRENT_OR_SELF) {
   4836                     return mCurrentUserId;
   4837                 }
   4838                 return resolveProfileParentLocked(userId);
   4839             }
   4840             final int callingUserId = UserHandle.getUserId(callingUid);
   4841             if (callingUserId == userId) {
   4842                 return resolveProfileParentLocked(userId);
   4843             }
   4844             final int callingUserParentId = resolveProfileParentLocked(callingUserId);
   4845             if (callingUserParentId == mCurrentUserId &&
   4846                     (userId == UserHandle.USER_CURRENT
   4847                             || userId == UserHandle.USER_CURRENT_OR_SELF)) {
   4848                 return mCurrentUserId;
   4849             }
   4850             if (!hasPermission(Manifest.permission.INTERACT_ACROSS_USERS)
   4851                     && !hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)) {
   4852                 throw new SecurityException("Call from user " + callingUserId + " as user "
   4853                         + userId + " without permission INTERACT_ACROSS_USERS or "
   4854                         + "INTERACT_ACROSS_USERS_FULL not allowed.");
   4855             }
   4856             if (userId == UserHandle.USER_CURRENT
   4857                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
   4858                 return mCurrentUserId;
   4859             }
   4860             throw new IllegalArgumentException("Calling user can be changed to only "
   4861                     + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
   4862         }
   4863 
   4864         public boolean isCallerInteractingAcrossUsers(int userId) {
   4865             final int callingUid = Binder.getCallingUid();
   4866             return (Binder.getCallingPid() == android.os.Process.myPid()
   4867                     || callingUid == Process.SHELL_UID
   4868                     || userId == UserHandle.USER_CURRENT
   4869                     || userId == UserHandle.USER_CURRENT_OR_SELF);
   4870         }
   4871 
   4872         private boolean isRetrievalAllowingWindow(int windowId) {
   4873             // The system gets to interact with any window it wants.
   4874             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
   4875                 return true;
   4876             }
   4877             if (windowId == mActiveWindowId) {
   4878                 return true;
   4879             }
   4880             return findA11yWindowInfoById(windowId) != null;
   4881         }
   4882 
   4883         private AccessibilityWindowInfo findA11yWindowInfoById(int windowId) {
   4884             return mA11yWindowInfoById.get(windowId);
   4885         }
   4886 
   4887         private WindowInfo findWindowInfoById(int windowId) {
   4888             return mWindowInfoById.get(windowId);
   4889         }
   4890 
   4891         private AccessibilityWindowInfo getPictureInPictureWindow() {
   4892             if (mWindows != null) {
   4893                 final int windowCount = mWindows.size();
   4894                 for (int i = 0; i < windowCount; i++) {
   4895                     AccessibilityWindowInfo window = mWindows.get(i);
   4896                     if (window.inPictureInPicture()) {
   4897                         return window;
   4898                     }
   4899                 }
   4900             }
   4901             return null;
   4902         }
   4903 
   4904         private void enforceCallingPermission(String permission, String function) {
   4905             if (OWN_PROCESS_ID == Binder.getCallingPid()) {
   4906                 return;
   4907             }
   4908             if (!hasPermission(permission)) {
   4909                 throw new SecurityException("You do not have " + permission
   4910                         + " required to call " + function + " from pid="
   4911                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
   4912             }
   4913         }
   4914 
   4915         private boolean hasPermission(String permission) {
   4916             return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
   4917         }
   4918 
   4919         private int getFocusedWindowId() {
   4920             IBinder token = mWindowManagerService.getFocusedWindowToken();
   4921             synchronized (mLock) {
   4922                 return findWindowIdLocked(token);
   4923             }
   4924         }
   4925     }
   4926 
   4927     private class UserState {
   4928         public final int mUserId;
   4929 
   4930         // Non-transient state.
   4931 
   4932         public final RemoteCallbackList<IAccessibilityManagerClient> mUserClients =
   4933             new RemoteCallbackList<>();
   4934 
   4935         public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections =
   4936                 new SparseArray<>();
   4937 
   4938         public final SparseArray<IBinder> mWindowTokens = new SparseArray<>();
   4939 
   4940         // Transient state.
   4941 
   4942         public final CopyOnWriteArrayList<Service> mBoundServices =
   4943                 new CopyOnWriteArrayList<>();
   4944 
   4945         public int mLastSentRelevantEventTypes = AccessibilityEvent.TYPES_ALL_MASK;
   4946 
   4947         public final Map<ComponentName, Service> mComponentNameToServiceMap =
   4948                 new HashMap<>();
   4949 
   4950         public final List<AccessibilityServiceInfo> mInstalledServices =
   4951                 new ArrayList<>();
   4952 
   4953         public final Set<ComponentName> mBindingServices = new HashSet<>();
   4954 
   4955         public final Set<ComponentName> mEnabledServices = new HashSet<>();
   4956 
   4957         public final Set<ComponentName> mTouchExplorationGrantedServices =
   4958                 new HashSet<>();
   4959 
   4960         public ComponentName mServiceChangingSoftKeyboardMode;
   4961 
   4962         public ComponentName mServiceToEnableWithShortcut;
   4963 
   4964         public int mLastSentClientState = -1;
   4965 
   4966         public int mSoftKeyboardShowMode = 0;
   4967 
   4968         public boolean mIsNavBarMagnificationAssignedToAccessibilityButton;
   4969         public ComponentName mServiceAssignedToAccessibilityButton;
   4970 
   4971         public boolean mIsTouchExplorationEnabled;
   4972         public boolean mIsTextHighContrastEnabled;
   4973         public boolean mIsDisplayMagnificationEnabled;
   4974         public boolean mIsNavBarMagnificationEnabled;
   4975         public boolean mIsAutoclickEnabled;
   4976         public boolean mIsPerformGesturesEnabled;
   4977         public boolean mIsFilterKeyEventsEnabled;
   4978         public boolean mAccessibilityFocusOnlyInActiveWindow;
   4979 
   4980         private Service mUiAutomationService;
   4981         private int mUiAutomationFlags;
   4982         private IAccessibilityServiceClient mUiAutomationServiceClient;
   4983 
   4984         private IBinder mUiAutomationServiceOwner;
   4985         private final DeathRecipient mUiAutomationSerivceOnwerDeathRecipient =
   4986                 new DeathRecipient() {
   4987             @Override
   4988             public void binderDied() {
   4989                 mUiAutomationServiceOwner.unlinkToDeath(
   4990                         mUiAutomationSerivceOnwerDeathRecipient, 0);
   4991                 mUiAutomationServiceOwner = null;
   4992                 if (mUiAutomationService != null) {
   4993                     mUiAutomationService.binderDied();
   4994                 }
   4995             }
   4996         };
   4997 
   4998         public UserState(int userId) {
   4999             mUserId = userId;
   5000         }
   5001 
   5002         public int getClientState() {
   5003             int clientState = 0;
   5004             if (isHandlingAccessibilityEvents()) {
   5005                 clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
   5006             }
   5007             // Touch exploration relies on enabled accessibility.
   5008             if (isHandlingAccessibilityEvents() && mIsTouchExplorationEnabled) {
   5009                 clientState |= AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED;
   5010             }
   5011             if (mIsTextHighContrastEnabled) {
   5012                 clientState |= AccessibilityManager.STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED;
   5013             }
   5014             return clientState;
   5015         }
   5016 
   5017         public boolean isHandlingAccessibilityEvents() {
   5018             return !mBoundServices.isEmpty() || !mBindingServices.isEmpty();
   5019         }
   5020 
   5021         public void onSwitchToAnotherUser() {
   5022             // Clear UI test automation state.
   5023             if (mUiAutomationService != null) {
   5024                 mUiAutomationService.binderDied();
   5025             }
   5026 
   5027             // Unbind all services.
   5028             unbindAllServicesLocked(this);
   5029 
   5030             // Clear service management state.
   5031             mBoundServices.clear();
   5032             mBindingServices.clear();
   5033 
   5034             // Clear event management state.
   5035             mLastSentClientState = -1;
   5036 
   5037             // Clear state persisted in settings.
   5038             mEnabledServices.clear();
   5039             mTouchExplorationGrantedServices.clear();
   5040             mIsTouchExplorationEnabled = false;
   5041             mIsDisplayMagnificationEnabled = false;
   5042             mIsNavBarMagnificationEnabled = false;
   5043             mServiceAssignedToAccessibilityButton = null;
   5044             mIsNavBarMagnificationAssignedToAccessibilityButton = false;
   5045             mIsAutoclickEnabled = false;
   5046             mSoftKeyboardShowMode = 0;
   5047         }
   5048 
   5049         public void destroyUiAutomationService() {
   5050             mUiAutomationService = null;
   5051             mUiAutomationFlags = 0;
   5052             mUiAutomationServiceClient = null;
   5053             if (mUiAutomationServiceOwner != null) {
   5054                 mUiAutomationServiceOwner.unlinkToDeath(
   5055                         mUiAutomationSerivceOnwerDeathRecipient, 0);
   5056                 mUiAutomationServiceOwner = null;
   5057             }
   5058         }
   5059 
   5060         boolean isUiAutomationSuppressingOtherServices() {
   5061             return ((mUiAutomationService != null) && (mUiAutomationFlags
   5062                     & UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0);
   5063         }
   5064     }
   5065 
   5066     private final class AccessibilityContentObserver extends ContentObserver {
   5067 
   5068         private final Uri mTouchExplorationEnabledUri = Settings.Secure.getUriFor(
   5069                 Settings.Secure.TOUCH_EXPLORATION_ENABLED);
   5070 
   5071         private final Uri mDisplayMagnificationEnabledUri = Settings.Secure.getUriFor(
   5072                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
   5073 
   5074         private final Uri mNavBarMagnificationEnabledUri = Settings.Secure.getUriFor(
   5075                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
   5076 
   5077         private final Uri mAutoclickEnabledUri = Settings.Secure.getUriFor(
   5078                 Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED);
   5079 
   5080         private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor(
   5081                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
   5082 
   5083         private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure
   5084                 .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
   5085 
   5086         private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(
   5087                 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
   5088 
   5089         private final Uri mDisplayDaltonizerEnabledUri = Settings.Secure.getUriFor(
   5090                 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
   5091 
   5092         private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
   5093                 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
   5094 
   5095         private final Uri mHighTextContrastUri = Settings.Secure.getUriFor(
   5096                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);
   5097 
   5098         private final Uri mAccessibilitySoftKeyboardModeUri = Settings.Secure.getUriFor(
   5099                 Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
   5100 
   5101         private final Uri mAccessibilityShortcutServiceIdUri = Settings.Secure.getUriFor(
   5102                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
   5103 
   5104         private final Uri mAccessibilityButtonComponentIdUri = Settings.Secure.getUriFor(
   5105                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
   5106 
   5107         public AccessibilityContentObserver(Handler handler) {
   5108             super(handler);
   5109         }
   5110 
   5111         public void register(ContentResolver contentResolver) {
   5112             contentResolver.registerContentObserver(mTouchExplorationEnabledUri,
   5113                     false, this, UserHandle.USER_ALL);
   5114             contentResolver.registerContentObserver(mDisplayMagnificationEnabledUri,
   5115                     false, this, UserHandle.USER_ALL);
   5116             contentResolver.registerContentObserver(mNavBarMagnificationEnabledUri,
   5117                     false, this, UserHandle.USER_ALL);
   5118             contentResolver.registerContentObserver(mAutoclickEnabledUri,
   5119                     false, this, UserHandle.USER_ALL);
   5120             contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri,
   5121                     false, this, UserHandle.USER_ALL);
   5122             contentResolver.registerContentObserver(
   5123                     mTouchExplorationGrantedAccessibilityServicesUri,
   5124                     false, this, UserHandle.USER_ALL);
   5125             contentResolver.registerContentObserver(
   5126                     mDisplayInversionEnabledUri, false, this, UserHandle.USER_ALL);
   5127             contentResolver.registerContentObserver(
   5128                     mDisplayDaltonizerEnabledUri, false, this, UserHandle.USER_ALL);
   5129             contentResolver.registerContentObserver(
   5130                     mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
   5131             contentResolver.registerContentObserver(
   5132                     mHighTextContrastUri, false, this, UserHandle.USER_ALL);
   5133             contentResolver.registerContentObserver(
   5134                     mAccessibilitySoftKeyboardModeUri, false, this, UserHandle.USER_ALL);
   5135             contentResolver.registerContentObserver(
   5136                     mAccessibilityShortcutServiceIdUri, false, this, UserHandle.USER_ALL);
   5137             contentResolver.registerContentObserver(
   5138                     mAccessibilityButtonComponentIdUri, false, this, UserHandle.USER_ALL);
   5139         }
   5140 
   5141         @Override
   5142         public void onChange(boolean selfChange, Uri uri) {
   5143             synchronized (mLock) {
   5144                 // Profiles share the accessibility state of the parent. Therefore,
   5145                 // we are checking for changes only the parent settings.
   5146                 UserState userState = getCurrentUserStateLocked();
   5147 
   5148                 // If the automation service is suppressing, we will update when it dies.
   5149                 if (userState.isUiAutomationSuppressingOtherServices()) {
   5150                     return;
   5151                 }
   5152 
   5153                 if (mTouchExplorationEnabledUri.equals(uri)) {
   5154                     if (readTouchExplorationEnabledSettingLocked(userState)) {
   5155                         onUserStateChangedLocked(userState);
   5156                     }
   5157                 } else if (mDisplayMagnificationEnabledUri.equals(uri)
   5158                         || mNavBarMagnificationEnabledUri.equals(uri)) {
   5159                     if (readMagnificationEnabledSettingsLocked(userState)) {
   5160                         onUserStateChangedLocked(userState);
   5161                     }
   5162                 } else if (mAutoclickEnabledUri.equals(uri)) {
   5163                     if (readAutoclickEnabledSettingLocked(userState)) {
   5164                         onUserStateChangedLocked(userState);
   5165                     }
   5166                 } else if (mEnabledAccessibilityServicesUri.equals(uri)) {
   5167                     if (readEnabledAccessibilityServicesLocked(userState)) {
   5168                         onUserStateChangedLocked(userState);
   5169                     }
   5170                 } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) {
   5171                     if (readTouchExplorationGrantedAccessibilityServicesLocked(userState)) {
   5172                         onUserStateChangedLocked(userState);
   5173                     }
   5174                 } else if (mDisplayDaltonizerEnabledUri.equals(uri)
   5175                         || mDisplayDaltonizerUri.equals(uri)) {
   5176                     updateDisplayDaltonizerLocked(userState);
   5177                 } else if (mDisplayInversionEnabledUri.equals(uri)) {
   5178                     updateDisplayInversionLocked(userState);
   5179                 } else if (mHighTextContrastUri.equals(uri)) {
   5180                     if (readHighTextContrastEnabledSettingLocked(userState)) {
   5181                         onUserStateChangedLocked(userState);
   5182                     }
   5183                 } else if (mAccessibilitySoftKeyboardModeUri.equals(uri)) {
   5184                     if (readSoftKeyboardShowModeChangedLocked(userState)) {
   5185                         notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
   5186                         onUserStateChangedLocked(userState);
   5187                     }
   5188                 } else if (mAccessibilityShortcutServiceIdUri.equals(uri)) {
   5189                     if (readAccessibilityShortcutSettingLocked(userState)) {
   5190                         onUserStateChangedLocked(userState);
   5191                     }
   5192                 } else if (mAccessibilityButtonComponentIdUri.equals(uri)) {
   5193                     if (readAccessibilityButtonSettingsLocked(userState)) {
   5194                         onUserStateChangedLocked(userState);
   5195                     }
   5196                 }
   5197             }
   5198         }
   5199     }
   5200 }
   5201