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