1 /*
2  * Copyright (C) 2023 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 com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.INTERACTIVE_UI_TIMEOUT_100MS;
20 import static com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.INTERACTIVE_UI_TIMEOUT_200MS;
21 import static com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.NON_INTERACTIVE_UI_TIMEOUT_100MS;
22 import static com.android.server.accessibility.ProxyAccessibilityServiceConnectionTest.NON_INTERACTIVE_UI_TIMEOUT_200MS;
23 import static com.android.server.accessibility.ProxyManager.PROXY_COMPONENT_CLASS_NAME;
24 import static com.android.server.accessibility.ProxyManager.PROXY_COMPONENT_PACKAGE_NAME;
25 
26 import static org.junit.Assert.fail;
27 
28 import android.accessibilityservice.AccessibilityGestureEvent;
29 import android.accessibilityservice.AccessibilityServiceInfo;
30 import android.accessibilityservice.AccessibilityTrace;
31 import android.accessibilityservice.IAccessibilityServiceClient;
32 import android.accessibilityservice.IAccessibilityServiceConnection;
33 import android.accessibilityservice.MagnificationConfig;
34 import android.companion.virtual.IVirtualDeviceManager;
35 import android.companion.virtual.VirtualDeviceManager;
36 import android.content.ComponentName;
37 import android.content.Context;
38 import android.content.res.Resources;
39 import android.graphics.Region;
40 import android.os.IBinder;
41 import android.os.RemoteCallbackList;
42 import android.os.RemoteException;
43 import android.util.ArraySet;
44 import android.view.KeyEvent;
45 import android.view.MotionEvent;
46 import android.view.accessibility.AccessibilityEvent;
47 import android.view.accessibility.AccessibilityManager;
48 import android.view.accessibility.IAccessibilityManagerClient;
49 import android.view.inputmethod.EditorInfo;
50 
51 import com.android.internal.R;
52 import com.android.internal.inputmethod.IAccessibilityInputMethodSession;
53 import com.android.internal.inputmethod.IAccessibilityInputMethodSessionCallback;
54 import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
55 import com.android.internal.util.IntPair;
56 import com.android.server.LocalServices;
57 import com.android.server.accessibility.test.MessageCapturingHandler;
58 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
59 import com.android.server.wm.WindowManagerInternal;
60 
61 import static com.google.common.truth.Truth.assertThat;
62 
63 import androidx.test.InstrumentationRegistry;
64 
65 import static org.mockito.ArgumentMatchers.any;
66 import static org.mockito.ArgumentMatchers.anyInt;
67 import static org.mockito.Mockito.never;
68 import static org.mockito.Mockito.verify;
69 import static org.mockito.Mockito.when;
70 
71 import org.junit.After;
72 import org.junit.Before;
73 import org.junit.Test;
74 import org.mockito.Mock;
75 import org.mockito.MockitoAnnotations;
76 
77 import java.util.ArrayList;
78 import java.util.List;
79 import java.util.Set;
80 
81 /**
82  * Tests for ProxyManager.
83  */
84 public class ProxyManagerTest {
85     private static final int DISPLAY_ID = 1000;
86     private static final int DISPLAY_2_ID = 1001;
87     private static final int DEVICE_ID = 10;
88     private static final int STREAMED_CALLING_UID = 9876;
89 
90     @Mock private Context mMockContext;
91     @Mock private AccessibilitySecurityPolicy mMockSecurityPolicy;
92     @Mock private AccessibilityWindowManager mMockA11yWindowManager;
93     @Mock private ProxyManager.SystemSupport mMockProxySystemSupport;
94     @Mock private AbstractAccessibilityServiceConnection.SystemSupport mMockConnectionSystemSupport;
95     @Mock private AccessibilityTrace mMockA11yTrace;
96     @Mock private WindowManagerInternal mMockWindowManagerInternal;
97     @Mock private IAccessibilityServiceClient mMockAccessibilityServiceClient;
98     @Mock private IBinder mMockServiceAsBinder;
99     @Mock private VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal;
100     @Mock private IVirtualDeviceManager mMockIVirtualDeviceManager;
101 
102     private int mFocusStrokeWidthDefaultValue;
103     private int mFocusColorDefaultValue;
104 
105     private MessageCapturingHandler mMessageCapturingHandler  = new MessageCapturingHandler(null);
106     private ProxyManager mProxyManager;
107 
108     @Before
setup()109     public void setup() throws RemoteException {
110         MockitoAnnotations.initMocks(this);
111         final Resources resources = InstrumentationRegistry.getContext().getResources();
112 
113         mFocusStrokeWidthDefaultValue =
114                 resources.getDimensionPixelSize(R.dimen.accessibility_focus_highlight_stroke_width);
115         mFocusColorDefaultValue = resources.getColor(R.color.accessibility_focus_highlight_color);
116         when(mMockContext.getResources()).thenReturn(resources);
117 
118         when(mMockVirtualDeviceManagerInternal.getDeviceIdsForUid(anyInt())).thenReturn(
119                 new ArraySet(Set.of(DEVICE_ID)));
120         LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
121         LocalServices.addService(VirtualDeviceManagerInternal.class,
122                 mMockVirtualDeviceManagerInternal);
123 
124         when(mMockIVirtualDeviceManager.getDeviceIdForDisplayId(anyInt())).thenReturn(DEVICE_ID);
125         final VirtualDeviceManager virtualDeviceManager =
126                 new VirtualDeviceManager(mMockIVirtualDeviceManager, mMockContext);
127         when(mMockContext.getSystemServiceName(VirtualDeviceManager.class)).thenReturn(
128                 Context.VIRTUAL_DEVICE_SERVICE);
129         when(mMockContext.getSystemService(VirtualDeviceManager.class))
130                 .thenReturn(virtualDeviceManager);
131 
132         when(mMockA11yTrace.isA11yTracingEnabled()).thenReturn(false);
133 
134         final RemoteCallbackList<IAccessibilityManagerClient> userClients =
135                 new RemoteCallbackList<>();
136         final RemoteCallbackList<IAccessibilityManagerClient> globalClients =
137                 new RemoteCallbackList<>();
138         when(mMockProxySystemSupport.getCurrentUserClientsLocked()).thenReturn(userClients);
139         when(mMockProxySystemSupport.getGlobalClientsLocked()).thenReturn(globalClients);
140 
141         when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder);
142 
143         mProxyManager = new ProxyManager(new Object(), mMockA11yWindowManager, mMockContext,
144                 mMessageCapturingHandler, new UiAutomationManager(new Object()),
145                 mMockProxySystemSupport);
146     }
147 
148     @After
tearDown()149     public void tearDown() {
150         mMessageCapturingHandler.removeAllMessages();
151     }
152 
153     /**
154      * Tests that the proxy’s backing AccessibilityServiceClient is initialized when registering a
155      * proxy.
156      */
157     @Test
registerProxy_always_connectsServiceClient()158     public void registerProxy_always_connectsServiceClient() throws RemoteException {
159         registerProxy(DISPLAY_ID);
160         verify(mMockAccessibilityServiceClient).init(any(), anyInt(), any());
161     }
162 
163     /** Tests that unregistering a proxy removes its display from tracking. */
164     @Test
unregisterProxy_always_stopsTrackingDisplay()165     public void unregisterProxy_always_stopsTrackingDisplay() {
166         registerProxy(DISPLAY_ID);
167 
168         mProxyManager.unregisterProxy(DISPLAY_ID);
169 
170         verify(mMockA11yWindowManager).stopTrackingDisplayProxy(DISPLAY_ID);
171         assertThat(mProxyManager.isProxyedDisplay(DISPLAY_ID)).isFalse();
172     }
173     /**
174      * Tests that unregistering a proxied display of a virtual device, where that virtual device
175      * owned only that one proxied display, removes the device from tracking.
176      */
177     @Test
unregisterProxy_deviceAssociatedWithSingleDisplay_stopsTrackingDevice()178     public void unregisterProxy_deviceAssociatedWithSingleDisplay_stopsTrackingDevice() {
179         registerProxy(DISPLAY_ID);
180 
181         mProxyManager.unregisterProxy(DISPLAY_ID);
182 
183         assertThat(mProxyManager.isProxyedDeviceId(DEVICE_ID)).isFalse();
184         verify(mMockProxySystemSupport).removeDeviceIdLocked(DEVICE_ID);
185     }
186 
187     /**
188      * Tests that unregistering a proxied display of a virtual device, where that virtual device
189      * owns more than one proxied display, does not remove the device from tracking.
190      */
191     @Test
unregisterProxy_deviceAssociatedWithMultipleDisplays_tracksRemainingProxy()192     public void unregisterProxy_deviceAssociatedWithMultipleDisplays_tracksRemainingProxy() {
193         registerProxy(DISPLAY_ID);
194         registerProxy(DISPLAY_2_ID);
195 
196         mProxyManager.unregisterProxy(DISPLAY_ID);
197 
198         assertThat(mProxyManager.isProxyedDeviceId(DEVICE_ID)).isTrue();
199         verify(mMockProxySystemSupport, never()).removeDeviceIdLocked(DEVICE_ID);
200     }
201 
202     /**
203      * Tests that changing a proxy, e.g. registering/unregistering a proxy or updating its service
204      * info, notifies the apps being streamed and AccessibilityManagerService.
205      */
206     @Test
testOnProxyChanged_always_propagatesChange()207     public void testOnProxyChanged_always_propagatesChange() {
208         registerProxy(DISPLAY_ID);
209         mMessageCapturingHandler.sendAllMessages();
210 
211         mProxyManager.onProxyChanged(DEVICE_ID);
212 
213         // Messages to notify IAccessibilityManagerClients should be posted.
214         assertThat(mMessageCapturingHandler.hasMessages()).isTrue();
215 
216         verify(mMockProxySystemSupport).updateWindowsForAccessibilityCallbackLocked();
217         verify(mMockProxySystemSupport).notifyClearAccessibilityCacheLocked();
218     }
219 
220     /**
221      * Tests that getting the first device id for an app uid, such as when an app queries for
222      * device-specific state, returns the right device id.
223      */
224     @Test
testGetFirstDeviceForUid_streamedAppQueriesState_getsHostDeviceId()225     public void testGetFirstDeviceForUid_streamedAppQueriesState_getsHostDeviceId() {
226         registerProxy(DISPLAY_ID);
227         assertThat(mProxyManager.getFirstDeviceIdForUidLocked(STREAMED_CALLING_UID))
228                 .isEqualTo(DEVICE_ID);
229     }
230 
231     /**
232      * Tests that the app client state retrieved for a device reflects that touch exploration is
233      * enabled since a proxy info has requested touch exploration.
234      */
235     @Test
testGetClientState_proxyWantsTouchExploration_returnsTouchExplorationEnabled()236     public void testGetClientState_proxyWantsTouchExploration_returnsTouchExplorationEnabled() {
237         registerProxy(DISPLAY_ID);
238 
239         final AccessibilityServiceInfo secondDisplayInfo = new AccessibilityServiceInfo();
240         secondDisplayInfo.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
241         AccessibilityServiceClientImpl client = new AccessibilityServiceClientImpl(
242                 secondDisplayInfo);
243         registerProxy(DISPLAY_2_ID, client);
244 
245         final int deviceClientState = mProxyManager.getStateLocked(DEVICE_ID);
246         assertThat((deviceClientState
247                 & AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0).isTrue();
248     }
249 
250     /**
251      * Tests that the highest interactive and non-interactive timeout is returned if there are
252      * multiple proxied displays belonging to a device.
253      */
254     @Test
testGetRecommendedTimeout_multipleProxies_returnsHighestTimeout()255     public void testGetRecommendedTimeout_multipleProxies_returnsHighestTimeout() {
256         final AccessibilityServiceInfo firstDisplayInfo = new AccessibilityServiceInfo();
257         firstDisplayInfo.setInteractiveUiTimeoutMillis(INTERACTIVE_UI_TIMEOUT_100MS);
258         firstDisplayInfo.setNonInteractiveUiTimeoutMillis(NON_INTERACTIVE_UI_TIMEOUT_200MS);
259 
260         final AccessibilityServiceInfo secondDisplayInfo = new AccessibilityServiceInfo();
261         secondDisplayInfo.setInteractiveUiTimeoutMillis(INTERACTIVE_UI_TIMEOUT_200MS);
262         secondDisplayInfo.setNonInteractiveUiTimeoutMillis(NON_INTERACTIVE_UI_TIMEOUT_100MS);
263 
264         registerProxy(DISPLAY_ID, new AccessibilityServiceClientImpl(firstDisplayInfo));
265         registerProxy(DISPLAY_2_ID, new AccessibilityServiceClientImpl(secondDisplayInfo));
266 
267         final long timeout = mProxyManager.getRecommendedTimeoutMillisLocked(DEVICE_ID);
268         final int interactiveTimeout = IntPair.first(timeout);
269         final int nonInteractiveTimeout = IntPair.second(timeout);
270 
271         assertThat(interactiveTimeout).isEqualTo(INTERACTIVE_UI_TIMEOUT_200MS);
272         assertThat(nonInteractiveTimeout).isEqualTo(NON_INTERACTIVE_UI_TIMEOUT_200MS);
273     }
274     /**
275      * Tests that getting the installed and enabled services returns the info of the registered
276      * proxy. (The component name reflects the display id.)
277      */
278     @Test
testGetInstalledAndEnabledServices_defaultInfo_returnsInfoForDisplayId()279     public void testGetInstalledAndEnabledServices_defaultInfo_returnsInfoForDisplayId() {
280         final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
281         registerProxy(DISPLAY_ID, new AccessibilityServiceClientImpl(info));
282         final List<AccessibilityServiceInfo> installedAndEnabledServices =
283                 mProxyManager.getInstalledAndEnabledServiceInfosLocked(
284                         AccessibilityServiceInfo.FEEDBACK_ALL_MASK, DEVICE_ID);
285         assertThat(installedAndEnabledServices.size()).isEqualTo(1);
286         AccessibilityServiceInfo proxyInfo = installedAndEnabledServices.get(0);
287 
288         assertThat(proxyInfo.getComponentName()).isEqualTo(new ComponentName(
289                 PROXY_COMPONENT_PACKAGE_NAME, PROXY_COMPONENT_CLASS_NAME + DISPLAY_ID));
290     }
291 
292     /**
293      * Tests that the app client state retrieved for a device reflects that accessibility is
294      * enabled.
295      */
296     @Test
testGetClientState_always_returnsAccessibilityEnabled()297     public void testGetClientState_always_returnsAccessibilityEnabled() {
298         registerProxy(DISPLAY_ID);
299 
300         final int deviceClientState = mProxyManager.getStateLocked(DEVICE_ID);
301         assertThat((deviceClientState
302                 & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0).isTrue();
303     }
304 
305     /**
306      * Tests that the manager can retrieve interactive windows if a proxy sets
307      * AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS.
308      */
309     @Test
testCanRetrieveInteractiveWindows_atLeastOneProxyWantsWindows_returnsTrue()310     public void testCanRetrieveInteractiveWindows_atLeastOneProxyWantsWindows_returnsTrue() {
311         registerProxy(DISPLAY_ID);
312 
313         final AccessibilityServiceInfo secondDisplayInfo = new AccessibilityServiceInfo();
314         secondDisplayInfo.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
315         registerProxy(DISPLAY_2_ID, new AccessibilityServiceClientImpl(secondDisplayInfo));
316 
317         assertThat(mProxyManager.canRetrieveInteractiveWindowsLocked()).isTrue();
318     }
319 
320     /**
321      * Tests that getting service interfaces to interrupt when AccessibilityManager#interrupt
322      * returns the registered proxy interface.
323      */
324     @Test
testGetServiceInterfacesForInterrupt_defaultProxy_returnsProxyInterface()325     public void testGetServiceInterfacesForInterrupt_defaultProxy_returnsProxyInterface() {
326         registerProxy(DISPLAY_ID);
327         final List<IAccessibilityServiceClient> interfacesToInterrupt = new ArrayList<>();
328         mProxyManager.addServiceInterfacesLocked(interfacesToInterrupt, DEVICE_ID);
329 
330         assertThat(interfacesToInterrupt.size()).isEqualTo(1);
331         assertThat(interfacesToInterrupt.get(0).asBinder()).isEqualTo(mMockServiceAsBinder);
332     }
333 
334     /** Tests that the default timeout (0) is returned when the proxy is registered. */
335     @Test
getRecommendedTimeout_defaultProxyInfo_getsDefaultTimeout()336     public void getRecommendedTimeout_defaultProxyInfo_getsDefaultTimeout() {
337         registerProxy(DISPLAY_ID);
338         final long timeout = mProxyManager.getRecommendedTimeoutMillisLocked(DEVICE_ID);
339         final int interactiveTimeout = IntPair.first(timeout);
340         final int nonInteractiveTimeout = IntPair.second(timeout);
341 
342         assertThat(interactiveTimeout).isEqualTo(0);
343         assertThat(nonInteractiveTimeout).isEqualTo(0);
344     }
345 
346     /** Tests that the manager returns the updated timeout when the proxy’s timeout is updated. */
347     @Test
getRecommendedTimeout_updateTimeout_getsUpdatedTimeout()348     public void getRecommendedTimeout_updateTimeout_getsUpdatedTimeout() {
349         registerProxy(DISPLAY_ID);
350 
351         mProxyManager.updateTimeoutsIfNeeded(NON_INTERACTIVE_UI_TIMEOUT_100MS,
352                 INTERACTIVE_UI_TIMEOUT_200MS);
353 
354         final long updatedTimeout = mProxyManager.getRecommendedTimeoutMillisLocked(DEVICE_ID);
355         final int updatedInteractiveTimeout = IntPair.first(updatedTimeout);
356         final int updatedNonInteractiveTimeout = IntPair.second(updatedTimeout);
357 
358         assertThat(updatedInteractiveTimeout).isEqualTo(INTERACTIVE_UI_TIMEOUT_200MS);
359         assertThat(updatedNonInteractiveTimeout).isEqualTo(NON_INTERACTIVE_UI_TIMEOUT_100MS);
360     }
361 
362     /** Tests that the system’s default focus color is returned. */
363     @Test
testGetFocusColor_defaultProxy_getsDefaultSystemColor()364     public void testGetFocusColor_defaultProxy_getsDefaultSystemColor() {
365         registerProxy(DISPLAY_ID);
366         final int focusColor = mProxyManager.getFocusColorLocked(DEVICE_ID);
367         assertThat(focusColor).isEqualTo(mFocusColorDefaultValue);
368     }
369 
370     /** Tests that the system’s default focus stroke width is returned. */
371     @Test
testGetFocusStrokeWidth_defaultProxy_getsDefaultSystemWidth()372     public void testGetFocusStrokeWidth_defaultProxy_getsDefaultSystemWidth() {
373         registerProxy(DISPLAY_ID);
374         final int focusStrokeWidth = mProxyManager.getFocusStrokeWidthLocked(DEVICE_ID);
375         assertThat(focusStrokeWidth).isEqualTo(mFocusStrokeWidthDefaultValue);
376     }
377 
registerProxy(int displayId)378     private void registerProxy(int displayId) {
379         try {
380             mProxyManager.registerProxy(mMockAccessibilityServiceClient, displayId, anyInt(),
381                     mMockSecurityPolicy, mMockConnectionSystemSupport,
382                     mMockA11yTrace, mMockWindowManagerInternal);
383         } catch (RemoteException e) {
384             fail("Failed to register proxy " + e);
385         }
386     }
387 
registerProxy(int displayId, AccessibilityServiceClientImpl serviceClient)388     private void registerProxy(int displayId, AccessibilityServiceClientImpl serviceClient) {
389         try {
390             mProxyManager.registerProxy(serviceClient, displayId, anyInt(),
391                     mMockSecurityPolicy, mMockConnectionSystemSupport,
392                     mMockA11yTrace, mMockWindowManagerInternal);
393         } catch (RemoteException e) {
394             fail("Failed to register proxy " + e);
395         }
396     }
397 
398     /**
399      * IAccessibilityServiceClient implementation.
400      * A proxy connection does not populate non-default AccessibilityServiceInfo values until the
401      * proxy is connected in A11yDisplayProxy#onServiceConnected. For tests that check for
402      * non-default values, populate immediately in this testing class, since a real Service is not
403      * being used and connected.
404      */
405     static class AccessibilityServiceClientImpl extends IAccessibilityServiceClient.Stub {
406         List<AccessibilityServiceInfo> mInstalledAndEnabledServices;
407 
AccessibilityServiceClientImpl(AccessibilityServiceInfo installedAndEnabledService)408         AccessibilityServiceClientImpl(AccessibilityServiceInfo
409                 installedAndEnabledService) {
410             mInstalledAndEnabledServices = List.of(installedAndEnabledService);
411         }
412 
413         @Override
init(IAccessibilityServiceConnection connection, int connectionId, IBinder windowToken)414         public void init(IAccessibilityServiceConnection connection, int connectionId,
415                 IBinder windowToken) throws RemoteException {
416             connection.setInstalledAndEnabledServices(mInstalledAndEnabledServices);
417         }
418 
419         @Override
onAccessibilityEvent(AccessibilityEvent event, boolean serviceWantsEvent)420         public void onAccessibilityEvent(AccessibilityEvent event, boolean serviceWantsEvent)
421                 throws RemoteException {
422 
423         }
424 
425         @Override
onInterrupt()426         public void onInterrupt() throws RemoteException {
427 
428         }
429 
430         @Override
onGesture(AccessibilityGestureEvent gestureEvent)431         public void onGesture(AccessibilityGestureEvent gestureEvent) throws RemoteException {
432 
433         }
434 
435         @Override
clearAccessibilityCache()436         public void clearAccessibilityCache() throws RemoteException {
437 
438         }
439 
440         @Override
onKeyEvent(KeyEvent event, int sequence)441         public void onKeyEvent(KeyEvent event, int sequence) throws RemoteException {
442 
443         }
444 
445         @Override
onMagnificationChanged(int displayId, Region region, MagnificationConfig config)446         public void onMagnificationChanged(int displayId, Region region, MagnificationConfig config)
447                 throws RemoteException {
448 
449         }
450 
451         @Override
onMotionEvent(MotionEvent event)452         public void onMotionEvent(MotionEvent event) throws RemoteException {
453 
454         }
455 
456         @Override
onTouchStateChanged(int displayId, int state)457         public void onTouchStateChanged(int displayId, int state) throws RemoteException {
458 
459         }
460 
461         @Override
onSoftKeyboardShowModeChanged(int showMode)462         public void onSoftKeyboardShowModeChanged(int showMode) throws RemoteException {
463 
464         }
465 
466         @Override
onPerformGestureResult(int sequence, boolean completedSuccessfully)467         public void onPerformGestureResult(int sequence, boolean completedSuccessfully)
468                 throws RemoteException {
469 
470         }
471 
472         @Override
onFingerprintCapturingGesturesChanged(boolean capturing)473         public void onFingerprintCapturingGesturesChanged(boolean capturing)
474                 throws RemoteException {
475 
476         }
477 
478         @Override
onFingerprintGesture(int gesture)479         public void onFingerprintGesture(int gesture) throws RemoteException {
480 
481         }
482 
483         @Override
onAccessibilityButtonClicked(int displayId)484         public void onAccessibilityButtonClicked(int displayId) throws RemoteException {
485 
486         }
487 
488         @Override
onAccessibilityButtonAvailabilityChanged(boolean available)489         public void onAccessibilityButtonAvailabilityChanged(boolean available)
490                 throws RemoteException {
491 
492         }
493 
494         @Override
onSystemActionsChanged()495         public void onSystemActionsChanged() throws RemoteException {
496 
497         }
498 
499         @Override
createImeSession(IAccessibilityInputMethodSessionCallback callback)500         public void createImeSession(IAccessibilityInputMethodSessionCallback callback)
501                 throws RemoteException {
502 
503         }
504 
505         @Override
setImeSessionEnabled(IAccessibilityInputMethodSession session, boolean enabled)506         public void setImeSessionEnabled(IAccessibilityInputMethodSession session, boolean enabled)
507                 throws RemoteException {
508 
509         }
510 
511         @Override
bindInput()512         public void bindInput() throws RemoteException {
513 
514         }
515 
516         @Override
unbindInput()517         public void unbindInput() throws RemoteException {
518 
519         }
520 
521         @Override
startInput(IRemoteAccessibilityInputConnection connection, EditorInfo editorInfo, boolean restarting)522         public void startInput(IRemoteAccessibilityInputConnection connection,
523                 EditorInfo editorInfo, boolean restarting) throws RemoteException {
524 
525         }
526     }
527 }
528