Loading core/api/system-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -15924,10 +15924,17 @@ package android.view { package android.view.accessibility { public abstract class AccessibilityDisplayProxy { ctor public AccessibilityDisplayProxy(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.List<android.accessibilityservice.AccessibilityServiceInfo>); method public int getDisplayId(); } public final class AccessibilityManager { method public int getAccessibilityWindowId(@Nullable android.os.IBinder); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void performAccessibilityShortcut(); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public boolean registerDisplayProxy(@NonNull android.view.accessibility.AccessibilityDisplayProxy); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull android.app.RemoteAction, int); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public boolean unregisterDisplayProxy(@NonNull android.view.accessibility.AccessibilityDisplayProxy); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int); } core/java/android/view/accessibility/AccessibilityDisplayProxy.java 0 → 100644 +181 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view.accessibility; import android.accessibilityservice.AccessibilityGestureEvent; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.MagnificationConfig; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.Context; import android.graphics.Region; import android.os.IBinder; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.inputmethod.EditorInfo; import com.android.internal.inputmethod.IAccessibilityInputMethodSessionCallback; import com.android.internal.inputmethod.RemoteAccessibilityInputConnection; import java.util.List; import java.util.concurrent.Executor; /** * Allows a privileged app - an app with MANAGE_ACCESSIBILITY permission and SystemAPI access - to * interact with the windows in the display that this proxy represents. Proxying the default display * or a display that is not tracked will throw an exception. Only the real user has access to global * clients like SystemUI. * * <p> * To register and unregister a proxy, use * {@link AccessibilityManager#registerDisplayProxy(AccessibilityDisplayProxy)} * and {@link AccessibilityManager#unregisterDisplayProxy(AccessibilityDisplayProxy)}. If the app * that has registered the proxy dies, the system will remove the proxy. * * TODO(241429275): Complete proxy impl and add additional support (if necessary) like cache methods * @hide */ @SystemApi public abstract class AccessibilityDisplayProxy { private static final String LOG_TAG = "AccessibilityDisplayProxy"; private static final int INVALID_CONNECTION_ID = -1; private List<AccessibilityServiceInfo> mInstalledAndEnabledServices; private Executor mExecutor; private int mConnectionId = INVALID_CONNECTION_ID; private int mDisplayId; IAccessibilityServiceClient mServiceClient; /** * Constructs an AccessibilityDisplayProxy instance. * @param displayId the id of the display to proxy. * @param executor the executor used to execute proxy callbacks. * @param installedAndEnabledServices the list of infos representing the installed and * enabled a11y services. */ public AccessibilityDisplayProxy(int displayId, @NonNull Executor executor, @NonNull List<AccessibilityServiceInfo> installedAndEnabledServices) { mDisplayId = displayId; mExecutor = executor; // Typically, the context is the Service context of an accessibility service. // Context is used for ResolveInfo check, which a proxy won't have, IME input // (FLAG_INPUT_METHOD_EDITOR), which the proxy doesn't need, and tracing // A11yInteractionClient methods. // TODO(254097475): Enable tracing, potentially without exposing Context. mServiceClient = new IAccessibilityServiceClientImpl(null, mExecutor); mInstalledAndEnabledServices = installedAndEnabledServices; } /** * Returns the id of the display being proxy-ed. */ public int getDisplayId() { return mDisplayId; } /** * An IAccessibilityServiceClient that handles interrupts and accessibility events. */ private class IAccessibilityServiceClientImpl extends AccessibilityService.IAccessibilityServiceClientWrapper { IAccessibilityServiceClientImpl(Context context, Executor executor) { super(context, executor, new AccessibilityService.Callbacks() { @Override public void onAccessibilityEvent(AccessibilityEvent event) { // TODO: call AccessiiblityProxy.onAccessibilityEvent } @Override public void onInterrupt() { // TODO: call AccessiiblityProxy.onInterrupt } @Override public void onServiceConnected() { // TODO: send service infos and call AccessiiblityProxy.onProxyConnected } @Override public void init(int connectionId, IBinder windowToken) { mConnectionId = connectionId; } @Override public boolean onGesture(AccessibilityGestureEvent gestureInfo) { return false; } @Override public boolean onKeyEvent(KeyEvent event) { return false; } @Override public void onMagnificationChanged(int displayId, @NonNull Region region, MagnificationConfig config) { } @Override public void onMotionEvent(MotionEvent event) { } @Override public void onTouchStateChanged(int displayId, int state) { } @Override public void onSoftKeyboardShowModeChanged(int showMode) { } @Override public void onPerformGestureResult(int sequence, boolean completedSuccessfully) { } @Override public void onFingerprintCapturingGesturesChanged(boolean active) { } @Override public void onFingerprintGesture(int gesture) { } @Override public void onAccessibilityButtonClicked(int displayId) { } @Override public void onAccessibilityButtonAvailabilityChanged(boolean available) { } @Override public void onSystemActionsChanged() { } @Override public void createImeSession(IAccessibilityInputMethodSessionCallback callback) { } @Override public void startInput(@Nullable RemoteAccessibilityInputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting) { } }); } } } core/java/android/view/accessibility/AccessibilityManager.java +61 −0 Original line number Diff line number Diff line Loading @@ -1921,6 +1921,67 @@ public final class AccessibilityManager { } } /** * Registers an {@link AccessibilityDisplayProxy}, so this proxy can access UI content specific * to its display. * * @param proxy the {@link AccessibilityDisplayProxy} to register. * @return {@code true} if the proxy is successfully registered. * * @throws IllegalArgumentException if the proxy's display is not currently tracked by a11y, is * {@link android.view.Display#DEFAULT_DISPLAY}, is or lower than * {@link android.view.Display#INVALID_DISPLAY}, or is already being proxy-ed. * * @throws SecurityException if the app does not hold the * {@link Manifest.permission#MANAGE_ACCESSIBILITY} permission. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public boolean registerDisplayProxy(@NonNull AccessibilityDisplayProxy proxy) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return false; } } try { return service.registerProxyForDisplay(proxy.mServiceClient, proxy.getDisplayId()); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Unregisters an {@link AccessibilityDisplayProxy}. * * @return {@code true} if the proxy is successfully unregistered. * * @throws SecurityException if the app does not hold the * {@link Manifest.permission#MANAGE_ACCESSIBILITY} permission. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public boolean unregisterDisplayProxy(@NonNull AccessibilityDisplayProxy proxy) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return false; } } try { return service.unregisterProxyForDisplay(proxy.getDisplayId()); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } private IAccessibilityManager getServiceLocked() { if (mService == null) { tryConnectToServiceLocked(null); Loading core/java/android/view/accessibility/IAccessibilityManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -109,9 +109,9 @@ interface IAccessibilityManager { oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes); // Requires Manifest.permission.MANAGE_ACCESSIBILITY @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)") boolean registerProxyForDisplay(IAccessibilityServiceClient proxy, int displayId); // Requires Manifest.permission.MANAGE_ACCESSIBILITY @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)") boolean unregisterProxyForDisplay(int displayId); } core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.RemoteAction; Loading @@ -34,6 +35,7 @@ import android.content.Intent; import android.graphics.drawable.Icon; import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; Loading @@ -51,6 +53,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; /** * Tests for the AccessibilityManager by mocking the backing service. Loading @@ -70,6 +73,7 @@ public class AccessibilityManagerTest { LABEL, DESCRIPTION, TEST_PENDING_INTENT); private static final int DISPLAY_ID = 22; @Mock private IAccessibilityManager mMockService; private MessageCapturingHandler mHandler; Loading Loading @@ -224,4 +228,45 @@ public class AccessibilityManagerTest { assertEquals(mFocusColorDefaultValue, manager.getAccessibilityFocusColor()); } @Test public void testRegisterAccessibilityProxy() throws Exception { // Accessibility does not need to be enabled for a proxy to be registered. AccessibilityManager manager = new AccessibilityManager(mInstrumentation.getContext(), mHandler, mMockService, UserHandle.USER_CURRENT, true); ArrayList<AccessibilityServiceInfo> infos = new ArrayList<>(); infos.add(new AccessibilityServiceInfo()); AccessibilityDisplayProxy proxy = new MyAccessibilityProxy(DISPLAY_ID, infos); manager.registerDisplayProxy(proxy); // Cannot access proxy.mServiceClient directly due to visibility. verify(mMockService).registerProxyForDisplay(any(IAccessibilityServiceClient.class), any(Integer.class)); } @Test public void testUnregisterAccessibilityProxy() throws Exception { // Accessibility does not need to be enabled for a proxy to be registered. final AccessibilityManager manager = new AccessibilityManager(mInstrumentation.getContext(), mHandler, mMockService, UserHandle.USER_CURRENT, true); final ArrayList<AccessibilityServiceInfo> infos = new ArrayList<>(); infos.add(new AccessibilityServiceInfo()); final AccessibilityDisplayProxy proxy = new MyAccessibilityProxy(DISPLAY_ID, infos); manager.registerDisplayProxy(proxy); manager.unregisterDisplayProxy(proxy); verify(mMockService).unregisterProxyForDisplay(proxy.getDisplayId()); } private class MyAccessibilityProxy extends AccessibilityDisplayProxy { // TODO(241429275): Will override A11yProxy methods in the future. MyAccessibilityProxy(int displayId, @NonNull List<AccessibilityServiceInfo> serviceInfos) { super(displayId, Executors.newSingleThreadExecutor(), serviceInfos); } } } Loading
core/api/system-current.txt +7 −0 Original line number Diff line number Diff line Loading @@ -15924,10 +15924,17 @@ package android.view { package android.view.accessibility { public abstract class AccessibilityDisplayProxy { ctor public AccessibilityDisplayProxy(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.List<android.accessibilityservice.AccessibilityServiceInfo>); method public int getDisplayId(); } public final class AccessibilityManager { method public int getAccessibilityWindowId(@Nullable android.os.IBinder); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void performAccessibilityShortcut(); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public boolean registerDisplayProxy(@NonNull android.view.accessibility.AccessibilityDisplayProxy); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull android.app.RemoteAction, int); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public boolean unregisterDisplayProxy(@NonNull android.view.accessibility.AccessibilityDisplayProxy); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int); }
core/java/android/view/accessibility/AccessibilityDisplayProxy.java 0 → 100644 +181 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view.accessibility; import android.accessibilityservice.AccessibilityGestureEvent; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.MagnificationConfig; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.Context; import android.graphics.Region; import android.os.IBinder; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.inputmethod.EditorInfo; import com.android.internal.inputmethod.IAccessibilityInputMethodSessionCallback; import com.android.internal.inputmethod.RemoteAccessibilityInputConnection; import java.util.List; import java.util.concurrent.Executor; /** * Allows a privileged app - an app with MANAGE_ACCESSIBILITY permission and SystemAPI access - to * interact with the windows in the display that this proxy represents. Proxying the default display * or a display that is not tracked will throw an exception. Only the real user has access to global * clients like SystemUI. * * <p> * To register and unregister a proxy, use * {@link AccessibilityManager#registerDisplayProxy(AccessibilityDisplayProxy)} * and {@link AccessibilityManager#unregisterDisplayProxy(AccessibilityDisplayProxy)}. If the app * that has registered the proxy dies, the system will remove the proxy. * * TODO(241429275): Complete proxy impl and add additional support (if necessary) like cache methods * @hide */ @SystemApi public abstract class AccessibilityDisplayProxy { private static final String LOG_TAG = "AccessibilityDisplayProxy"; private static final int INVALID_CONNECTION_ID = -1; private List<AccessibilityServiceInfo> mInstalledAndEnabledServices; private Executor mExecutor; private int mConnectionId = INVALID_CONNECTION_ID; private int mDisplayId; IAccessibilityServiceClient mServiceClient; /** * Constructs an AccessibilityDisplayProxy instance. * @param displayId the id of the display to proxy. * @param executor the executor used to execute proxy callbacks. * @param installedAndEnabledServices the list of infos representing the installed and * enabled a11y services. */ public AccessibilityDisplayProxy(int displayId, @NonNull Executor executor, @NonNull List<AccessibilityServiceInfo> installedAndEnabledServices) { mDisplayId = displayId; mExecutor = executor; // Typically, the context is the Service context of an accessibility service. // Context is used for ResolveInfo check, which a proxy won't have, IME input // (FLAG_INPUT_METHOD_EDITOR), which the proxy doesn't need, and tracing // A11yInteractionClient methods. // TODO(254097475): Enable tracing, potentially without exposing Context. mServiceClient = new IAccessibilityServiceClientImpl(null, mExecutor); mInstalledAndEnabledServices = installedAndEnabledServices; } /** * Returns the id of the display being proxy-ed. */ public int getDisplayId() { return mDisplayId; } /** * An IAccessibilityServiceClient that handles interrupts and accessibility events. */ private class IAccessibilityServiceClientImpl extends AccessibilityService.IAccessibilityServiceClientWrapper { IAccessibilityServiceClientImpl(Context context, Executor executor) { super(context, executor, new AccessibilityService.Callbacks() { @Override public void onAccessibilityEvent(AccessibilityEvent event) { // TODO: call AccessiiblityProxy.onAccessibilityEvent } @Override public void onInterrupt() { // TODO: call AccessiiblityProxy.onInterrupt } @Override public void onServiceConnected() { // TODO: send service infos and call AccessiiblityProxy.onProxyConnected } @Override public void init(int connectionId, IBinder windowToken) { mConnectionId = connectionId; } @Override public boolean onGesture(AccessibilityGestureEvent gestureInfo) { return false; } @Override public boolean onKeyEvent(KeyEvent event) { return false; } @Override public void onMagnificationChanged(int displayId, @NonNull Region region, MagnificationConfig config) { } @Override public void onMotionEvent(MotionEvent event) { } @Override public void onTouchStateChanged(int displayId, int state) { } @Override public void onSoftKeyboardShowModeChanged(int showMode) { } @Override public void onPerformGestureResult(int sequence, boolean completedSuccessfully) { } @Override public void onFingerprintCapturingGesturesChanged(boolean active) { } @Override public void onFingerprintGesture(int gesture) { } @Override public void onAccessibilityButtonClicked(int displayId) { } @Override public void onAccessibilityButtonAvailabilityChanged(boolean available) { } @Override public void onSystemActionsChanged() { } @Override public void createImeSession(IAccessibilityInputMethodSessionCallback callback) { } @Override public void startInput(@Nullable RemoteAccessibilityInputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting) { } }); } } }
core/java/android/view/accessibility/AccessibilityManager.java +61 −0 Original line number Diff line number Diff line Loading @@ -1921,6 +1921,67 @@ public final class AccessibilityManager { } } /** * Registers an {@link AccessibilityDisplayProxy}, so this proxy can access UI content specific * to its display. * * @param proxy the {@link AccessibilityDisplayProxy} to register. * @return {@code true} if the proxy is successfully registered. * * @throws IllegalArgumentException if the proxy's display is not currently tracked by a11y, is * {@link android.view.Display#DEFAULT_DISPLAY}, is or lower than * {@link android.view.Display#INVALID_DISPLAY}, or is already being proxy-ed. * * @throws SecurityException if the app does not hold the * {@link Manifest.permission#MANAGE_ACCESSIBILITY} permission. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public boolean registerDisplayProxy(@NonNull AccessibilityDisplayProxy proxy) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return false; } } try { return service.registerProxyForDisplay(proxy.mServiceClient, proxy.getDisplayId()); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Unregisters an {@link AccessibilityDisplayProxy}. * * @return {@code true} if the proxy is successfully unregistered. * * @throws SecurityException if the app does not hold the * {@link Manifest.permission#MANAGE_ACCESSIBILITY} permission. * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public boolean unregisterDisplayProxy(@NonNull AccessibilityDisplayProxy proxy) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return false; } } try { return service.unregisterProxyForDisplay(proxy.getDisplayId()); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } private IAccessibilityManager getServiceLocked() { if (mService == null) { tryConnectToServiceLocked(null); Loading
core/java/android/view/accessibility/IAccessibilityManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -109,9 +109,9 @@ interface IAccessibilityManager { oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes); // Requires Manifest.permission.MANAGE_ACCESSIBILITY @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)") boolean registerProxyForDisplay(IAccessibilityServiceClient proxy, int displayId); // Requires Manifest.permission.MANAGE_ACCESSIBILITY @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY)") boolean unregisterProxyForDisplay(int displayId); }
core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.RemoteAction; Loading @@ -34,6 +35,7 @@ import android.content.Intent; import android.graphics.drawable.Icon; import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; Loading @@ -51,6 +53,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; /** * Tests for the AccessibilityManager by mocking the backing service. Loading @@ -70,6 +73,7 @@ public class AccessibilityManagerTest { LABEL, DESCRIPTION, TEST_PENDING_INTENT); private static final int DISPLAY_ID = 22; @Mock private IAccessibilityManager mMockService; private MessageCapturingHandler mHandler; Loading Loading @@ -224,4 +228,45 @@ public class AccessibilityManagerTest { assertEquals(mFocusColorDefaultValue, manager.getAccessibilityFocusColor()); } @Test public void testRegisterAccessibilityProxy() throws Exception { // Accessibility does not need to be enabled for a proxy to be registered. AccessibilityManager manager = new AccessibilityManager(mInstrumentation.getContext(), mHandler, mMockService, UserHandle.USER_CURRENT, true); ArrayList<AccessibilityServiceInfo> infos = new ArrayList<>(); infos.add(new AccessibilityServiceInfo()); AccessibilityDisplayProxy proxy = new MyAccessibilityProxy(DISPLAY_ID, infos); manager.registerDisplayProxy(proxy); // Cannot access proxy.mServiceClient directly due to visibility. verify(mMockService).registerProxyForDisplay(any(IAccessibilityServiceClient.class), any(Integer.class)); } @Test public void testUnregisterAccessibilityProxy() throws Exception { // Accessibility does not need to be enabled for a proxy to be registered. final AccessibilityManager manager = new AccessibilityManager(mInstrumentation.getContext(), mHandler, mMockService, UserHandle.USER_CURRENT, true); final ArrayList<AccessibilityServiceInfo> infos = new ArrayList<>(); infos.add(new AccessibilityServiceInfo()); final AccessibilityDisplayProxy proxy = new MyAccessibilityProxy(DISPLAY_ID, infos); manager.registerDisplayProxy(proxy); manager.unregisterDisplayProxy(proxy); verify(mMockService).unregisterProxyForDisplay(proxy.getDisplayId()); } private class MyAccessibilityProxy extends AccessibilityDisplayProxy { // TODO(241429275): Will override A11yProxy methods in the future. MyAccessibilityProxy(int displayId, @NonNull List<AccessibilityServiceInfo> serviceInfos) { super(displayId, Executors.newSingleThreadExecutor(), serviceInfos); } } }