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