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