1 /* 2 ** Copyright 2017, 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.AccessibilityService.ACCESSIBILITY_TAKE_SCREENSHOT_REQUEST_INTERVAL_TIMES_MS; 20 import static android.accessibilityservice.AccessibilityService.KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE; 21 import static android.accessibilityservice.AccessibilityService.KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER; 22 import static android.accessibilityservice.AccessibilityService.KEY_ACCESSIBILITY_SCREENSHOT_STATUS; 23 import static android.accessibilityservice.AccessibilityService.KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP; 24 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT; 25 import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION; 26 import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_SERVICE_CLIENT; 27 import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_SERVICE_CONNECTION; 28 import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; 29 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 30 import static android.view.accessibility.AccessibilityInteractionClient.CALL_STACK; 31 import static android.view.accessibility.AccessibilityInteractionClient.IGNORE_CALL_STACK; 32 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS; 33 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS; 34 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; 35 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; 36 37 import static com.android.window.flags.Flags.deleteCaptureDisplay; 38 39 import android.accessibilityservice.AccessibilityGestureEvent; 40 import android.accessibilityservice.AccessibilityService; 41 import android.accessibilityservice.AccessibilityServiceInfo; 42 import android.accessibilityservice.AccessibilityTrace; 43 import android.accessibilityservice.IAccessibilityServiceClient; 44 import android.accessibilityservice.IAccessibilityServiceConnection; 45 import android.accessibilityservice.IBrailleDisplayController; 46 import android.accessibilityservice.MagnificationConfig; 47 import android.annotation.EnforcePermission; 48 import android.annotation.IntDef; 49 import android.annotation.NonNull; 50 import android.annotation.Nullable; 51 import android.annotation.PermissionManuallyEnforced; 52 import android.annotation.RequiresNoPermission; 53 import android.app.PendingIntent; 54 import android.content.ComponentName; 55 import android.content.Context; 56 import android.content.Intent; 57 import android.content.ServiceConnection; 58 import android.content.pm.PackageManager; 59 import android.content.pm.ParceledListSlice; 60 import android.graphics.ParcelableColorSpace; 61 import android.graphics.Region; 62 import android.hardware.HardwareBuffer; 63 import android.hardware.display.DisplayManager; 64 import android.hardware.display.DisplayManagerInternal; 65 import android.hardware.usb.UsbDevice; 66 import android.os.Binder; 67 import android.os.Build; 68 import android.os.Bundle; 69 import android.os.Handler; 70 import android.os.IBinder; 71 import android.os.Looper; 72 import android.os.Message; 73 import android.os.PermissionEnforcer; 74 import android.os.PowerManager; 75 import android.os.RemoteCallback; 76 import android.os.RemoteException; 77 import android.os.ServiceManager; 78 import android.os.SystemClock; 79 import android.provider.Settings; 80 import android.util.Pair; 81 import android.util.Slog; 82 import android.util.SparseArray; 83 import android.view.Display; 84 import android.view.InputDevice; 85 import android.view.KeyEvent; 86 import android.view.MagnificationSpec; 87 import android.view.MotionEvent; 88 import android.view.SurfaceControl; 89 import android.view.View; 90 import android.view.accessibility.AccessibilityCache; 91 import android.view.accessibility.AccessibilityEvent; 92 import android.view.accessibility.AccessibilityNodeInfo; 93 import android.view.accessibility.AccessibilityWindowInfo; 94 import android.view.accessibility.IAccessibilityInteractionConnectionCallback; 95 import android.view.inputmethod.EditorInfo; 96 import android.window.ScreenCapture; 97 import android.window.ScreenCapture.ScreenshotHardwareBuffer; 98 99 import com.android.internal.annotations.GuardedBy; 100 import com.android.internal.compat.IPlatformCompat; 101 import com.android.internal.inputmethod.IAccessibilityInputMethodSession; 102 import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection; 103 import com.android.internal.os.SomeArgs; 104 import com.android.internal.util.DumpUtils; 105 import com.android.internal.util.function.pooled.PooledLambda; 106 import com.android.server.LocalServices; 107 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection; 108 import com.android.server.accessibility.magnification.MagnificationProcessor; 109 import com.android.server.wm.WindowManagerInternal; 110 111 import java.io.FileDescriptor; 112 import java.io.PrintWriter; 113 import java.lang.annotation.Retention; 114 import java.lang.annotation.RetentionPolicy; 115 import java.util.ArrayList; 116 import java.util.Arrays; 117 import java.util.Collections; 118 import java.util.HashSet; 119 import java.util.List; 120 import java.util.NoSuchElementException; 121 import java.util.Set; 122 123 /** 124 * This class represents an accessibility client - either an AccessibilityService or a UiAutomation. 125 * It is responsible for behavior common to both types of clients. 126 */ 127 abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServiceConnection.Stub 128 implements ServiceConnection, IBinder.DeathRecipient, KeyEventDispatcher.KeyEventFilter, 129 FingerprintGestureDispatcher.FingerprintGestureClient { 130 private static final boolean DEBUG = false; 131 private static final String LOG_TAG = "AbstractAccessibilityServiceConnection"; 132 private static final String TRACE_SVC_CONN = LOG_TAG + ".IAccessibilityServiceConnection"; 133 private static final String TRACE_SVC_CLIENT = LOG_TAG + ".IAccessibilityServiceClient"; 134 private static final String TRACE_WM = "WindowManagerInternal"; 135 private static final int WAIT_WINDOWS_TIMEOUT_MILLIS = 5000; 136 137 /** Display type for displays associated with the default user of the device. */ 138 public static final int DISPLAY_TYPE_DEFAULT = 1 << 0; 139 /** Display type for displays associated with an AccessibilityDisplayProxy user. */ 140 public static final int DISPLAY_TYPE_PROXY = 1 << 1; 141 142 protected static final String TAKE_SCREENSHOT = "takeScreenshot"; 143 protected final Context mContext; 144 protected final SystemSupport mSystemSupport; 145 protected final WindowManagerInternal mWindowManagerService; 146 private final SystemActionPerformer mSystemActionPerformer; 147 final AccessibilityWindowManager mA11yWindowManager; 148 private final DisplayManager mDisplayManager; 149 private final PowerManager mPowerManager; 150 private final IPlatformCompat mIPlatformCompat; 151 152 private final Handler mMainHandler; 153 154 // Handler for scheduling method invocations on the main thread. 155 public final InvocationHandler mInvocationHandler; 156 157 final int mId; 158 159 protected final AccessibilityServiceInfo mAccessibilityServiceInfo; 160 161 // Lock must match the one used by AccessibilityManagerService 162 protected final Object mLock; 163 164 protected final AccessibilitySecurityPolicy mSecurityPolicy; 165 protected final AccessibilityTrace mTrace; 166 167 // The attribution tag set by the service that is bound to this instance 168 protected String mAttributionTag; 169 170 protected int mDisplayTypes = DISPLAY_TYPE_DEFAULT; 171 172 // The service that's bound to this instance. Whenever this value is non-null, this 173 // object is registered as a death recipient 174 IBinder mService; 175 176 IAccessibilityServiceClient mServiceInterface; 177 178 int mEventTypes; 179 180 int mFeedbackType; 181 182 Set<String> mPackageNames = new HashSet<>(); 183 184 boolean mIsDefault; 185 186 boolean mRequestTouchExplorationMode; 187 188 private boolean mServiceHandlesDoubleTap; 189 190 private boolean mRequestMultiFingerGestures; 191 192 private boolean mRequestTwoFingerPassthrough; 193 194 private boolean mSendMotionEvents; 195 196 private SparseArray<Boolean> mServiceDetectsGestures = new SparseArray<>(0); 197 boolean mRequestFilterKeyEvents; 198 199 boolean mRetrieveInteractiveWindows; 200 201 boolean mCaptureFingerprintGestures; 202 203 boolean mRequestAccessibilityButton; 204 205 boolean mReceivedAccessibilityButtonCallbackSinceBind; 206 207 boolean mLastAccessibilityButtonCallbackState; 208 209 boolean mRequestImeApis; 210 211 int mFetchFlags; 212 213 long mNotificationTimeout; 214 215 final ComponentName mComponentName; 216 217 int mGenericMotionEventSources; 218 int mObservedMotionEventSources; 219 220 // the events pending events to be dispatched to this service 221 final SparseArray<AccessibilityEvent> mPendingEvents = new SparseArray<>(); 222 223 /** Whether this service relies on its {@link AccessibilityCache} being up to date */ 224 boolean mUsesAccessibilityCache = false; 225 226 // Handler only for dispatching accessibility events since we use event 227 // types as message types allowing us to remove messages per event type. 228 public Handler mEventDispatchHandler; 229 230 final SparseArray<IBinder> mOverlayWindowTokens = new SparseArray(); 231 232 // All the embedded accessibility overlays that have been added by this service. 233 private List<SurfaceControl> mOverlays = new ArrayList<>(); 234 235 /** The timestamp of requesting to take screenshot in milliseconds */ 236 private long mRequestTakeScreenshotTimestampMs; 237 /** 238 * The timestamps of requesting to take a window screenshot in milliseconds, 239 * mapping from accessibility window id -> timestamp. 240 */ 241 private SparseArray<Long> mRequestTakeScreenshotOfWindowTimestampMs = new SparseArray<>(); 242 243 /** @hide */ 244 @Retention(RetentionPolicy.SOURCE) 245 @IntDef(flag = true, prefix = { "DISPLAY_TYPE_" }, value = { 246 DISPLAY_TYPE_DEFAULT, 247 DISPLAY_TYPE_PROXY 248 }) 249 public @interface DisplayTypes {} 250 251 public interface SystemSupport { 252 /** 253 * @return The current dispatcher for key events 254 */ getKeyEventDispatcher()255 @NonNull KeyEventDispatcher getKeyEventDispatcher(); 256 257 /** 258 * @param displayId The display id. 259 * @return The current injector of motion events used on the display, if one exists. 260 */ getMotionEventInjectorForDisplayLocked(int displayId)261 @Nullable MotionEventInjector getMotionEventInjectorForDisplayLocked(int displayId); 262 263 /** 264 * @return The current dispatcher for fingerprint gestures, if one exists 265 */ getFingerprintGestureDispatcher()266 @Nullable FingerprintGestureDispatcher getFingerprintGestureDispatcher(); 267 268 /** 269 * @return The magnification processor 270 */ 271 @NonNull getMagnificationProcessor()272 MagnificationProcessor getMagnificationProcessor(); 273 274 /** 275 * Called back to notify system that the client has changed 276 * @param serviceInfoChanged True if the service's AccessibilityServiceInfo changed. 277 */ onClientChangeLocked(boolean serviceInfoChanged)278 void onClientChangeLocked(boolean serviceInfoChanged); 279 280 /** 281 * Called back to notify the system the proxy client for a device has changed. 282 * 283 * Changes include if the proxy is unregistered, if its service info list has changed, or if 284 * its focus appearance has changed. 285 */ onProxyChanged(int deviceId)286 void onProxyChanged(int deviceId); 287 getCurrentUserIdLocked()288 int getCurrentUserIdLocked(); 289 getWindowTransformationMatrixAndMagnificationSpec( int windowId)290 Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec( 291 int windowId); 292 isAccessibilityButtonShown()293 boolean isAccessibilityButtonShown(); 294 295 /** 296 * Persists the component names in the specified setting in a 297 * colon separated fashion. 298 * 299 * @param settingName The setting name. 300 * @param componentNames The component names. 301 * @param userId The user id to persist the setting for. 302 */ persistComponentNamesToSettingLocked(String settingName, Set<ComponentName> componentNames, int userId)303 void persistComponentNamesToSettingLocked(String settingName, 304 Set<ComponentName> componentNames, int userId); 305 306 /* This is exactly PendingIntent.getActivity, separated out for testability */ getPendingIntentActivity(Context context, int requestCode, Intent intent, int flags)307 PendingIntent getPendingIntentActivity(Context context, int requestCode, Intent intent, 308 int flags); 309 setGestureDetectionPassthroughRegion(int displayId, Region region)310 void setGestureDetectionPassthroughRegion(int displayId, Region region); 311 setTouchExplorationPassthroughRegion(int displayId, Region region)312 void setTouchExplorationPassthroughRegion(int displayId, Region region); 313 setServiceDetectsGesturesEnabled(int displayId, boolean mode)314 void setServiceDetectsGesturesEnabled(int displayId, boolean mode); 315 requestTouchExploration(int displayId)316 void requestTouchExploration(int displayId); 317 requestDragging(int displayId, int pointerId)318 void requestDragging(int displayId, int pointerId); 319 requestDelegating(int displayId)320 void requestDelegating(int displayId); 321 onDoubleTap(int displayId)322 void onDoubleTap(int displayId); 323 onDoubleTapAndHold(int displayId)324 void onDoubleTapAndHold(int displayId); 325 requestImeLocked(AbstractAccessibilityServiceConnection connection)326 void requestImeLocked(AbstractAccessibilityServiceConnection connection); 327 unbindImeLocked(AbstractAccessibilityServiceConnection connection)328 void unbindImeLocked(AbstractAccessibilityServiceConnection connection); 329 attachAccessibilityOverlayToDisplay( int interactionId, int displayId, SurfaceControl sc, IAccessibilityInteractionConnectionCallback callback)330 void attachAccessibilityOverlayToDisplay( 331 int interactionId, 332 int displayId, 333 SurfaceControl sc, 334 IAccessibilityInteractionConnectionCallback callback); 335 336 } 337 AbstractAccessibilityServiceConnection(Context context, ComponentName componentName, AccessibilityServiceInfo accessibilityServiceInfo, int id, Handler mainHandler, Object lock, AccessibilitySecurityPolicy securityPolicy, SystemSupport systemSupport, AccessibilityTrace trace, WindowManagerInternal windowManagerInternal, SystemActionPerformer systemActionPerfomer, AccessibilityWindowManager a11yWindowManager)338 public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName, 339 AccessibilityServiceInfo accessibilityServiceInfo, int id, Handler mainHandler, 340 Object lock, AccessibilitySecurityPolicy securityPolicy, SystemSupport systemSupport, 341 AccessibilityTrace trace, WindowManagerInternal windowManagerInternal, 342 SystemActionPerformer systemActionPerfomer, 343 AccessibilityWindowManager a11yWindowManager) { 344 super(PermissionEnforcer.fromContext(context)); 345 mContext = context; 346 mWindowManagerService = windowManagerInternal; 347 mId = id; 348 mComponentName = componentName; 349 mAccessibilityServiceInfo = accessibilityServiceInfo; 350 mLock = lock; 351 mSecurityPolicy = securityPolicy; 352 mSystemActionPerformer = systemActionPerfomer; 353 mSystemSupport = systemSupport; 354 mTrace = trace; 355 mMainHandler = mainHandler; 356 mInvocationHandler = new InvocationHandler(mainHandler.getLooper()); 357 mA11yWindowManager = a11yWindowManager; 358 mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); 359 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 360 mIPlatformCompat = IPlatformCompat.Stub.asInterface( 361 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); 362 mEventDispatchHandler = new Handler(mainHandler.getLooper()) { 363 @Override 364 public void handleMessage(Message message) { 365 final int eventType = message.what; 366 AccessibilityEvent event = (AccessibilityEvent) message.obj; 367 boolean serviceWantsEvent = message.arg1 != 0; 368 notifyAccessibilityEventInternal(eventType, event, serviceWantsEvent); 369 } 370 }; 371 setDynamicallyConfigurableProperties(accessibilityServiceInfo); 372 } 373 374 @Override onKeyEvent(KeyEvent keyEvent, int sequenceNumber)375 public boolean onKeyEvent(KeyEvent keyEvent, int sequenceNumber) { 376 if (!mRequestFilterKeyEvents || (mServiceInterface == null)) { 377 return false; 378 } 379 if((mAccessibilityServiceInfo.getCapabilities() 380 & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) == 0) { 381 return false; 382 } 383 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 384 return false; 385 } 386 try { 387 if (svcClientTracingEnabled()) { 388 logTraceSvcClient("onKeyEvent", keyEvent + ", " + sequenceNumber); 389 } 390 mServiceInterface.onKeyEvent(keyEvent, sequenceNumber); 391 } catch (RemoteException e) { 392 return false; 393 } 394 return true; 395 } 396 setDynamicallyConfigurableProperties(AccessibilityServiceInfo info)397 public void setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) { 398 mEventTypes = info.eventTypes; 399 mFeedbackType = info.feedbackType; 400 String[] packageNames = info.packageNames; 401 mPackageNames.clear(); 402 if (packageNames != null) { 403 mPackageNames.addAll(Arrays.asList(packageNames)); 404 } 405 mNotificationTimeout = info.notificationTimeout; 406 mIsDefault = (info.flags & DEFAULT) != 0; 407 mGenericMotionEventSources = info.getMotionEventSources(); 408 if (android.view.accessibility.Flags.motionEventObserving()) { 409 if (mContext.checkCallingOrSelfPermission( 410 android.Manifest.permission.ACCESSIBILITY_MOTION_EVENT_OBSERVING) 411 == PackageManager.PERMISSION_GRANTED) { 412 mObservedMotionEventSources = info.getObservedMotionEventSources(); 413 } else { 414 Slog.e( 415 LOG_TAG, 416 "Observing motion events requires" 417 + " android.Manifest.permission.ACCESSIBILITY_MOTION_EVENT_OBSERVING."); 418 mObservedMotionEventSources = 0; 419 } 420 } 421 422 if (supportsFlagForNotImportantViews(info)) { 423 if ((info.flags & AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0) { 424 mFetchFlags |= 425 AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_INCLUDE_NOT_IMPORTANT_VIEWS; 426 } else { 427 mFetchFlags &= 428 ~AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_INCLUDE_NOT_IMPORTANT_VIEWS; 429 } 430 } 431 432 if ((info.flags & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0) { 433 mFetchFlags |= AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_REPORT_VIEW_IDS; 434 } else { 435 mFetchFlags &= ~AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_REPORT_VIEW_IDS; 436 } 437 438 if (mAccessibilityServiceInfo.isAccessibilityTool()) { 439 mFetchFlags |= AccessibilityNodeInfo.FLAG_SERVICE_IS_ACCESSIBILITY_TOOL; 440 } else { 441 mFetchFlags &= ~AccessibilityNodeInfo.FLAG_SERVICE_IS_ACCESSIBILITY_TOOL; 442 } 443 444 mRequestTouchExplorationMode = (info.flags 445 & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0; 446 mServiceHandlesDoubleTap = (info.flags 447 & AccessibilityServiceInfo.FLAG_SERVICE_HANDLES_DOUBLE_TAP) != 0; 448 mRequestMultiFingerGestures = (info.flags 449 & AccessibilityServiceInfo.FLAG_REQUEST_MULTI_FINGER_GESTURES) != 0; 450 mRequestTwoFingerPassthrough = 451 (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_2_FINGER_PASSTHROUGH) != 0; 452 mSendMotionEvents = 453 (info.flags & AccessibilityServiceInfo.FLAG_SEND_MOTION_EVENTS) != 0; 454 mRequestFilterKeyEvents = 455 (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0; 456 mRetrieveInteractiveWindows = (info.flags 457 & AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0; 458 mCaptureFingerprintGestures = (info.flags 459 & AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES) != 0; 460 mRequestAccessibilityButton = (info.flags 461 & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0; 462 mRequestImeApis = (info.flags 463 & AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR) != 0; 464 } 465 supportsFlagForNotImportantViews(AccessibilityServiceInfo info)466 protected boolean supportsFlagForNotImportantViews(AccessibilityServiceInfo info) { 467 return info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion 468 >= Build.VERSION_CODES.JELLY_BEAN; 469 } 470 canReceiveEventsLocked()471 public boolean canReceiveEventsLocked() { 472 return (mEventTypes != 0 && mService != null); 473 } 474 475 @RequiresNoPermission 476 @Override setOnKeyEventResult(boolean handled, int sequence)477 public void setOnKeyEventResult(boolean handled, int sequence) { 478 if (svcConnTracingEnabled()) { 479 logTraceSvcConn("setOnKeyEventResult", "handled=" + handled + ";sequence=" + sequence); 480 } 481 final long identity = Binder.clearCallingIdentity(); 482 try { 483 mSystemSupport.getKeyEventDispatcher().setOnKeyEventResult(this, handled, sequence); 484 } finally { 485 Binder.restoreCallingIdentity(identity); 486 } 487 } 488 489 @RequiresNoPermission 490 @Override getServiceInfo()491 public AccessibilityServiceInfo getServiceInfo() { 492 if (svcConnTracingEnabled()) { 493 logTraceSvcConn("getServiceInfo", ""); 494 } 495 synchronized (mLock) { 496 return mAccessibilityServiceInfo; 497 } 498 } 499 getCapabilities()500 public int getCapabilities() { 501 return mAccessibilityServiceInfo.getCapabilities(); 502 } 503 getRelevantEventTypes()504 int getRelevantEventTypes() { 505 return (mUsesAccessibilityCache ? AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK 506 : AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) | mEventTypes; 507 } 508 509 @RequiresNoPermission 510 @Override setServiceInfo(AccessibilityServiceInfo info)511 public void setServiceInfo(AccessibilityServiceInfo info) { 512 if (svcConnTracingEnabled()) { 513 logTraceSvcConn("setServiceInfo", "info=" + info); 514 } 515 if (!info.isWithinParcelableSize()) { 516 throw new IllegalStateException( 517 "Cannot update service info: size is larger than safe parcelable limits."); 518 } 519 final long identity = Binder.clearCallingIdentity(); 520 try { 521 synchronized (mLock) { 522 // If the XML manifest had data to configure the service its info 523 // should be already set. In such a case update only the dynamically 524 // configurable properties. 525 boolean oldRequestIme = mRequestImeApis; 526 AccessibilityServiceInfo oldInfo = mAccessibilityServiceInfo; 527 if (oldInfo != null) { 528 oldInfo.updateDynamicallyConfigurableProperties(mIPlatformCompat, info); 529 setDynamicallyConfigurableProperties(oldInfo); 530 } else { 531 setDynamicallyConfigurableProperties(info); 532 } 533 mSystemSupport.onClientChangeLocked(true); 534 if (!oldRequestIme && mRequestImeApis) { 535 mSystemSupport.requestImeLocked(this); 536 } else if (oldRequestIme && !mRequestImeApis) { 537 mSystemSupport.unbindImeLocked(this); 538 } 539 } 540 } finally { 541 Binder.restoreCallingIdentity(identity); 542 } 543 } 544 545 @RequiresNoPermission 546 @Override setInstalledAndEnabledServices(List<AccessibilityServiceInfo> infos)547 public void setInstalledAndEnabledServices(List<AccessibilityServiceInfo> infos) { 548 return; 549 } 550 551 @RequiresNoPermission 552 @Override getInstalledAndEnabledServices()553 public List<AccessibilityServiceInfo> getInstalledAndEnabledServices() { 554 return null; 555 } 556 557 @RequiresNoPermission 558 @Override setAttributionTag(String attributionTag)559 public void setAttributionTag(String attributionTag) { 560 mAttributionTag = attributionTag; 561 } 562 getAttributionTag()563 String getAttributionTag() { 564 return mAttributionTag; 565 } 566 hasRightsToCurrentUserLocked()567 protected abstract boolean hasRightsToCurrentUserLocked(); 568 569 @Nullable 570 @RequiresNoPermission 571 @Override getWindows()572 public AccessibilityWindowInfo.WindowListSparseArray getWindows() { 573 if (svcConnTracingEnabled()) { 574 logTraceSvcConn("getWindows", ""); 575 } 576 synchronized (mLock) { 577 if (!hasRightsToCurrentUserLocked()) { 578 return null; 579 } 580 final boolean permissionGranted = 581 mSecurityPolicy.canRetrieveWindowsLocked(this); 582 if (!permissionGranted) { 583 return null; 584 } 585 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 586 return null; 587 } 588 589 final long identity = Binder.clearCallingIdentity(); 590 try { 591 final AccessibilityWindowInfo.WindowListSparseArray allWindows = 592 new AccessibilityWindowInfo.WindowListSparseArray(); 593 final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked( 594 mDisplayTypes); 595 final int displayListCounts = displayList.size(); 596 if (displayListCounts > 0) { 597 for (int i = 0; i < displayListCounts; i++) { 598 final int displayId = displayList.get(i); 599 ensureWindowsAvailableTimedLocked(displayId); 600 601 final List<AccessibilityWindowInfo> windowList = getWindowsByDisplayLocked( 602 displayId); 603 if (windowList != null) { 604 allWindows.put(displayId, windowList); 605 } 606 } 607 } 608 return allWindows; 609 } finally { 610 Binder.restoreCallingIdentity(identity); 611 } 612 } 613 } 614 setDisplayTypes(@isplayTypes int displayTypes)615 protected void setDisplayTypes(@DisplayTypes int displayTypes) { 616 mDisplayTypes = displayTypes; 617 } 618 619 @RequiresNoPermission 620 @Override getWindow(int windowId)621 public AccessibilityWindowInfo getWindow(int windowId) { 622 if (svcConnTracingEnabled()) { 623 logTraceSvcConn("getWindow", "windowId=" + windowId); 624 } 625 int displayId = Display.INVALID_DISPLAY; 626 if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { 627 displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowId( 628 mSystemSupport.getCurrentUserIdLocked(), windowId); 629 } 630 synchronized (mLock) { 631 ensureWindowsAvailableTimedLocked(displayId); 632 633 if (!hasRightsToCurrentUserLocked()) { 634 return null; 635 } 636 final boolean permissionGranted = 637 mSecurityPolicy.canRetrieveWindowsLocked(this); 638 if (!permissionGranted) { 639 return null; 640 } 641 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 642 return null; 643 } 644 final long identity = Binder.clearCallingIdentity(); 645 try { 646 AccessibilityWindowInfo window = 647 mA11yWindowManager.findA11yWindowInfoByIdLocked(windowId); 648 if (window != null) { 649 AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window); 650 windowClone.setConnectionId(mId); 651 return windowClone; 652 } 653 return null; 654 } finally { 655 Binder.restoreCallingIdentity(identity); 656 } 657 } 658 } 659 660 @RequiresNoPermission 661 @Override findAccessibilityNodeInfosByViewId(int accessibilityWindowId, long accessibilityNodeId, String viewIdResName, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)662 public String[] findAccessibilityNodeInfosByViewId(int accessibilityWindowId, 663 long accessibilityNodeId, String viewIdResName, int interactionId, 664 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 665 throws RemoteException { 666 if (svcConnTracingEnabled()) { 667 logTraceSvcConn("findAccessibilityNodeInfosByViewId", 668 "accessibilityWindowId=" + accessibilityWindowId + ";accessibilityNodeId=" 669 + accessibilityNodeId + ";viewIdResName=" + viewIdResName + ";interactionId=" 670 + interactionId + ";callback=" + callback + ";interrogatingTid=" 671 + interrogatingTid); 672 } 673 final int resolvedWindowId; 674 RemoteAccessibilityConnection connection; 675 Region partialInteractiveRegion = Region.obtain(); 676 synchronized (mLock) { 677 mUsesAccessibilityCache = true; 678 if (!hasRightsToCurrentUserLocked()) { 679 return null; 680 } 681 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 682 final boolean permissionGranted = 683 mSecurityPolicy.canGetAccessibilityNodeInfoLocked( 684 mSystemSupport.getCurrentUserIdLocked(), this, resolvedWindowId); 685 if (!permissionGranted) { 686 return null; 687 } else { 688 connection = mA11yWindowManager.getConnectionLocked( 689 mSystemSupport.getCurrentUserIdLocked(), resolvedWindowId); 690 if (connection == null) { 691 return null; 692 } 693 } 694 if (!mA11yWindowManager.computePartialInteractiveRegionForWindowLocked( 695 resolvedWindowId, partialInteractiveRegion)) { 696 partialInteractiveRegion.recycle(); 697 partialInteractiveRegion = null; 698 } 699 } 700 final Pair<float[], MagnificationSpec> transformMatrixAndSpec = 701 getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId); 702 final float[] transformMatrix = transformMatrixAndSpec.first; 703 final MagnificationSpec spec = transformMatrixAndSpec.second; 704 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 705 return null; 706 } 707 final int interrogatingPid = Binder.getCallingPid(); 708 callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, 709 interrogatingPid, interrogatingTid); 710 final long identityToken = Binder.clearCallingIdentity(); 711 if (intConnTracingEnabled()) { 712 logTraceIntConn("findAccessibilityNodeInfosByViewId", 713 accessibilityNodeId + ";" + viewIdResName + ";" + partialInteractiveRegion + ";" 714 + interactionId + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid 715 + ";" + interrogatingTid + ";" + spec + ";" + Arrays.toString(transformMatrix)); 716 } 717 try { 718 connection.getRemote().findAccessibilityNodeInfosByViewId(accessibilityNodeId, 719 viewIdResName, partialInteractiveRegion, interactionId, callback, mFetchFlags, 720 interrogatingPid, interrogatingTid, spec, transformMatrix); 721 return mSecurityPolicy.computeValidReportedPackages( 722 connection.getPackageName(), connection.getUid()); 723 } catch (RemoteException re) { 724 if (DEBUG) { 725 Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId()."); 726 } 727 } finally { 728 Binder.restoreCallingIdentity(identityToken); 729 // Recycle if passed to another process. 730 if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) { 731 partialInteractiveRegion.recycle(); 732 } 733 } 734 return null; 735 } 736 737 @RequiresNoPermission 738 @Override findAccessibilityNodeInfosByText(int accessibilityWindowId, long accessibilityNodeId, String text, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)739 public String[] findAccessibilityNodeInfosByText(int accessibilityWindowId, 740 long accessibilityNodeId, String text, int interactionId, 741 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 742 throws RemoteException { 743 if (svcConnTracingEnabled()) { 744 logTraceSvcConn("findAccessibilityNodeInfosByText", 745 "accessibilityWindowId=" + accessibilityWindowId + ";accessibilityNodeId=" 746 + accessibilityNodeId + ";text=" + text + ";interactionId=" + interactionId 747 + ";callback=" + callback + ";interrogatingTid=" + interrogatingTid); 748 } 749 final int resolvedWindowId; 750 RemoteAccessibilityConnection connection; 751 Region partialInteractiveRegion = Region.obtain(); 752 synchronized (mLock) { 753 mUsesAccessibilityCache = true; 754 if (!hasRightsToCurrentUserLocked()) { 755 return null; 756 } 757 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 758 final boolean permissionGranted = 759 mSecurityPolicy.canGetAccessibilityNodeInfoLocked( 760 mSystemSupport.getCurrentUserIdLocked(), this, resolvedWindowId); 761 if (!permissionGranted) { 762 return null; 763 } else { 764 connection = mA11yWindowManager.getConnectionLocked( 765 mSystemSupport.getCurrentUserIdLocked(), resolvedWindowId); 766 if (connection == null) { 767 return null; 768 } 769 } 770 if (!mA11yWindowManager.computePartialInteractiveRegionForWindowLocked( 771 resolvedWindowId, partialInteractiveRegion)) { 772 partialInteractiveRegion.recycle(); 773 partialInteractiveRegion = null; 774 } 775 } 776 final Pair<float[], MagnificationSpec> transformMatrixAndSpec = 777 getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId); 778 final float[] transformMatrix = transformMatrixAndSpec.first; 779 final MagnificationSpec spec = transformMatrixAndSpec.second; 780 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 781 return null; 782 } 783 final int interrogatingPid = Binder.getCallingPid(); 784 callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, 785 interrogatingPid, interrogatingTid); 786 final long identityToken = Binder.clearCallingIdentity(); 787 if (intConnTracingEnabled()) { 788 logTraceIntConn("findAccessibilityNodeInfosByText", 789 accessibilityNodeId + ";" + text + ";" + partialInteractiveRegion + ";" 790 + interactionId + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid 791 + ";" + interrogatingTid + ";" + spec + ";" + Arrays.toString(transformMatrix)); 792 } 793 try { 794 connection.getRemote().findAccessibilityNodeInfosByText(accessibilityNodeId, 795 text, partialInteractiveRegion, interactionId, callback, mFetchFlags, 796 interrogatingPid, interrogatingTid, spec, transformMatrix); 797 return mSecurityPolicy.computeValidReportedPackages( 798 connection.getPackageName(), connection.getUid()); 799 } catch (RemoteException re) { 800 if (DEBUG) { 801 Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()"); 802 } 803 } finally { 804 Binder.restoreCallingIdentity(identityToken); 805 // Recycle if passed to another process. 806 if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) { 807 partialInteractiveRegion.recycle(); 808 } 809 } 810 return null; 811 } 812 813 @RequiresNoPermission 814 @Override findAccessibilityNodeInfoByAccessibilityId( int accessibilityWindowId, long accessibilityNodeId, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, long interrogatingTid, Bundle arguments)815 public String[] findAccessibilityNodeInfoByAccessibilityId( 816 int accessibilityWindowId, long accessibilityNodeId, int interactionId, 817 IAccessibilityInteractionConnectionCallback callback, int flags, 818 long interrogatingTid, Bundle arguments) throws RemoteException { 819 if (svcConnTracingEnabled()) { 820 logTraceSvcConn("findAccessibilityNodeInfoByAccessibilityId", 821 "accessibilityWindowId=" + accessibilityWindowId + ";accessibilityNodeId=" 822 + accessibilityNodeId + ";interactionId=" + interactionId + ";callback=" 823 + callback + ";flags=" + flags + ";interrogatingTid=" + interrogatingTid 824 + ";arguments=" + arguments); 825 } 826 final int resolvedWindowId; 827 RemoteAccessibilityConnection connection; 828 Region partialInteractiveRegion = Region.obtain(); 829 synchronized (mLock) { 830 mUsesAccessibilityCache = true; 831 if (!hasRightsToCurrentUserLocked()) { 832 return null; 833 } 834 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 835 final boolean permissionGranted = 836 mSecurityPolicy.canGetAccessibilityNodeInfoLocked( 837 mSystemSupport.getCurrentUserIdLocked(), this, resolvedWindowId); 838 if (!permissionGranted) { 839 return null; 840 } else { 841 connection = mA11yWindowManager.getConnectionLocked( 842 mSystemSupport.getCurrentUserIdLocked(), resolvedWindowId); 843 if (connection == null) { 844 return null; 845 } 846 } 847 if (!mA11yWindowManager.computePartialInteractiveRegionForWindowLocked( 848 resolvedWindowId, partialInteractiveRegion)) { 849 partialInteractiveRegion.recycle(); 850 partialInteractiveRegion = null; 851 } 852 } 853 final Pair<float[], MagnificationSpec> transformMatrixAndSpec = 854 getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId); 855 final float[] transformMatrix = transformMatrixAndSpec.first; 856 final MagnificationSpec spec = transformMatrixAndSpec.second; 857 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 858 return null; 859 } 860 final int interrogatingPid = Binder.getCallingPid(); 861 callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, 862 interrogatingPid, interrogatingTid); 863 final long identityToken = Binder.clearCallingIdentity(); 864 if (intConnTracingEnabled()) { 865 logTraceIntConn("findAccessibilityNodeInfoByAccessibilityId", 866 accessibilityNodeId + ";" + partialInteractiveRegion + ";" + interactionId + ";" 867 + callback + ";" + (mFetchFlags | flags) + ";" + interrogatingPid + ";" 868 + interrogatingTid + ";" + spec + ";" + Arrays.toString(transformMatrix) 869 + ";" + arguments); 870 } 871 try { 872 connection.getRemote().findAccessibilityNodeInfoByAccessibilityId( 873 accessibilityNodeId, partialInteractiveRegion, interactionId, callback, 874 mFetchFlags | flags, interrogatingPid, interrogatingTid, spec, transformMatrix, 875 arguments); 876 return mSecurityPolicy.computeValidReportedPackages( 877 connection.getPackageName(), connection.getUid()); 878 } catch (RemoteException re) { 879 if (DEBUG) { 880 Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()"); 881 } 882 } finally { 883 Binder.restoreCallingIdentity(identityToken); 884 // Recycle if passed to another process. 885 if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) { 886 partialInteractiveRegion.recycle(); 887 } 888 } 889 return null; 890 } 891 892 @RequiresNoPermission 893 @Override findFocus(int accessibilityWindowId, long accessibilityNodeId, int focusType, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)894 public String[] findFocus(int accessibilityWindowId, long accessibilityNodeId, 895 int focusType, int interactionId, 896 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 897 throws RemoteException { 898 if (svcConnTracingEnabled()) { 899 logTraceSvcConn("findFocus", 900 "accessibilityWindowId=" + accessibilityWindowId + ";accessibilityNodeId=" 901 + accessibilityNodeId + ";focusType=" + focusType + ";interactionId=" 902 + interactionId + ";callback=" + callback + ";interrogatingTid=" 903 + interrogatingTid); 904 } 905 final int resolvedWindowId; 906 RemoteAccessibilityConnection connection; 907 Region partialInteractiveRegion = Region.obtain(); 908 synchronized (mLock) { 909 if (!hasRightsToCurrentUserLocked()) { 910 return null; 911 } 912 resolvedWindowId = resolveAccessibilityWindowIdForFindFocusLocked( 913 accessibilityWindowId, focusType); 914 final boolean permissionGranted = 915 mSecurityPolicy.canGetAccessibilityNodeInfoLocked( 916 mSystemSupport.getCurrentUserIdLocked(), this, resolvedWindowId); 917 if (!permissionGranted) { 918 return null; 919 } else { 920 connection = mA11yWindowManager.getConnectionLocked( 921 mSystemSupport.getCurrentUserIdLocked(), resolvedWindowId); 922 if (connection == null) { 923 return null; 924 } 925 } 926 if (!mA11yWindowManager.computePartialInteractiveRegionForWindowLocked( 927 resolvedWindowId, partialInteractiveRegion)) { 928 partialInteractiveRegion.recycle(); 929 partialInteractiveRegion = null; 930 } 931 } 932 final Pair<float[], MagnificationSpec> transformMatrixAndSpec = 933 getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId); 934 final float[] transformMatrix = transformMatrixAndSpec.first; 935 final MagnificationSpec spec = transformMatrixAndSpec.second; 936 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 937 return null; 938 } 939 final int interrogatingPid = Binder.getCallingPid(); 940 callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, 941 interrogatingPid, interrogatingTid); 942 final long identityToken = Binder.clearCallingIdentity(); 943 if (intConnTracingEnabled()) { 944 logTraceIntConn("findFocus", 945 accessibilityNodeId + ";" + focusType + ";" + partialInteractiveRegion + ";" 946 + interactionId + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid 947 + ";" + interrogatingTid + ";" + spec + ";" 948 + Arrays.toString(transformMatrix)); 949 } 950 try { 951 connection.getRemote().findFocus(accessibilityNodeId, focusType, 952 partialInteractiveRegion, interactionId, callback, mFetchFlags, 953 interrogatingPid, interrogatingTid, spec, transformMatrix); 954 return mSecurityPolicy.computeValidReportedPackages( 955 connection.getPackageName(), connection.getUid()); 956 } catch (RemoteException re) { 957 if (DEBUG) { 958 Slog.e(LOG_TAG, "Error calling findFocus()"); 959 } 960 } finally { 961 Binder.restoreCallingIdentity(identityToken); 962 // Recycle if passed to another process. 963 if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) { 964 partialInteractiveRegion.recycle(); 965 } 966 } 967 return null; 968 } 969 970 @RequiresNoPermission 971 @Override focusSearch(int accessibilityWindowId, long accessibilityNodeId, int direction, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)972 public String[] focusSearch(int accessibilityWindowId, long accessibilityNodeId, 973 int direction, int interactionId, 974 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 975 throws RemoteException { 976 if (svcConnTracingEnabled()) { 977 logTraceSvcConn("focusSearch", 978 "accessibilityWindowId=" + accessibilityWindowId + ";accessibilityNodeId=" 979 + accessibilityNodeId + ";direction=" + direction + ";interactionId=" 980 + interactionId + ";callback=" + callback + ";interrogatingTid=" 981 + interrogatingTid); 982 } 983 final int resolvedWindowId; 984 RemoteAccessibilityConnection connection; 985 Region partialInteractiveRegion = Region.obtain(); 986 synchronized (mLock) { 987 if (!hasRightsToCurrentUserLocked()) { 988 return null; 989 } 990 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 991 final boolean permissionGranted = 992 mSecurityPolicy.canGetAccessibilityNodeInfoLocked( 993 mSystemSupport.getCurrentUserIdLocked(), this, resolvedWindowId); 994 if (!permissionGranted) { 995 return null; 996 } else { 997 connection = mA11yWindowManager.getConnectionLocked( 998 mSystemSupport.getCurrentUserIdLocked(), resolvedWindowId); 999 if (connection == null) { 1000 return null; 1001 } 1002 } 1003 if (!mA11yWindowManager.computePartialInteractiveRegionForWindowLocked( 1004 resolvedWindowId, partialInteractiveRegion)) { 1005 partialInteractiveRegion.recycle(); 1006 partialInteractiveRegion = null; 1007 } 1008 } 1009 final Pair<float[], MagnificationSpec> transformMatrixAndSpec = 1010 getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId); 1011 final float[] transformMatrix = transformMatrixAndSpec.first; 1012 final MagnificationSpec spec = transformMatrixAndSpec.second; 1013 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 1014 return null; 1015 } 1016 final int interrogatingPid = Binder.getCallingPid(); 1017 callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, 1018 interrogatingPid, interrogatingTid); 1019 final long identityToken = Binder.clearCallingIdentity(); 1020 if (intConnTracingEnabled()) { 1021 logTraceIntConn("focusSearch", 1022 accessibilityNodeId + ";" + direction + ";" + partialInteractiveRegion 1023 + ";" + interactionId + ";" + callback + ";" + mFetchFlags + ";" 1024 + interrogatingPid + ";" + interrogatingTid + ";" + spec + ";" 1025 + Arrays.toString(transformMatrix)); 1026 } 1027 try { 1028 connection.getRemote().focusSearch(accessibilityNodeId, direction, 1029 partialInteractiveRegion, interactionId, callback, mFetchFlags, 1030 interrogatingPid, interrogatingTid, spec, transformMatrix); 1031 return mSecurityPolicy.computeValidReportedPackages( 1032 connection.getPackageName(), connection.getUid()); 1033 } catch (RemoteException re) { 1034 if (DEBUG) { 1035 Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()"); 1036 } 1037 } finally { 1038 Binder.restoreCallingIdentity(identityToken); 1039 // Recycle if passed to another process. 1040 if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) { 1041 partialInteractiveRegion.recycle(); 1042 } 1043 } 1044 return null; 1045 } 1046 1047 @RequiresNoPermission 1048 @Override sendGesture(int sequence, ParceledListSlice gestureSteps)1049 public void sendGesture(int sequence, ParceledListSlice gestureSteps) { 1050 if (svcConnTracingEnabled()) { 1051 logTraceSvcConn( 1052 "sendGesture", "sequence=" + sequence + ";gestureSteps=" + gestureSteps); 1053 } 1054 } 1055 1056 @RequiresNoPermission 1057 @Override dispatchGesture(int sequence, ParceledListSlice gestureSteps, int displayId)1058 public void dispatchGesture(int sequence, ParceledListSlice gestureSteps, int displayId) { 1059 if (svcConnTracingEnabled()) { 1060 logTraceSvcConn("dispatchGesture", "sequence=" + sequence + ";gestureSteps=" 1061 + gestureSteps + ";displayId=" + displayId); 1062 } 1063 } 1064 1065 @RequiresNoPermission 1066 @Override performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId, int action, Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)1067 public boolean performAccessibilityAction(int accessibilityWindowId, 1068 long accessibilityNodeId, int action, Bundle arguments, int interactionId, 1069 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) 1070 throws RemoteException { 1071 if (svcConnTracingEnabled()) { 1072 logTraceSvcConn("performAccessibilityAction", 1073 "accessibilityWindowId=" + accessibilityWindowId + ";accessibilityNodeId=" 1074 + accessibilityNodeId + ";action=" + action + ";arguments=" + arguments 1075 + ";interactionId=" + interactionId + ";callback=" + callback 1076 + ";interrogatingTid=" + interrogatingTid); 1077 } 1078 final int resolvedWindowId; 1079 synchronized (mLock) { 1080 if (!hasRightsToCurrentUserLocked()) { 1081 return false; 1082 } 1083 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); 1084 if (!mSecurityPolicy.canGetAccessibilityNodeInfoLocked( 1085 mSystemSupport.getCurrentUserIdLocked(), this, resolvedWindowId)) { 1086 return false; 1087 } 1088 } 1089 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 1090 return false; 1091 } 1092 return performAccessibilityActionInternal( 1093 mSystemSupport.getCurrentUserIdLocked(), resolvedWindowId, accessibilityNodeId, 1094 action, arguments, interactionId, callback, mFetchFlags, interrogatingTid); 1095 } 1096 1097 @RequiresNoPermission 1098 @Override performGlobalAction(int action)1099 public boolean performGlobalAction(int action) { 1100 if (svcConnTracingEnabled()) { 1101 logTraceSvcConn("performGlobalAction", "action=" + action); 1102 } 1103 synchronized (mLock) { 1104 if (!hasRightsToCurrentUserLocked()) { 1105 return false; 1106 } 1107 } 1108 final long identity = Binder.clearCallingIdentity(); 1109 try { 1110 return mSystemActionPerformer.performSystemAction(action); 1111 } finally { 1112 Binder.restoreCallingIdentity(identity); 1113 } 1114 } 1115 1116 @RequiresNoPermission 1117 @Override getSystemActions()1118 public @NonNull List<AccessibilityNodeInfo.AccessibilityAction> getSystemActions() { 1119 if (svcConnTracingEnabled()) { 1120 logTraceSvcConn("getSystemActions", ""); 1121 } 1122 synchronized (mLock) { 1123 if (!hasRightsToCurrentUserLocked()) { 1124 return Collections.emptyList(); 1125 } 1126 } 1127 final long identity = Binder.clearCallingIdentity(); 1128 try { 1129 return mSystemActionPerformer.getSystemActions(); 1130 } finally { 1131 Binder.restoreCallingIdentity(identity); 1132 } 1133 } 1134 1135 @RequiresNoPermission 1136 @Override isFingerprintGestureDetectionAvailable()1137 public boolean isFingerprintGestureDetectionAvailable() { 1138 if (svcConnTracingEnabled()) { 1139 logTraceSvcConn("isFingerprintGestureDetectionAvailable", ""); 1140 } 1141 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 1142 return false; 1143 } 1144 final long identity = Binder.clearCallingIdentity(); 1145 try { 1146 if (isCapturingFingerprintGestures()) { 1147 FingerprintGestureDispatcher dispatcher = 1148 mSystemSupport.getFingerprintGestureDispatcher(); 1149 return (dispatcher != null) && dispatcher.isFingerprintGestureDetectionAvailable(); 1150 } 1151 return false; 1152 } finally { 1153 Binder.restoreCallingIdentity(identity); 1154 } 1155 } 1156 1157 @Nullable 1158 @RequiresNoPermission 1159 @Override getMagnificationConfig(int displayId)1160 public MagnificationConfig getMagnificationConfig(int displayId) { 1161 if (svcConnTracingEnabled()) { 1162 logTraceSvcConn("getMagnificationConfig", "displayId=" + displayId); 1163 } 1164 synchronized (mLock) { 1165 if (!hasRightsToCurrentUserLocked()) { 1166 return null; 1167 } 1168 } 1169 final long identity = Binder.clearCallingIdentity(); 1170 try { 1171 return mSystemSupport.getMagnificationProcessor().getMagnificationConfig(displayId); 1172 } finally { 1173 Binder.restoreCallingIdentity(identity); 1174 } 1175 } 1176 1177 @RequiresNoPermission 1178 @Override getMagnificationScale(int displayId)1179 public float getMagnificationScale(int displayId) { 1180 if (svcConnTracingEnabled()) { 1181 logTraceSvcConn("getMagnificationScale", "displayId=" + displayId); 1182 } 1183 synchronized (mLock) { 1184 if (!hasRightsToCurrentUserLocked()) { 1185 return 1.0f; 1186 } 1187 } 1188 final long identity = Binder.clearCallingIdentity(); 1189 try { 1190 return mSystemSupport.getMagnificationProcessor().getScale(displayId); 1191 } finally { 1192 Binder.restoreCallingIdentity(identity); 1193 } 1194 } 1195 1196 @RequiresNoPermission 1197 @Override getMagnificationRegion(int displayId)1198 public Region getMagnificationRegion(int displayId) { 1199 if (svcConnTracingEnabled()) { 1200 logTraceSvcConn("getMagnificationRegion", "displayId=" + displayId); 1201 } 1202 synchronized (mLock) { 1203 final Region region = Region.obtain(); 1204 if (!hasRightsToCurrentUserLocked()) { 1205 return region; 1206 } 1207 MagnificationProcessor magnificationProcessor = 1208 mSystemSupport.getMagnificationProcessor(); 1209 final long identity = Binder.clearCallingIdentity(); 1210 try { 1211 magnificationProcessor.getFullscreenMagnificationRegion(displayId, 1212 region, mSecurityPolicy.canControlMagnification(this)); 1213 return region; 1214 } finally { 1215 Binder.restoreCallingIdentity(identity); 1216 } 1217 } 1218 } 1219 1220 1221 @RequiresNoPermission 1222 @Override getCurrentMagnificationRegion(int displayId)1223 public Region getCurrentMagnificationRegion(int displayId) { 1224 if (svcConnTracingEnabled()) { 1225 logTraceSvcConn("getCurrentMagnificationRegion", "displayId=" + displayId); 1226 } 1227 synchronized (mLock) { 1228 final Region region = Region.obtain(); 1229 if (!hasRightsToCurrentUserLocked()) { 1230 return region; 1231 } 1232 MagnificationProcessor magnificationProcessor = 1233 mSystemSupport.getMagnificationProcessor(); 1234 final long identity = Binder.clearCallingIdentity(); 1235 try { 1236 magnificationProcessor.getCurrentMagnificationRegion(displayId, 1237 region, mSecurityPolicy.canControlMagnification(this)); 1238 return region; 1239 } finally { 1240 Binder.restoreCallingIdentity(identity); 1241 } 1242 } 1243 } 1244 1245 @RequiresNoPermission 1246 @Override getMagnificationCenterX(int displayId)1247 public float getMagnificationCenterX(int displayId) { 1248 if (svcConnTracingEnabled()) { 1249 logTraceSvcConn("getMagnificationCenterX", "displayId=" + displayId); 1250 } 1251 synchronized (mLock) { 1252 if (!hasRightsToCurrentUserLocked()) { 1253 return 0.0f; 1254 } 1255 MagnificationProcessor magnificationProcessor = 1256 mSystemSupport.getMagnificationProcessor(); 1257 final long identity = Binder.clearCallingIdentity(); 1258 try { 1259 return magnificationProcessor.getCenterX(displayId, 1260 mSecurityPolicy.canControlMagnification(this)); 1261 } finally { 1262 Binder.restoreCallingIdentity(identity); 1263 } 1264 } 1265 } 1266 1267 @RequiresNoPermission 1268 @Override getMagnificationCenterY(int displayId)1269 public float getMagnificationCenterY(int displayId) { 1270 if (svcConnTracingEnabled()) { 1271 logTraceSvcConn("getMagnificationCenterY", "displayId=" + displayId); 1272 } 1273 synchronized (mLock) { 1274 if (!hasRightsToCurrentUserLocked()) { 1275 return 0.0f; 1276 } 1277 MagnificationProcessor magnificationProcessor = 1278 mSystemSupport.getMagnificationProcessor(); 1279 final long identity = Binder.clearCallingIdentity(); 1280 try { 1281 return magnificationProcessor.getCenterY(displayId, 1282 mSecurityPolicy.canControlMagnification(this)); 1283 } finally { 1284 Binder.restoreCallingIdentity(identity); 1285 } 1286 } 1287 } 1288 1289 @RequiresNoPermission 1290 @Override resetMagnification(int displayId, boolean animate)1291 public boolean resetMagnification(int displayId, boolean animate) { 1292 if (svcConnTracingEnabled()) { 1293 logTraceSvcConn("resetMagnification", "displayId=" + displayId + ";animate=" + animate); 1294 } 1295 synchronized (mLock) { 1296 if (!hasRightsToCurrentUserLocked()) { 1297 return false; 1298 } 1299 if (!mSecurityPolicy.canControlMagnification(this)) { 1300 return false; 1301 } 1302 } 1303 final long identity = Binder.clearCallingIdentity(); 1304 try { 1305 MagnificationProcessor magnificationProcessor = 1306 mSystemSupport.getMagnificationProcessor(); 1307 return (magnificationProcessor.resetFullscreenMagnification(displayId, animate) 1308 || !magnificationProcessor.isMagnifying(displayId)); 1309 } finally { 1310 Binder.restoreCallingIdentity(identity); 1311 } 1312 } 1313 1314 @RequiresNoPermission 1315 @Override resetCurrentMagnification(int displayId, boolean animate)1316 public boolean resetCurrentMagnification(int displayId, boolean animate) { 1317 if (svcConnTracingEnabled()) { 1318 logTraceSvcConn("resetCurrentMagnification", 1319 "displayId=" + displayId + ";animate=" + animate); 1320 } 1321 synchronized (mLock) { 1322 if (!hasRightsToCurrentUserLocked()) { 1323 return false; 1324 } 1325 if (!mSecurityPolicy.canControlMagnification(this)) { 1326 return false; 1327 } 1328 } 1329 final long identity = Binder.clearCallingIdentity(); 1330 try { 1331 MagnificationProcessor magnificationProcessor = 1332 mSystemSupport.getMagnificationProcessor(); 1333 return (magnificationProcessor.resetCurrentMagnification(displayId, animate) 1334 || !magnificationProcessor.isMagnifying(displayId)); 1335 } finally { 1336 Binder.restoreCallingIdentity(identity); 1337 } 1338 } 1339 1340 @RequiresNoPermission 1341 @Override setMagnificationConfig(int displayId, @NonNull MagnificationConfig config, boolean animate)1342 public boolean setMagnificationConfig(int displayId, 1343 @NonNull MagnificationConfig config, boolean animate) { 1344 if (svcConnTracingEnabled()) { 1345 logTraceSvcConn("setMagnificationSpec", 1346 "displayId=" + displayId + ", config=" + config.toString()); 1347 } 1348 synchronized (mLock) { 1349 if (!hasRightsToCurrentUserLocked()) { 1350 return false; 1351 } 1352 if (!mSecurityPolicy.canControlMagnification(this)) { 1353 return false; 1354 } 1355 final long identity = Binder.clearCallingIdentity(); 1356 try { 1357 MagnificationProcessor magnificationProcessor = 1358 mSystemSupport.getMagnificationProcessor(); 1359 return magnificationProcessor.setMagnificationConfig(displayId, config, animate, 1360 mId); 1361 } finally { 1362 Binder.restoreCallingIdentity(identity); 1363 } 1364 } 1365 } 1366 1367 @RequiresNoPermission 1368 @Override setMagnificationCallbackEnabled(int displayId, boolean enabled)1369 public void setMagnificationCallbackEnabled(int displayId, boolean enabled) { 1370 if (svcConnTracingEnabled()) { 1371 logTraceSvcConn("setMagnificationCallbackEnabled", 1372 "displayId=" + displayId + ";enabled=" + enabled); 1373 } 1374 final long identity = Binder.clearCallingIdentity(); 1375 try { 1376 mInvocationHandler.setMagnificationCallbackEnabled(displayId, enabled); 1377 } finally { 1378 Binder.restoreCallingIdentity(identity); 1379 } 1380 } 1381 isMagnificationCallbackEnabled(int displayId)1382 public boolean isMagnificationCallbackEnabled(int displayId) { 1383 return mInvocationHandler.isMagnificationCallbackEnabled(displayId); 1384 } 1385 1386 @RequiresNoPermission 1387 @Override setSoftKeyboardCallbackEnabled(boolean enabled)1388 public void setSoftKeyboardCallbackEnabled(boolean enabled) { 1389 if (svcConnTracingEnabled()) { 1390 logTraceSvcConn("setSoftKeyboardCallbackEnabled", "enabled=" + enabled); 1391 } 1392 final long identity = Binder.clearCallingIdentity(); 1393 try { 1394 mInvocationHandler.setSoftKeyboardCallbackEnabled(enabled); 1395 } finally { 1396 Binder.restoreCallingIdentity(identity); 1397 } 1398 } 1399 1400 @RequiresNoPermission 1401 @Override takeScreenshotOfWindow(int accessibilityWindowId, int interactionId, ScreenCapture.ScreenCaptureListener listener, IAccessibilityInteractionConnectionCallback callback)1402 public void takeScreenshotOfWindow(int accessibilityWindowId, int interactionId, 1403 ScreenCapture.ScreenCaptureListener listener, 1404 IAccessibilityInteractionConnectionCallback callback) throws RemoteException { 1405 final long currentTimestamp = SystemClock.uptimeMillis(); 1406 if ((currentTimestamp 1407 - mRequestTakeScreenshotOfWindowTimestampMs.get(accessibilityWindowId, 0L)) 1408 <= ACCESSIBILITY_TAKE_SCREENSHOT_REQUEST_INTERVAL_TIMES_MS) { 1409 callback.sendTakeScreenshotOfWindowError( 1410 AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERVAL_TIME_SHORT, interactionId); 1411 return; 1412 } 1413 mRequestTakeScreenshotOfWindowTimestampMs.put(accessibilityWindowId, currentTimestamp); 1414 1415 synchronized (mLock) { 1416 if (!hasRightsToCurrentUserLocked()) { 1417 callback.sendTakeScreenshotOfWindowError( 1418 AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERNAL_ERROR, interactionId); 1419 return; 1420 } 1421 if (!mSecurityPolicy.canTakeScreenshotLocked(this)) { 1422 callback.sendTakeScreenshotOfWindowError( 1423 AccessibilityService.ERROR_TAKE_SCREENSHOT_NO_ACCESSIBILITY_ACCESS, 1424 interactionId); 1425 return; 1426 } 1427 } 1428 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 1429 callback.sendTakeScreenshotOfWindowError( 1430 AccessibilityService.ERROR_TAKE_SCREENSHOT_NO_ACCESSIBILITY_ACCESS, 1431 interactionId); 1432 return; 1433 } 1434 1435 final long identity = Binder.clearCallingIdentity(); 1436 try { 1437 RemoteAccessibilityConnection connection = mA11yWindowManager.getConnectionLocked( 1438 mSystemSupport.getCurrentUserIdLocked(), 1439 resolveAccessibilityWindowIdLocked(accessibilityWindowId)); 1440 if (connection == null) { 1441 callback.sendTakeScreenshotOfWindowError( 1442 AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_WINDOW, interactionId); 1443 return; 1444 } 1445 connection.getRemote().takeScreenshotOfWindow(interactionId, listener, callback); 1446 } finally { 1447 Binder.restoreCallingIdentity(identity); 1448 } 1449 } 1450 1451 @RequiresNoPermission 1452 @Override takeScreenshot(int displayId, RemoteCallback callback)1453 public void takeScreenshot(int displayId, RemoteCallback callback) { 1454 if (svcConnTracingEnabled()) { 1455 logTraceSvcConn("takeScreenshot", "displayId=" + displayId + ";callback=" + callback); 1456 } 1457 final long currentTimestamp = SystemClock.uptimeMillis(); 1458 if (mRequestTakeScreenshotTimestampMs != 0 1459 && (currentTimestamp - mRequestTakeScreenshotTimestampMs) 1460 <= AccessibilityService.ACCESSIBILITY_TAKE_SCREENSHOT_REQUEST_INTERVAL_TIMES_MS) { 1461 sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERVAL_TIME_SHORT, 1462 callback); 1463 return; 1464 } 1465 mRequestTakeScreenshotTimestampMs = currentTimestamp; 1466 1467 synchronized (mLock) { 1468 if (!hasRightsToCurrentUserLocked()) { 1469 sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERNAL_ERROR, 1470 callback); 1471 return; 1472 } 1473 1474 if (!mSecurityPolicy.canTakeScreenshotLocked(this)) { 1475 throw new SecurityException("Services don't have the capability of taking" 1476 + " the screenshot."); 1477 } 1478 } 1479 1480 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 1481 sendScreenshotFailure( 1482 AccessibilityService.ERROR_TAKE_SCREENSHOT_NO_ACCESSIBILITY_ACCESS, 1483 callback); 1484 return; 1485 } 1486 1487 // Private virtual displays are created by the ap and is not allowed to access by other 1488 // aps. We assume the contents on this display should not be captured. 1489 final DisplayManager displayManager = 1490 (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); 1491 final Display display = displayManager.getDisplay(displayId); 1492 if ((display == null) || (display.getType() == Display.TYPE_VIRTUAL 1493 && (display.getFlags() & Display.FLAG_PRIVATE) != 0)) { 1494 sendScreenshotFailure( 1495 AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); 1496 return; 1497 } 1498 final long identity = Binder.clearCallingIdentity(); 1499 if (deleteCaptureDisplay()) { 1500 try { 1501 ScreenCapture.ScreenCaptureListener screenCaptureListener = new 1502 ScreenCapture.ScreenCaptureListener( 1503 (screenshotBuffer, result) -> { 1504 if (screenshotBuffer != null && result == 0) { 1505 sendScreenshotSuccess(screenshotBuffer, callback); 1506 } else { 1507 sendScreenshotFailure( 1508 AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, 1509 callback); 1510 } 1511 } 1512 ); 1513 mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener); 1514 } catch (Exception e) { 1515 sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, 1516 callback); 1517 } finally { 1518 Binder.restoreCallingIdentity(identity); 1519 } 1520 } else { 1521 try { 1522 mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { 1523 final ScreenshotHardwareBuffer screenshotBuffer = LocalServices 1524 .getService(DisplayManagerInternal.class).userScreenshot(displayId); 1525 if (screenshotBuffer != null) { 1526 sendScreenshotSuccess(screenshotBuffer, callback); 1527 } else { 1528 sendScreenshotFailure( 1529 AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, 1530 callback); 1531 } 1532 }, null).recycleOnUse()); 1533 } finally { 1534 Binder.restoreCallingIdentity(identity); 1535 } 1536 } 1537 } 1538 sendScreenshotSuccess(ScreenshotHardwareBuffer screenshotBuffer, RemoteCallback callback)1539 private void sendScreenshotSuccess(ScreenshotHardwareBuffer screenshotBuffer, 1540 RemoteCallback callback) { 1541 if (deleteCaptureDisplay()) { 1542 mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { 1543 final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); 1544 final ParcelableColorSpace colorSpace = 1545 new ParcelableColorSpace(screenshotBuffer.getColorSpace()); 1546 1547 final Bundle payload = new Bundle(); 1548 payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS, 1549 AccessibilityService.TAKE_SCREENSHOT_SUCCESS); 1550 payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, 1551 hardwareBuffer); 1552 payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace); 1553 payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP, 1554 SystemClock.uptimeMillis()); 1555 1556 // Send back the result. 1557 callback.sendResult(payload); 1558 hardwareBuffer.close(); 1559 }, null).recycleOnUse()); 1560 } else { 1561 final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); 1562 final ParcelableColorSpace colorSpace = 1563 new ParcelableColorSpace(screenshotBuffer.getColorSpace()); 1564 1565 final Bundle payload = new Bundle(); 1566 payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS, 1567 AccessibilityService.TAKE_SCREENSHOT_SUCCESS); 1568 payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, 1569 hardwareBuffer); 1570 payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace); 1571 payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP, 1572 SystemClock.uptimeMillis()); 1573 1574 // Send back the result. 1575 callback.sendResult(payload); 1576 hardwareBuffer.close(); 1577 } 1578 } 1579 sendScreenshotFailure(@ccessibilityService.ScreenshotErrorCode int errorCode, RemoteCallback callback)1580 private void sendScreenshotFailure(@AccessibilityService.ScreenshotErrorCode int errorCode, 1581 RemoteCallback callback) { 1582 mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { 1583 final Bundle payload = new Bundle(); 1584 payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS, errorCode); 1585 // Send back the result. 1586 callback.sendResult(payload); 1587 }, null).recycleOnUse()); 1588 } 1589 1590 @Override 1591 @PermissionManuallyEnforced dump(FileDescriptor fd, final PrintWriter pw, String[] args)1592 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 1593 if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; 1594 synchronized (mLock) { 1595 pw.append("Service[label=" + mAccessibilityServiceInfo.getResolveInfo() 1596 .loadLabel(mContext.getPackageManager())); 1597 pw.append(", feedbackType" 1598 + AccessibilityServiceInfo.feedbackTypeToString(mFeedbackType)); 1599 pw.append(", capabilities=" + mAccessibilityServiceInfo.getCapabilities()); 1600 pw.append(", eventTypes=" 1601 + AccessibilityEvent.eventTypeToString(mEventTypes)); 1602 pw.append(", notificationTimeout=" + mNotificationTimeout); 1603 pw.append(", requestA11yBtn=" + mRequestAccessibilityButton); 1604 pw.append("]"); 1605 } 1606 } 1607 1608 /** 1609 * Called when the connection is first created. Add a window token for all known displays. 1610 * <p> 1611 * <strong>Note:</strong> Should not be called while holding the AccessibilityManagerService 1612 * lock because this calls out to WindowManagerService. 1613 */ addWindowTokensForAllDisplays()1614 void addWindowTokensForAllDisplays() { 1615 final Display[] displays = mDisplayManager.getDisplays(); 1616 for (int i = 0; i < displays.length; i++) { 1617 final int displayId = displays[i].getDisplayId(); 1618 addWindowTokenForDisplay(displayId); 1619 } 1620 } 1621 1622 /** 1623 * Called whenever a logical display has been added to the system. Add a window token for adding 1624 * an accessibility overlay. 1625 * 1626 * <p> 1627 * <strong>Note:</strong> Should not be called while holding the AccessibilityManagerService 1628 * lock because this calls out to WindowManagerService. 1629 * 1630 * @param displayId The id of the logical display that was added. 1631 */ addWindowTokenForDisplay(int displayId)1632 void addWindowTokenForDisplay(int displayId) { 1633 final long identity = Binder.clearCallingIdentity(); 1634 try { 1635 final IBinder overlayWindowToken = new Binder(); 1636 if (wmTracingEnabled()) { 1637 logTraceWM("addWindowToken", 1638 overlayWindowToken + ";TYPE_ACCESSIBILITY_OVERLAY;" + displayId + ";null"); 1639 } 1640 mWindowManagerService.addWindowToken(overlayWindowToken, TYPE_ACCESSIBILITY_OVERLAY, 1641 displayId, null /* options */); 1642 synchronized (mLock) { 1643 mOverlayWindowTokens.put(displayId, overlayWindowToken); 1644 } 1645 } finally { 1646 Binder.restoreCallingIdentity(identity); 1647 } 1648 } 1649 onRemoved()1650 public void onRemoved() { 1651 final Display[] displays = mDisplayManager.getDisplays(); 1652 for (int i = 0; i < displays.length; i++) { 1653 final int displayId = displays[i].getDisplayId(); 1654 onDisplayRemoved(displayId); 1655 } 1656 detachAllOverlays(); 1657 } 1658 1659 /** 1660 * Called whenever a logical display has been removed from the system. Remove a window token for 1661 * removing an accessibility overlay. 1662 * 1663 * @param displayId The id of the logical display that was added. 1664 */ onDisplayRemoved(int displayId)1665 public void onDisplayRemoved(int displayId) { 1666 final long identity = Binder.clearCallingIdentity(); 1667 if (wmTracingEnabled()) { 1668 logTraceWM( 1669 "addWindowToken", mOverlayWindowTokens.get(displayId) + ";true;" + displayId); 1670 } 1671 try { 1672 mWindowManagerService.removeWindowToken(mOverlayWindowTokens.get(displayId), true, 1673 displayId); 1674 synchronized (mLock) { 1675 mOverlayWindowTokens.remove(displayId); 1676 } 1677 } finally { 1678 Binder.restoreCallingIdentity(identity); 1679 } 1680 } 1681 1682 /** 1683 * Gets overlay window token by the display Id. 1684 * 1685 * @param displayId The id of the logical display that was added. 1686 * @return window token. 1687 */ 1688 @RequiresNoPermission 1689 @Override getOverlayWindowToken(int displayId)1690 public IBinder getOverlayWindowToken(int displayId) { 1691 if (svcConnTracingEnabled()) { 1692 logTraceSvcConn("getOverlayWindowToken", "displayId=" + displayId); 1693 } 1694 synchronized (mLock) { 1695 final long identity = Binder.clearCallingIdentity(); 1696 try { 1697 return mOverlayWindowTokens.get(displayId); 1698 } finally { 1699 Binder.restoreCallingIdentity(identity); 1700 } 1701 } 1702 } 1703 1704 /** 1705 * Gets windowId of given token. 1706 * 1707 * @param token The token 1708 * @return window id 1709 */ 1710 @RequiresNoPermission 1711 @Override getWindowIdForLeashToken(@onNull IBinder token)1712 public int getWindowIdForLeashToken(@NonNull IBinder token) { 1713 if (svcConnTracingEnabled()) { 1714 logTraceSvcConn("getWindowIdForLeashToken", "token=" + token); 1715 } 1716 synchronized (mLock) { 1717 final long identity = Binder.clearCallingIdentity(); 1718 try { 1719 return mA11yWindowManager.getWindowIdLocked(token); 1720 } finally { 1721 Binder.restoreCallingIdentity(identity); 1722 } 1723 } 1724 } 1725 resetLocked()1726 public void resetLocked() { 1727 mAccessibilityServiceInfo.resetDynamicallyConfigurableProperties(); 1728 mSystemSupport.getKeyEventDispatcher().flush(this); 1729 try { 1730 // Clear the proxy in the other process so this 1731 // IAccessibilityServiceConnection can be garbage collected. 1732 if (mServiceInterface != null) { 1733 if (svcClientTracingEnabled()) { 1734 logTraceSvcClient("init", "null, " + mId + ", null"); 1735 } 1736 mServiceInterface.init(null, mId, null); 1737 } 1738 } catch (RemoteException re) { 1739 /* ignore */ 1740 } 1741 if (mService != null) { 1742 try { 1743 mService.unlinkToDeath(this, 0); 1744 } catch (NoSuchElementException e) { 1745 Slog.e(LOG_TAG, "Failed unregistering death link"); 1746 } 1747 mService = null; 1748 } 1749 1750 mServiceInterface = null; 1751 mReceivedAccessibilityButtonCallbackSinceBind = false; 1752 } 1753 isConnectedLocked()1754 public boolean isConnectedLocked() { 1755 return (mService != null); 1756 } 1757 notifyAccessibilityEvent(AccessibilityEvent event)1758 public void notifyAccessibilityEvent(AccessibilityEvent event) { 1759 synchronized (mLock) { 1760 final int eventType = event.getEventType(); 1761 1762 final boolean serviceWantsEvent = wantsEventLocked(event); 1763 final boolean requiredForCacheConsistency = mUsesAccessibilityCache 1764 && ((AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK & eventType) != 0); 1765 if (!serviceWantsEvent && !requiredForCacheConsistency) { 1766 return; 1767 } 1768 1769 if (!mSecurityPolicy.checkAccessibilityAccess(this)) { 1770 return; 1771 } 1772 // Make a copy since during dispatch it is possible the event to 1773 // be modified to remove its source if the receiving service does 1774 // not have permission to access the window content. 1775 AccessibilityEvent newEvent = AccessibilityEvent.obtain(event); 1776 Message message; 1777 if ((mNotificationTimeout > 0) 1778 && (eventType != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)) { 1779 // Allow at most one pending event 1780 final AccessibilityEvent oldEvent = mPendingEvents.get(eventType); 1781 mPendingEvents.put(eventType, newEvent); 1782 if (oldEvent != null) { 1783 mEventDispatchHandler.removeMessages(eventType); 1784 oldEvent.recycle(); 1785 } 1786 message = mEventDispatchHandler.obtainMessage(eventType); 1787 } else { 1788 // Send all messages, bypassing mPendingEvents 1789 message = mEventDispatchHandler.obtainMessage(eventType, newEvent); 1790 } 1791 message.arg1 = serviceWantsEvent ? 1 : 0; 1792 1793 mEventDispatchHandler.sendMessageDelayed(message, mNotificationTimeout); 1794 } 1795 } 1796 1797 /** 1798 * Determines if given event can be dispatched to a service based on the package of the 1799 * event source. Specifically, a service is notified if it is interested in events from the 1800 * package. 1801 * 1802 * @param event The event. 1803 * @return True if the listener should be notified, false otherwise. 1804 */ wantsEventLocked(AccessibilityEvent event)1805 private boolean wantsEventLocked(AccessibilityEvent event) { 1806 1807 if (!canReceiveEventsLocked()) { 1808 return false; 1809 } 1810 1811 final boolean includeNotImportantViews = (mFetchFlags 1812 & AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_INCLUDE_NOT_IMPORTANT_VIEWS) != 0; 1813 if ((event.getWindowId() != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) 1814 && !event.isImportantForAccessibility() 1815 && !includeNotImportantViews) { 1816 return false; 1817 } 1818 1819 if (event.isAccessibilityDataSensitive() 1820 && (mFetchFlags & AccessibilityNodeInfo.FLAG_SERVICE_IS_ACCESSIBILITY_TOOL) == 0) { 1821 return false; 1822 } 1823 1824 int eventType = event.getEventType(); 1825 if ((mEventTypes & eventType) != eventType) { 1826 return false; 1827 } 1828 1829 Set<String> packageNames = mPackageNames; 1830 String packageName = (event.getPackageName() != null) 1831 ? event.getPackageName().toString() : null; 1832 1833 return (packageNames.isEmpty() || packageNames.contains(packageName)); 1834 } 1835 1836 /** 1837 * Notifies an accessibility service client for a scheduled event given the event type. 1838 * 1839 * @param eventType The type of the event to dispatch. 1840 */ notifyAccessibilityEventInternal( int eventType, AccessibilityEvent event, boolean serviceWantsEvent)1841 private void notifyAccessibilityEventInternal( 1842 int eventType, 1843 AccessibilityEvent event, 1844 boolean serviceWantsEvent) { 1845 IAccessibilityServiceClient listener; 1846 1847 synchronized (mLock) { 1848 listener = mServiceInterface; 1849 1850 // If the service died/was disabled while the message for dispatching 1851 // the accessibility event was propagating the listener may be null. 1852 if (listener == null) { 1853 return; 1854 } 1855 1856 // There are two ways we notify for events, throttled AND non-throttled. If we 1857 // are not throttling, then messages come with events, which we handle with 1858 // minimal fuss. 1859 if (event == null) { 1860 // We are throttling events, so we'll send the event for this type in 1861 // mPendingEvents as long as it it's null. It can only null due to a race 1862 // condition: 1863 // 1864 // 1) A binder thread calls notifyAccessibilityServiceDelayedLocked 1865 // which posts a message for dispatching an event and stores the event 1866 // in mPendingEvents. 1867 // 2) The message is pulled from the queue by the handler on the service 1868 // thread and this method is just about to acquire the lock. 1869 // 3) Another binder thread acquires the lock in notifyAccessibilityEvent 1870 // 4) notifyAccessibilityEvent recycles the event that this method was about 1871 // to process, replaces it with a new one, and posts a second message 1872 // 5) This method grabs the new event, processes it, and removes it from 1873 // mPendingEvents 1874 // 6) The second message dispatched in (4) arrives, but the event has been 1875 // remvoved in (5). 1876 event = mPendingEvents.get(eventType); 1877 if (event == null) { 1878 return; 1879 } 1880 mPendingEvents.remove(eventType); 1881 } 1882 if (mSecurityPolicy.canRetrieveWindowContentLocked(this)) { 1883 event.setConnectionId(mId); 1884 } else { 1885 event.setSource((View) null); 1886 } 1887 event.setSealed(true); 1888 } 1889 1890 try { 1891 if (svcClientTracingEnabled()) { 1892 logTraceSvcClient("onAccessibilityEvent", event + ";" + serviceWantsEvent); 1893 } 1894 listener.onAccessibilityEvent(event, serviceWantsEvent); 1895 if (DEBUG) { 1896 Slog.i(LOG_TAG, "Event " + event + " sent to " + listener); 1897 } 1898 } catch (RemoteException re) { 1899 Slog.e(LOG_TAG, "Error during sending " + event + " to " + listener, re); 1900 } finally { 1901 event.recycle(); 1902 } 1903 } 1904 notifyGesture(AccessibilityGestureEvent gestureEvent)1905 public void notifyGesture(AccessibilityGestureEvent gestureEvent) { 1906 if (android.view.accessibility.Flags.copyEventsForGestureDetection()) { 1907 // We will use this event async, so copy it because it contains MotionEvents. 1908 mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_GESTURE, 1909 gestureEvent.copyForAsync()).sendToTarget(); 1910 } else { 1911 mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_GESTURE, 1912 gestureEvent).sendToTarget(); 1913 } 1914 } 1915 notifySystemActionsChangedLocked()1916 public void notifySystemActionsChangedLocked() { 1917 mInvocationHandler.sendEmptyMessage( 1918 InvocationHandler.MSG_ON_SYSTEM_ACTIONS_CHANGED); 1919 } 1920 notifyClearAccessibilityNodeInfoCache()1921 public void notifyClearAccessibilityNodeInfoCache() { 1922 mInvocationHandler.sendEmptyMessage( 1923 InvocationHandler.MSG_CLEAR_ACCESSIBILITY_CACHE); 1924 } 1925 notifyMagnificationChangedLocked(int displayId, @NonNull Region region, @NonNull MagnificationConfig config)1926 public void notifyMagnificationChangedLocked(int displayId, @NonNull Region region, 1927 @NonNull MagnificationConfig config) { 1928 mInvocationHandler 1929 .notifyMagnificationChangedLocked(displayId, region, config); 1930 } 1931 notifySoftKeyboardShowModeChangedLocked(int showState)1932 public void notifySoftKeyboardShowModeChangedLocked(int showState) { 1933 mInvocationHandler.notifySoftKeyboardShowModeChangedLocked(showState); 1934 } 1935 notifyAccessibilityButtonClickedLocked(int displayId)1936 public void notifyAccessibilityButtonClickedLocked(int displayId) { 1937 mInvocationHandler.notifyAccessibilityButtonClickedLocked(displayId); 1938 } 1939 notifyAccessibilityButtonAvailabilityChangedLocked(boolean available)1940 public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) { 1941 mInvocationHandler.notifyAccessibilityButtonAvailabilityChangedLocked(available); 1942 } 1943 createImeSessionLocked()1944 public void createImeSessionLocked() { 1945 mInvocationHandler.createImeSessionLocked(); 1946 } 1947 setImeSessionEnabledLocked(IAccessibilityInputMethodSession session, boolean enabled)1948 public void setImeSessionEnabledLocked(IAccessibilityInputMethodSession session, 1949 boolean enabled) { 1950 mInvocationHandler.setImeSessionEnabledLocked(session, enabled); 1951 } 1952 bindInputLocked()1953 public void bindInputLocked() { 1954 mInvocationHandler.bindInputLocked(); 1955 } 1956 unbindInputLocked()1957 public void unbindInputLocked() { 1958 mInvocationHandler.unbindInputLocked(); 1959 } 1960 startInputLocked(IRemoteAccessibilityInputConnection connection, EditorInfo editorInfo, boolean restarting)1961 public void startInputLocked(IRemoteAccessibilityInputConnection connection, 1962 EditorInfo editorInfo, boolean restarting) { 1963 mInvocationHandler.startInputLocked(connection, editorInfo, restarting); 1964 } 1965 1966 @Nullable getWindowTransformationMatrixAndMagnificationSpec( int resolvedWindowId)1967 private Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec( 1968 int resolvedWindowId) { 1969 return mSystemSupport.getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId); 1970 } 1971 wantsGenericMotionEvent(MotionEvent event)1972 public boolean wantsGenericMotionEvent(MotionEvent event) { 1973 final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK; 1974 return (mGenericMotionEventSources & eventSourceWithoutClass) != 0; 1975 } 1976 1977 1978 /** 1979 * Called by the invocation handler to notify the service that the 1980 * state of magnification has changed. 1981 */ notifyMagnificationChangedInternal(int displayId, @NonNull Region region, @NonNull MagnificationConfig config)1982 private void notifyMagnificationChangedInternal(int displayId, @NonNull Region region, 1983 @NonNull MagnificationConfig config) { 1984 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 1985 if (listener != null) { 1986 try { 1987 if (svcClientTracingEnabled()) { 1988 logTraceSvcClient("onMagnificationChanged", displayId + ", " + region + ", " 1989 + config.toString()); 1990 } 1991 listener.onMagnificationChanged(displayId, region, config); 1992 } catch (RemoteException re) { 1993 Slog.e(LOG_TAG, "Error sending magnification changes to " + mService, re); 1994 } 1995 } 1996 } 1997 1998 /** 1999 * Called by the invocation handler to notify the service that the state of the soft 2000 * keyboard show mode has changed. 2001 */ notifySoftKeyboardShowModeChangedInternal(int showState)2002 private void notifySoftKeyboardShowModeChangedInternal(int showState) { 2003 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2004 if (listener != null) { 2005 try { 2006 if (svcClientTracingEnabled()) { 2007 logTraceSvcClient("onSoftKeyboardShowModeChanged", String.valueOf(showState)); 2008 } 2009 listener.onSoftKeyboardShowModeChanged(showState); 2010 } catch (RemoteException re) { 2011 Slog.e(LOG_TAG, "Error sending soft keyboard show mode changes to " + mService, 2012 re); 2013 } 2014 } 2015 } 2016 notifyAccessibilityButtonClickedInternal(int displayId)2017 private void notifyAccessibilityButtonClickedInternal(int displayId) { 2018 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2019 if (listener != null) { 2020 try { 2021 if (svcClientTracingEnabled()) { 2022 logTraceSvcClient("onAccessibilityButtonClicked", String.valueOf(displayId)); 2023 } 2024 listener.onAccessibilityButtonClicked(displayId); 2025 } catch (RemoteException re) { 2026 Slog.e(LOG_TAG, "Error sending accessibility button click to " + mService, re); 2027 } 2028 } 2029 } 2030 notifyAccessibilityButtonAvailabilityChangedInternal(boolean available)2031 private void notifyAccessibilityButtonAvailabilityChangedInternal(boolean available) { 2032 // Only notify the service if it's not been notified or the state has changed 2033 if (mReceivedAccessibilityButtonCallbackSinceBind 2034 && (mLastAccessibilityButtonCallbackState == available)) { 2035 return; 2036 } 2037 mReceivedAccessibilityButtonCallbackSinceBind = true; 2038 mLastAccessibilityButtonCallbackState = available; 2039 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2040 if (listener != null) { 2041 try { 2042 if (svcClientTracingEnabled()) { 2043 logTraceSvcClient("onAccessibilityButtonAvailabilityChanged", 2044 String.valueOf(available)); 2045 } 2046 listener.onAccessibilityButtonAvailabilityChanged(available); 2047 } catch (RemoteException re) { 2048 Slog.e(LOG_TAG, 2049 "Error sending accessibility button availability change to " + mService, 2050 re); 2051 } 2052 } 2053 } 2054 notifyGestureInternal(AccessibilityGestureEvent gestureInfo)2055 private void notifyGestureInternal(AccessibilityGestureEvent gestureInfo) { 2056 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2057 if (listener != null) { 2058 try { 2059 if (svcClientTracingEnabled()) { 2060 logTraceSvcClient("onGesture", gestureInfo.toString()); 2061 } 2062 listener.onGesture(gestureInfo); 2063 } catch (RemoteException re) { 2064 Slog.e(LOG_TAG, "Error during sending gesture " + gestureInfo 2065 + " to " + mService, re); 2066 } 2067 } 2068 } 2069 notifySystemActionsChangedInternal()2070 private void notifySystemActionsChangedInternal() { 2071 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2072 if (listener != null) { 2073 try { 2074 if (svcClientTracingEnabled()) { 2075 logTraceSvcClient("onSystemActionsChanged", ""); 2076 } 2077 listener.onSystemActionsChanged(); 2078 } catch (RemoteException re) { 2079 Slog.e(LOG_TAG, "Error sending system actions change to " + mService, 2080 re); 2081 } 2082 } 2083 } 2084 notifyClearAccessibilityCacheInternal()2085 private void notifyClearAccessibilityCacheInternal() { 2086 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2087 if (listener != null) { 2088 try { 2089 if (svcClientTracingEnabled()) { 2090 logTraceSvcClient("clearAccessibilityCache", ""); 2091 } 2092 listener.clearAccessibilityCache(); 2093 } catch (RemoteException re) { 2094 Slog.e(LOG_TAG, "Error during requesting accessibility info cache" 2095 + " to be cleared.", re); 2096 } 2097 } 2098 } 2099 createImeSessionInternal()2100 protected void createImeSessionInternal() { 2101 } 2102 setImeSessionEnabledInternal(IAccessibilityInputMethodSession session, boolean enabled)2103 private void setImeSessionEnabledInternal(IAccessibilityInputMethodSession session, 2104 boolean enabled) { 2105 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2106 if (listener != null && session != null) { 2107 try { 2108 if (svcClientTracingEnabled()) { 2109 logTraceSvcClient("createImeSession", ""); 2110 } 2111 listener.setImeSessionEnabled(session, enabled); 2112 } catch (RemoteException re) { 2113 Slog.e(LOG_TAG, 2114 "Error requesting IME session from " + mService, re); 2115 } 2116 } 2117 } 2118 bindInputInternal()2119 private void bindInputInternal() { 2120 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2121 if (listener != null) { 2122 try { 2123 if (svcClientTracingEnabled()) { 2124 logTraceSvcClient("bindInput", ""); 2125 } 2126 listener.bindInput(); 2127 } catch (RemoteException re) { 2128 Slog.e(LOG_TAG, 2129 "Error binding input to " + mService, re); 2130 } 2131 } 2132 } 2133 unbindInputInternal()2134 private void unbindInputInternal() { 2135 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2136 if (listener != null) { 2137 try { 2138 if (svcClientTracingEnabled()) { 2139 logTraceSvcClient("unbindInput", ""); 2140 } 2141 listener.unbindInput(); 2142 } catch (RemoteException re) { 2143 Slog.e(LOG_TAG, 2144 "Error unbinding input to " + mService, re); 2145 } 2146 } 2147 } 2148 startInputInternal(IRemoteAccessibilityInputConnection connection, EditorInfo editorInfo, boolean restarting)2149 private void startInputInternal(IRemoteAccessibilityInputConnection connection, 2150 EditorInfo editorInfo, boolean restarting) { 2151 final IAccessibilityServiceClient listener = getServiceInterfaceSafely(); 2152 if (listener != null) { 2153 try { 2154 if (svcClientTracingEnabled()) { 2155 logTraceSvcClient("startInput", "editorInfo=" + editorInfo 2156 + " restarting=" + restarting); 2157 } 2158 listener.startInput(connection, editorInfo, restarting); 2159 } catch (RemoteException re) { 2160 Slog.e(LOG_TAG, 2161 "Error starting input to " + mService, re); 2162 } 2163 } 2164 } 2165 getServiceInterfaceSafely()2166 protected IAccessibilityServiceClient getServiceInterfaceSafely() { 2167 synchronized (mLock) { 2168 return mServiceInterface; 2169 } 2170 } 2171 resolveAccessibilityWindowIdLocked(int accessibilityWindowId)2172 private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) { 2173 if (accessibilityWindowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) { 2174 final int focusedWindowId = 2175 mA11yWindowManager.getActiveWindowId(mSystemSupport.getCurrentUserIdLocked()); 2176 if (!mA11yWindowManager.windowIdBelongsToDisplayType(focusedWindowId, mDisplayTypes)) { 2177 return AccessibilityWindowInfo.UNDEFINED_WINDOW_ID; 2178 } 2179 return focusedWindowId; 2180 } 2181 return accessibilityWindowId; 2182 } 2183 resolveAccessibilityWindowIdForFindFocusLocked(int windowId, int focusType)2184 int resolveAccessibilityWindowIdForFindFocusLocked(int windowId, int focusType) { 2185 if (windowId == AccessibilityWindowInfo.ANY_WINDOW_ID) { 2186 final int focusedWindowId = mA11yWindowManager.getFocusedWindowId(focusType); 2187 // If the caller is a proxy and the found window doesn't belong to a proxy display 2188 // (or vice versa), then return null. This doesn't work if there are multiple active 2189 // proxys, but in the future this code shouldn't be needed if input focus are 2190 // properly split. (so we will deal with the issues if we see them). 2191 //TODO(254545943): Remove this when there is user and proxy separation of input focus 2192 if (!mA11yWindowManager.windowIdBelongsToDisplayType(focusedWindowId, mDisplayTypes)) { 2193 return AccessibilityWindowInfo.UNDEFINED_WINDOW_ID; 2194 } 2195 return focusedWindowId; 2196 } 2197 return windowId; 2198 } 2199 2200 /** 2201 * Request that the system make sure windows are available to interrogate. 2202 * 2203 * @param displayId The logical display id. 2204 */ ensureWindowsAvailableTimedLocked(int displayId)2205 private void ensureWindowsAvailableTimedLocked(int displayId) { 2206 if (displayId == Display.INVALID_DISPLAY) { 2207 return; 2208 } 2209 2210 if (mA11yWindowManager.getWindowListLocked(displayId) != null) { 2211 return; 2212 } 2213 // If we have no registered callback, update the state we 2214 // we may have to register one but it didn't happen yet. 2215 if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) { 2216 // Invokes client change to make sure tracking window enabled. 2217 mSystemSupport.onClientChangeLocked(false); 2218 } 2219 // We have no windows but do not care about them, done. 2220 if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) { 2221 return; 2222 } 2223 2224 // Wait for the windows with a timeout. 2225 final long startMillis = SystemClock.uptimeMillis(); 2226 while (mA11yWindowManager.getWindowListLocked(displayId) == null) { 2227 final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; 2228 final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis; 2229 if (remainMillis <= 0) { 2230 return; 2231 } 2232 try { 2233 mLock.wait(remainMillis); 2234 } catch (InterruptedException ie) { 2235 /* ignore */ 2236 } 2237 } 2238 } 2239 2240 /** 2241 * Perform the specified accessibility action 2242 * 2243 * @param resolvedWindowId The window ID 2244 * [Other parameters match the method on IAccessibilityServiceConnection] 2245 * 2246 * @return Whether or not the action could be sent to the app process 2247 */ performAccessibilityActionInternal(int userId, int resolvedWindowId, long accessibilityNodeId, int action, Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, int fetchFlags, long interrogatingTid)2248 private boolean performAccessibilityActionInternal(int userId, int resolvedWindowId, 2249 long accessibilityNodeId, int action, Bundle arguments, int interactionId, 2250 IAccessibilityInteractionConnectionCallback callback, int fetchFlags, 2251 long interrogatingTid) { 2252 RemoteAccessibilityConnection connection; 2253 IBinder windowToken = null; 2254 synchronized (mLock) { 2255 connection = mA11yWindowManager.getConnectionLocked(userId, resolvedWindowId); 2256 if (connection == null) { 2257 return false; 2258 } 2259 final boolean isA11yFocusAction = (action == ACTION_ACCESSIBILITY_FOCUS) 2260 || (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS); 2261 if (!isA11yFocusAction) { 2262 windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked( 2263 userId, resolvedWindowId); 2264 } 2265 final AccessibilityWindowInfo a11yWindowInfo = 2266 mA11yWindowManager.findA11yWindowInfoByIdLocked(resolvedWindowId); 2267 if (a11yWindowInfo != null && a11yWindowInfo.isInPictureInPictureMode() 2268 && mA11yWindowManager.getPictureInPictureActionReplacingConnection() != null 2269 && !isA11yFocusAction) { 2270 connection = mA11yWindowManager.getPictureInPictureActionReplacingConnection(); 2271 } 2272 } 2273 final int interrogatingPid = Binder.getCallingPid(); 2274 final long identityToken = Binder.clearCallingIdentity(); 2275 try { 2276 // Regardless of whether or not the action succeeds, it was generated by an 2277 // accessibility service that is driven by user actions, so note user activity. 2278 mPowerManager.userActivity(SystemClock.uptimeMillis(), 2279 PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY, 0); 2280 2281 if (action == ACTION_CLICK || action == ACTION_LONG_CLICK) { 2282 mA11yWindowManager.notifyOutsideTouch(userId, resolvedWindowId); 2283 } 2284 if (windowToken != null) { 2285 mWindowManagerService.requestWindowFocus(windowToken); 2286 } 2287 if (intConnTracingEnabled()) { 2288 logTraceIntConn("performAccessibilityAction", 2289 accessibilityNodeId + ";" + action + ";" + arguments + ";" + interactionId 2290 + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid + ";" 2291 + interrogatingTid); 2292 } 2293 connection.getRemote().performAccessibilityAction(accessibilityNodeId, action, 2294 arguments, interactionId, callback, fetchFlags, interrogatingPid, 2295 interrogatingTid); 2296 } catch (RemoteException re) { 2297 if (DEBUG) { 2298 Slog.e(LOG_TAG, "Error calling performAccessibilityAction: " + re); 2299 } 2300 return false; 2301 } finally { 2302 Binder.restoreCallingIdentity(identityToken); 2303 } 2304 return true; 2305 } 2306 2307 /** 2308 * Replace the interaction callback if needed, for example if the window is in picture- 2309 * in-picture mode and needs its nodes replaced. 2310 * 2311 * @param originalCallback The callback we were planning to use 2312 * @param resolvedWindowId The ID of the window we're calling 2313 * @param interactionId The id for the original callback 2314 * @param interrogatingPid Process ID of requester 2315 * @param interrogatingTid Thread ID of requester 2316 * 2317 * @return The callback to use, which may be the original one. 2318 */ replaceCallbackIfNeeded( IAccessibilityInteractionConnectionCallback originalCallback, int resolvedWindowId, int interactionId, int interrogatingPid, long interrogatingTid)2319 private IAccessibilityInteractionConnectionCallback replaceCallbackIfNeeded( 2320 IAccessibilityInteractionConnectionCallback originalCallback, int resolvedWindowId, 2321 int interactionId, int interrogatingPid, long interrogatingTid) { 2322 final RemoteAccessibilityConnection pipActionReplacingConnection = 2323 mA11yWindowManager.getPictureInPictureActionReplacingConnection(); 2324 synchronized (mLock) { 2325 final AccessibilityWindowInfo windowInfo = 2326 mA11yWindowManager.findA11yWindowInfoByIdLocked(resolvedWindowId); 2327 if ((windowInfo == null) || !windowInfo.isInPictureInPictureMode() 2328 || (pipActionReplacingConnection == null)) { 2329 return originalCallback; 2330 } 2331 } 2332 return new ActionReplacingCallback(originalCallback, 2333 pipActionReplacingConnection.getRemote(), interactionId, 2334 interrogatingPid, interrogatingTid); 2335 } 2336 getWindowsByDisplayLocked(int displayId)2337 private List<AccessibilityWindowInfo> getWindowsByDisplayLocked(int displayId) { 2338 final List<AccessibilityWindowInfo> internalWindowList = 2339 mA11yWindowManager.getWindowListLocked(displayId); 2340 if (internalWindowList == null) { 2341 return null; 2342 } 2343 final List<AccessibilityWindowInfo> returnedWindowList = new ArrayList<>(); 2344 final int windowCount = internalWindowList.size(); 2345 for (int i = 0; i < windowCount; i++) { 2346 AccessibilityWindowInfo window = internalWindowList.get(i); 2347 AccessibilityWindowInfo windowClone = 2348 AccessibilityWindowInfo.obtain(window); 2349 windowClone.setConnectionId(mId); 2350 returnedWindowList.add(windowClone); 2351 } 2352 return returnedWindowList; 2353 } 2354 getComponentName()2355 public ComponentName getComponentName() { 2356 return mComponentName; 2357 } 2358 2359 private final class InvocationHandler extends Handler { 2360 public static final int MSG_ON_GESTURE = 1; 2361 public static final int MSG_CLEAR_ACCESSIBILITY_CACHE = 2; 2362 2363 private static final int MSG_ON_MAGNIFICATION_CHANGED = 5; 2364 private static final int MSG_ON_SOFT_KEYBOARD_STATE_CHANGED = 6; 2365 private static final int MSG_ON_ACCESSIBILITY_BUTTON_CLICKED = 7; 2366 private static final int MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 8; 2367 private static final int MSG_ON_SYSTEM_ACTIONS_CHANGED = 9; 2368 private static final int MSG_CREATE_IME_SESSION = 10; 2369 private static final int MSG_SET_IME_SESSION_ENABLED = 11; 2370 private static final int MSG_BIND_INPUT = 12; 2371 private static final int MSG_UNBIND_INPUT = 13; 2372 private static final int MSG_START_INPUT = 14; 2373 2374 /** List of magnification callback states, mapping from displayId -> Boolean */ 2375 @GuardedBy("mlock") 2376 private final SparseArray<Boolean> mMagnificationCallbackState = new SparseArray<>(0); 2377 private boolean mIsSoftKeyboardCallbackEnabled = false; 2378 InvocationHandler(Looper looper)2379 public InvocationHandler(Looper looper) { 2380 super(looper, null, true); 2381 } 2382 2383 @Override handleMessage(Message message)2384 public void handleMessage(Message message) { 2385 final int type = message.what; 2386 switch (type) { 2387 case MSG_ON_GESTURE: { 2388 if (message.obj instanceof AccessibilityGestureEvent gesture) { 2389 notifyGestureInternal(gesture); 2390 if (android.view.accessibility.Flags.copyEventsForGestureDetection()) { 2391 gesture.recycle(); 2392 } 2393 } 2394 } break; 2395 case MSG_CLEAR_ACCESSIBILITY_CACHE: { 2396 notifyClearAccessibilityCacheInternal(); 2397 } break; 2398 2399 case MSG_ON_MAGNIFICATION_CHANGED: { 2400 final SomeArgs args = (SomeArgs) message.obj; 2401 final Region region = (Region) args.arg1; 2402 final MagnificationConfig config = (MagnificationConfig) args.arg2; 2403 final int displayId = args.argi1; 2404 notifyMagnificationChangedInternal(displayId, region, config); 2405 args.recycle(); 2406 } break; 2407 2408 case MSG_ON_SOFT_KEYBOARD_STATE_CHANGED: { 2409 final int showState = (int) message.arg1; 2410 notifySoftKeyboardShowModeChangedInternal(showState); 2411 } break; 2412 2413 case MSG_ON_ACCESSIBILITY_BUTTON_CLICKED: { 2414 final int displayId = (int) message.arg1; 2415 notifyAccessibilityButtonClickedInternal(displayId); 2416 } break; 2417 2418 case MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED: { 2419 final boolean available = (message.arg1 != 0); 2420 notifyAccessibilityButtonAvailabilityChangedInternal(available); 2421 } break; 2422 case MSG_ON_SYSTEM_ACTIONS_CHANGED: { 2423 notifySystemActionsChangedInternal(); 2424 break; 2425 } 2426 case MSG_CREATE_IME_SESSION: 2427 createImeSessionInternal(); 2428 break; 2429 case MSG_SET_IME_SESSION_ENABLED: 2430 final boolean enabled = (message.arg1 != 0); 2431 final IAccessibilityInputMethodSession session = 2432 (IAccessibilityInputMethodSession) message.obj; 2433 setImeSessionEnabledInternal(session, enabled); 2434 break; 2435 case MSG_BIND_INPUT: 2436 bindInputInternal(); 2437 break; 2438 case MSG_UNBIND_INPUT: 2439 unbindInputInternal(); 2440 break; 2441 case MSG_START_INPUT: 2442 final boolean restarting = (message.arg1 != 0); 2443 final SomeArgs args = (SomeArgs) message.obj; 2444 final IRemoteAccessibilityInputConnection connection = 2445 (IRemoteAccessibilityInputConnection) args.arg1; 2446 final EditorInfo editorInfo = (EditorInfo) args.arg2; 2447 startInputInternal(connection, editorInfo, restarting); 2448 args.recycle(); 2449 break; 2450 default: { 2451 throw new IllegalArgumentException("Unknown message: " + type); 2452 } 2453 } 2454 } 2455 notifyMagnificationChangedLocked(int displayId, @NonNull Region region, @NonNull MagnificationConfig config)2456 public void notifyMagnificationChangedLocked(int displayId, @NonNull Region region, 2457 @NonNull MagnificationConfig config) { 2458 synchronized (mLock) { 2459 if (mMagnificationCallbackState.get(displayId) == null) { 2460 return; 2461 } 2462 } 2463 2464 final SomeArgs args = SomeArgs.obtain(); 2465 args.arg1 = region; 2466 args.arg2 = config; 2467 args.argi1 = displayId; 2468 2469 final Message msg = obtainMessage(MSG_ON_MAGNIFICATION_CHANGED, args); 2470 msg.sendToTarget(); 2471 } 2472 setMagnificationCallbackEnabled(int displayId, boolean enabled)2473 public void setMagnificationCallbackEnabled(int displayId, boolean enabled) { 2474 synchronized (mLock) { 2475 if (enabled) { 2476 mMagnificationCallbackState.put(displayId, true); 2477 } else { 2478 mMagnificationCallbackState.remove(displayId); 2479 } 2480 } 2481 } 2482 isMagnificationCallbackEnabled(int displayId)2483 public boolean isMagnificationCallbackEnabled(int displayId) { 2484 synchronized (mLock) { 2485 return mMagnificationCallbackState.get(displayId) != null; 2486 } 2487 } 2488 notifySoftKeyboardShowModeChangedLocked(int showState)2489 public void notifySoftKeyboardShowModeChangedLocked(int showState) { 2490 if (!mIsSoftKeyboardCallbackEnabled) { 2491 return; 2492 } 2493 2494 final Message msg = obtainMessage(MSG_ON_SOFT_KEYBOARD_STATE_CHANGED, showState, 0); 2495 msg.sendToTarget(); 2496 } 2497 setSoftKeyboardCallbackEnabled(boolean enabled)2498 public void setSoftKeyboardCallbackEnabled(boolean enabled) { 2499 mIsSoftKeyboardCallbackEnabled = enabled; 2500 } 2501 notifyAccessibilityButtonClickedLocked(int displayId)2502 public void notifyAccessibilityButtonClickedLocked(int displayId) { 2503 final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_CLICKED, displayId, 0); 2504 msg.sendToTarget(); 2505 } 2506 notifyAccessibilityButtonAvailabilityChangedLocked(boolean available)2507 public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) { 2508 final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED, 2509 (available ? 1 : 0), 0); 2510 msg.sendToTarget(); 2511 } 2512 createImeSessionLocked()2513 public void createImeSessionLocked() { 2514 final Message msg = obtainMessage(MSG_CREATE_IME_SESSION); 2515 msg.sendToTarget(); 2516 } 2517 setImeSessionEnabledLocked(IAccessibilityInputMethodSession session, boolean enabled)2518 public void setImeSessionEnabledLocked(IAccessibilityInputMethodSession session, 2519 boolean enabled) { 2520 final Message msg = obtainMessage(MSG_SET_IME_SESSION_ENABLED, (enabled ? 1 : 0), 2521 0, session); 2522 msg.sendToTarget(); 2523 } 2524 bindInputLocked()2525 public void bindInputLocked() { 2526 final Message msg = obtainMessage(MSG_BIND_INPUT); 2527 msg.sendToTarget(); 2528 } 2529 unbindInputLocked()2530 public void unbindInputLocked() { 2531 final Message msg = obtainMessage(MSG_UNBIND_INPUT); 2532 msg.sendToTarget(); 2533 } 2534 startInputLocked( IRemoteAccessibilityInputConnection connection, EditorInfo editorInfo, boolean restarting)2535 public void startInputLocked( 2536 IRemoteAccessibilityInputConnection connection, 2537 EditorInfo editorInfo, boolean restarting) { 2538 final SomeArgs args = SomeArgs.obtain(); 2539 args.arg1 = connection; 2540 args.arg2 = editorInfo; 2541 final Message msg = obtainMessage(MSG_START_INPUT, restarting ? 1 : 0, 0, args); 2542 msg.sendToTarget(); 2543 } 2544 } 2545 isServiceHandlesDoubleTapEnabled()2546 public boolean isServiceHandlesDoubleTapEnabled() { 2547 return mServiceHandlesDoubleTap; 2548 } 2549 isMultiFingerGesturesEnabled()2550 public boolean isMultiFingerGesturesEnabled() { 2551 return mRequestMultiFingerGestures; 2552 } 2553 isTwoFingerPassthroughEnabled()2554 public boolean isTwoFingerPassthroughEnabled() { 2555 return mRequestTwoFingerPassthrough; 2556 } 2557 isSendMotionEventsEnabled()2558 public boolean isSendMotionEventsEnabled() { 2559 return mSendMotionEvents; 2560 } 2561 2562 @RequiresNoPermission 2563 @Override setGestureDetectionPassthroughRegion(int displayId, Region region)2564 public void setGestureDetectionPassthroughRegion(int displayId, Region region) { 2565 if (svcConnTracingEnabled()) { 2566 logTraceSvcConn("setGestureDetectionPassthroughRegion", 2567 "displayId=" + displayId + ";region=" + region); 2568 } 2569 final long identity = Binder.clearCallingIdentity(); 2570 try { 2571 mSystemSupport.setGestureDetectionPassthroughRegion(displayId, region); 2572 } finally { 2573 Binder.restoreCallingIdentity(identity); 2574 } 2575 } 2576 2577 @RequiresNoPermission 2578 @Override setTouchExplorationPassthroughRegion(int displayId, Region region)2579 public void setTouchExplorationPassthroughRegion(int displayId, Region region) { 2580 if (svcConnTracingEnabled()) { 2581 logTraceSvcConn("setTouchExplorationPassthroughRegion", 2582 "displayId=" + displayId + ";region=" + region); 2583 } 2584 final long identity = Binder.clearCallingIdentity(); 2585 try { 2586 mSystemSupport.setTouchExplorationPassthroughRegion(displayId, region); 2587 } finally { 2588 Binder.restoreCallingIdentity(identity); 2589 } 2590 } 2591 2592 @RequiresNoPermission 2593 @Override setFocusAppearance(int strokeWidth, int color)2594 public void setFocusAppearance(int strokeWidth, int color) { 2595 if (svcConnTracingEnabled()) { 2596 logTraceSvcConn("setFocusAppearance", "strokeWidth=" + strokeWidth + ";color=" + color); 2597 } 2598 } 2599 2600 @RequiresNoPermission 2601 @Override setCacheEnabled(boolean enabled)2602 public void setCacheEnabled(boolean enabled) { 2603 if (svcConnTracingEnabled()) { 2604 logTraceSvcConn("setCacheEnabled", "enabled=" + enabled); 2605 } 2606 final long identity = Binder.clearCallingIdentity(); 2607 try { 2608 synchronized (mLock) { 2609 mUsesAccessibilityCache = enabled; 2610 mSystemSupport.onClientChangeLocked(true); 2611 } 2612 } finally { 2613 Binder.restoreCallingIdentity(identity); 2614 } 2615 } 2616 2617 @RequiresNoPermission 2618 @Override logTrace(long timestamp, String where, long loggingTypes, String callingParams, int processId, long threadId, int callingUid, Bundle callingStack)2619 public void logTrace(long timestamp, String where, long loggingTypes, String callingParams, 2620 int processId, long threadId, int callingUid, Bundle callingStack) { 2621 final long identity = Binder.clearCallingIdentity(); 2622 try { 2623 if (mTrace.isA11yTracingEnabledForTypes(loggingTypes)) { 2624 ArrayList<StackTraceElement> list = 2625 (ArrayList<StackTraceElement>) callingStack.getSerializable(CALL_STACK, 2626 java.util.ArrayList.class); 2627 HashSet<String> ignoreList = 2628 (HashSet<String>) callingStack.getSerializable(IGNORE_CALL_STACK, 2629 java.util.HashSet.class); 2630 mTrace.logTrace(timestamp, where, loggingTypes, callingParams, processId, threadId, 2631 callingUid, list.toArray(new StackTraceElement[list.size()]), ignoreList); 2632 } 2633 } finally { 2634 Binder.restoreCallingIdentity(identity); 2635 } 2636 } 2637 svcClientTracingEnabled()2638 protected boolean svcClientTracingEnabled() { 2639 return mTrace.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_SERVICE_CLIENT); 2640 } 2641 logTraceSvcClient(String methodName, String params)2642 protected void logTraceSvcClient(String methodName, String params) { 2643 mTrace.logTrace(TRACE_SVC_CLIENT + "." + methodName, 2644 FLAGS_ACCESSIBILITY_SERVICE_CLIENT, params); 2645 } 2646 svcConnTracingEnabled()2647 protected boolean svcConnTracingEnabled() { 2648 return mTrace.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_SERVICE_CONNECTION); 2649 } 2650 logTraceSvcConn(String methodName, String params)2651 protected void logTraceSvcConn(String methodName, String params) { 2652 mTrace.logTrace(TRACE_SVC_CONN + "." + methodName, 2653 FLAGS_ACCESSIBILITY_SERVICE_CONNECTION, params); 2654 } 2655 intConnTracingEnabled()2656 protected boolean intConnTracingEnabled() { 2657 return mTrace.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION); 2658 } 2659 logTraceIntConn(String methodName, String params)2660 protected void logTraceIntConn(String methodName, String params) { 2661 mTrace.logTrace(LOG_TAG + "." + methodName, 2662 FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION, params); 2663 } 2664 wmTracingEnabled()2665 protected boolean wmTracingEnabled() { 2666 return mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MANAGER_INTERNAL); 2667 } 2668 logTraceWM(String methodName, String params)2669 protected void logTraceWM(String methodName, String params) { 2670 mTrace.logTrace(TRACE_WM + "." + methodName, FLAGS_WINDOW_MANAGER_INTERNAL, params); 2671 } 2672 2673 @RequiresNoPermission 2674 @Override setServiceDetectsGesturesEnabled(int displayId, boolean mode)2675 public void setServiceDetectsGesturesEnabled(int displayId, boolean mode) { 2676 final long identity = Binder.clearCallingIdentity(); 2677 try { 2678 mServiceDetectsGestures.put(displayId, mode); 2679 mSystemSupport.setServiceDetectsGesturesEnabled(displayId, mode); 2680 } finally { 2681 Binder.restoreCallingIdentity(identity); 2682 } 2683 } 2684 isServiceDetectsGesturesEnabled(int displayId)2685 public boolean isServiceDetectsGesturesEnabled(int displayId) { 2686 if (mServiceDetectsGestures.contains(displayId)) { 2687 return mServiceDetectsGestures.get(displayId); 2688 } 2689 return false; 2690 } 2691 2692 @RequiresNoPermission 2693 @Override requestTouchExploration(int displayId)2694 public void requestTouchExploration(int displayId) { 2695 final long identity = Binder.clearCallingIdentity(); 2696 try { 2697 mSystemSupport.requestTouchExploration(displayId); 2698 } finally { 2699 Binder.restoreCallingIdentity(identity); 2700 } 2701 } 2702 2703 @RequiresNoPermission 2704 @Override requestDragging(int displayId, int pointerId)2705 public void requestDragging(int displayId, int pointerId) { 2706 final long identity = Binder.clearCallingIdentity(); 2707 try { 2708 mSystemSupport.requestDragging(displayId, pointerId); 2709 } finally { 2710 Binder.restoreCallingIdentity(identity); 2711 } 2712 } 2713 2714 @RequiresNoPermission 2715 @Override requestDelegating(int displayId)2716 public void requestDelegating(int displayId) { 2717 final long identity = Binder.clearCallingIdentity(); 2718 try { 2719 mSystemSupport.requestDelegating(displayId); 2720 } finally { 2721 Binder.restoreCallingIdentity(identity); 2722 } 2723 } 2724 2725 @RequiresNoPermission 2726 @Override onDoubleTap(int displayId)2727 public void onDoubleTap(int displayId) { 2728 final long identity = Binder.clearCallingIdentity(); 2729 try { 2730 mSystemSupport.onDoubleTap(displayId); 2731 } finally { 2732 Binder.restoreCallingIdentity(identity); 2733 } 2734 } 2735 2736 @RequiresNoPermission 2737 @Override onDoubleTapAndHold(int displayId)2738 public void onDoubleTapAndHold(int displayId) { 2739 final long identity = Binder.clearCallingIdentity(); 2740 try { 2741 mSystemSupport.onDoubleTapAndHold(displayId); 2742 } finally { 2743 Binder.restoreCallingIdentity(identity); 2744 } 2745 } 2746 2747 /** 2748 * Sets the scaling factor for animations. 2749 */ 2750 @RequiresNoPermission 2751 @Override setAnimationScale(float scale)2752 public void setAnimationScale(float scale) { 2753 final long identity = Binder.clearCallingIdentity(); 2754 try { 2755 Settings.Global.putFloat( 2756 mContext.getContentResolver(), Settings.Global.WINDOW_ANIMATION_SCALE, scale); 2757 Settings.Global.putFloat( 2758 mContext.getContentResolver(), 2759 Settings.Global.TRANSITION_ANIMATION_SCALE, 2760 scale); 2761 Settings.Global.putFloat( 2762 mContext.getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, scale); 2763 } finally { 2764 Binder.restoreCallingIdentity(identity); 2765 } 2766 } 2767 2768 @RequiresNoPermission 2769 @Override attachAccessibilityOverlayToDisplay( int interactionId, int displayId, SurfaceControl sc, IAccessibilityInteractionConnectionCallback callback)2770 public void attachAccessibilityOverlayToDisplay( 2771 int interactionId, 2772 int displayId, 2773 SurfaceControl sc, 2774 IAccessibilityInteractionConnectionCallback callback) { 2775 final long identity = Binder.clearCallingIdentity(); 2776 try { 2777 mSystemSupport.attachAccessibilityOverlayToDisplay( 2778 interactionId, displayId, sc, callback); 2779 mOverlays.add(sc); 2780 } finally { 2781 Binder.restoreCallingIdentity(identity); 2782 } 2783 } 2784 2785 @RequiresNoPermission 2786 @Override attachAccessibilityOverlayToWindow( int interactionId, int accessibilityWindowId, SurfaceControl sc, IAccessibilityInteractionConnectionCallback callback)2787 public void attachAccessibilityOverlayToWindow( 2788 int interactionId, 2789 int accessibilityWindowId, 2790 SurfaceControl sc, 2791 IAccessibilityInteractionConnectionCallback callback) 2792 throws RemoteException { 2793 final long identity = Binder.clearCallingIdentity(); 2794 try { 2795 SurfaceControl.Transaction t = new SurfaceControl.Transaction(); 2796 t.setTrustedOverlay(sc, true).apply(); 2797 t.close(); 2798 synchronized (mLock) { 2799 RemoteAccessibilityConnection connection = 2800 mA11yWindowManager.getConnectionLocked( 2801 mSystemSupport.getCurrentUserIdLocked(), 2802 resolveAccessibilityWindowIdLocked(accessibilityWindowId)); 2803 if (connection == null) { 2804 callback.sendAttachOverlayResult( 2805 AccessibilityService.OVERLAY_RESULT_INVALID, interactionId); 2806 return; 2807 } 2808 connection 2809 .getRemote() 2810 .attachAccessibilityOverlayToWindow(sc, interactionId, callback); 2811 mOverlays.add(sc); 2812 } 2813 2814 } finally { 2815 Binder.restoreCallingIdentity(identity); 2816 } 2817 } 2818 detachAllOverlays()2819 protected void detachAllOverlays() { 2820 SurfaceControl.Transaction t = new SurfaceControl.Transaction(); 2821 for (SurfaceControl sc : mOverlays) { 2822 if (sc.isValid()) { 2823 t.reparent(sc, null); 2824 } 2825 } 2826 t.apply(); 2827 t.close(); 2828 mOverlays.clear(); 2829 } 2830 2831 @Override 2832 @EnforcePermission(android.Manifest.permission.BLUETOOTH_CONNECT) connectBluetoothBrailleDisplay(String bluetoothAddress, IBrailleDisplayController controller)2833 public void connectBluetoothBrailleDisplay(String bluetoothAddress, 2834 IBrailleDisplayController controller) { 2835 connectBluetoothBrailleDisplay_enforcePermission(); 2836 throw new UnsupportedOperationException(); 2837 } 2838 2839 @RequiresNoPermission 2840 @Override connectUsbBrailleDisplay(UsbDevice usbDevice, IBrailleDisplayController controller)2841 public void connectUsbBrailleDisplay(UsbDevice usbDevice, 2842 IBrailleDisplayController controller) { 2843 throw new UnsupportedOperationException(); 2844 } 2845 2846 @Override 2847 @EnforcePermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) setTestBrailleDisplayData(List<Bundle> brailleDisplays)2848 public void setTestBrailleDisplayData(List<Bundle> brailleDisplays) { 2849 setTestBrailleDisplayData_enforcePermission(); 2850 throw new UnsupportedOperationException(); 2851 } 2852 } 2853