Loading core/java/android/view/accessibility/IAccessibilityManager.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -108,4 +108,10 @@ interface IAccessibilityManager { void setSystemAudioCaptioningUiEnabled(boolean isEnabled, int userId); oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes); // Requires Manifest.permission.MANAGE_ACCESSIBILITY boolean registerProxyForDisplay(IAccessibilityServiceClient proxy, int displayId); // Requires Manifest.permission.MANAGE_ACCESSIBILITY boolean unregisterProxyForDisplay(int displayId); } services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +48 −1 Original line number Diff line number Diff line Loading @@ -277,6 +277,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final SparseArray<AccessibilityUserState> mUserStates = new SparseArray<>(); private final UiAutomationManager mUiAutomationManager = new UiAutomationManager(mLock); private final ProxyManager mProxyManager; private final AccessibilityTraceManager mTraceManager; private final CaptioningManagerImpl mCaptioningManagerImpl; Loading Loading @@ -396,7 +397,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityWindowManager a11yWindowManager, AccessibilityDisplayListener a11yDisplayListener, MagnificationController magnificationController, @Nullable AccessibilityInputFilter inputFilter) { @Nullable AccessibilityInputFilter inputFilter, ProxyManager proxyManager) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); Loading @@ -412,6 +414,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMagnificationController = magnificationController; mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); mProxyManager = proxyManager; if (inputFilter != null) { mInputFilter = inputFilter; mHasInputFilter = true; Loading Loading @@ -445,6 +448,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub new MagnificationScaleProvider(mContext)); mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); mProxyManager = new ProxyManager(mLock); init(); } Loading Loading @@ -3601,6 +3605,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mCaptioningManagerImpl.setSystemAudioCaptioningUiEnabled(isEnabled, userId); } @Override public boolean registerProxyForDisplay(IAccessibilityServiceClient client, int displayId) throws RemoteException { mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); if (client == null) { return false; } if (displayId < 0) { throw new IllegalArgumentException("The display id " + displayId + " is invalid."); } if (displayId == Display.DEFAULT_DISPLAY) { throw new IllegalArgumentException("The default display cannot be proxy-ed."); } if (!isTrackedDisplay(displayId)) { throw new IllegalArgumentException("The display " + displayId + " does not exist or is" + " not tracked by accessibility."); } mProxyManager.registerProxy(client, displayId); return true; } @Override public boolean unregisterProxyForDisplay(int displayId) throws RemoteException { mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); return mProxyManager.unregisterProxy(displayId); } @Override public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; Loading Loading @@ -3830,6 +3862,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return mA11yDisplayListener.getValidDisplayList(); } /** * Returns {@code true} if the display id is in the list of currently valid logical displays * being tracked by a11y. */ private boolean isTrackedDisplay(int displayId) { final ArrayList<Display> displays = getValidDisplayList(); for (Display display : displays) { if (display.getDisplayId() == displayId) { return true; } } return false; } /** * A Utility class to handle display state. */ Loading services/accessibility/java/com/android/server/accessibility/ProxyManager.java 0 → 100644 +46 −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 com.android.server.accessibility; import android.accessibilityservice.IAccessibilityServiceClient; /** * Manages proxy connections. * * Currently this acts similarly to UiAutomationManager as a global manager, though ideally each * proxy connection will belong to a separate user state. * * TODO(241117292): Remove or cut down during simultaneous user refactoring. */ public class ProxyManager { private final Object mLock; ProxyManager(Object lock) { mLock = lock; } /** * TODO: Create the proxy service connection. */ public void registerProxy(IAccessibilityServiceClient client, int displayId) { } /** * TODO: Unregister the proxy service connection based on display id. */ public boolean unregisterProxy(int displayId) { return true; } } services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +46 −1 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ public class AccessibilityManagerServiceTest { @Mock private WindowMagnificationManager mMockWindowMagnificationMgr; @Mock private MagnificationController mMockMagnificationController; @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController; @Mock private ProxyManager mProxyManager; @Rule public final TestableContext mTestableContext = new TestableContext( Loading Loading @@ -184,7 +185,8 @@ public class AccessibilityManagerServiceTest { mMockA11yWindowManager, mMockA11yDisplayListener, mMockMagnificationController, mInputFilter); mInputFilter, mProxyManager); final AccessibilityUserState userState = new AccessibilityUserState( mA11yms.getCurrentUserIdLocked(), mTestableContext, mA11yms); Loading Loading @@ -276,6 +278,49 @@ public class AccessibilityManagerServiceTest { verify(mMockServiceClient).onSystemActionsChanged(); } @SmallTest @Test public void testRegisterProxy() throws Exception { mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY); verify(mProxyManager).registerProxy(mMockServiceClient, TEST_DISPLAY); } @SmallTest @Test public void testRegisterProxyWithoutPermission() throws Exception { doThrow(SecurityException.class).when(mMockSecurityPolicy) .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); try { mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY); Assert.fail(); } catch (SecurityException expected) { } verify(mProxyManager, never()).registerProxy(mMockServiceClient, TEST_DISPLAY); } @SmallTest @Test public void testRegisterProxyForDefaultDisplay() throws Exception { try { mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY); Assert.fail(); } catch (IllegalArgumentException expected) { } verify(mProxyManager, never()).registerProxy(mMockServiceClient, Display.DEFAULT_DISPLAY); } @SmallTest @Test public void testRegisterProxyForInvalidDisplay() throws Exception { try { mA11yms.registerProxyForDisplay(mMockServiceClient, Display.INVALID_DISPLAY); Assert.fail(); } catch (IllegalArgumentException expected) { } verify(mProxyManager, never()).registerProxy(mMockServiceClient, Display.INVALID_DISPLAY); } @SmallTest @Test public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() { Loading Loading
core/java/android/view/accessibility/IAccessibilityManager.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -108,4 +108,10 @@ interface IAccessibilityManager { void setSystemAudioCaptioningUiEnabled(boolean isEnabled, int userId); oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes); // Requires Manifest.permission.MANAGE_ACCESSIBILITY boolean registerProxyForDisplay(IAccessibilityServiceClient proxy, int displayId); // Requires Manifest.permission.MANAGE_ACCESSIBILITY boolean unregisterProxyForDisplay(int displayId); }
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +48 −1 Original line number Diff line number Diff line Loading @@ -277,6 +277,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final SparseArray<AccessibilityUserState> mUserStates = new SparseArray<>(); private final UiAutomationManager mUiAutomationManager = new UiAutomationManager(mLock); private final ProxyManager mProxyManager; private final AccessibilityTraceManager mTraceManager; private final CaptioningManagerImpl mCaptioningManagerImpl; Loading Loading @@ -396,7 +397,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityWindowManager a11yWindowManager, AccessibilityDisplayListener a11yDisplayListener, MagnificationController magnificationController, @Nullable AccessibilityInputFilter inputFilter) { @Nullable AccessibilityInputFilter inputFilter, ProxyManager proxyManager) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); Loading @@ -412,6 +414,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMagnificationController = magnificationController; mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); mProxyManager = proxyManager; if (inputFilter != null) { mInputFilter = inputFilter; mHasInputFilter = true; Loading Loading @@ -445,6 +448,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub new MagnificationScaleProvider(mContext)); mMagnificationProcessor = new MagnificationProcessor(mMagnificationController); mCaptioningManagerImpl = new CaptioningManagerImpl(mContext); mProxyManager = new ProxyManager(mLock); init(); } Loading Loading @@ -3601,6 +3605,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mCaptioningManagerImpl.setSystemAudioCaptioningUiEnabled(isEnabled, userId); } @Override public boolean registerProxyForDisplay(IAccessibilityServiceClient client, int displayId) throws RemoteException { mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); if (client == null) { return false; } if (displayId < 0) { throw new IllegalArgumentException("The display id " + displayId + " is invalid."); } if (displayId == Display.DEFAULT_DISPLAY) { throw new IllegalArgumentException("The default display cannot be proxy-ed."); } if (!isTrackedDisplay(displayId)) { throw new IllegalArgumentException("The display " + displayId + " does not exist or is" + " not tracked by accessibility."); } mProxyManager.registerProxy(client, displayId); return true; } @Override public boolean unregisterProxyForDisplay(int displayId) throws RemoteException { mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); return mProxyManager.unregisterProxy(displayId); } @Override public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return; Loading Loading @@ -3830,6 +3862,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return mA11yDisplayListener.getValidDisplayList(); } /** * Returns {@code true} if the display id is in the list of currently valid logical displays * being tracked by a11y. */ private boolean isTrackedDisplay(int displayId) { final ArrayList<Display> displays = getValidDisplayList(); for (Display display : displays) { if (display.getDisplayId() == displayId) { return true; } } return false; } /** * A Utility class to handle display state. */ Loading
services/accessibility/java/com/android/server/accessibility/ProxyManager.java 0 → 100644 +46 −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 com.android.server.accessibility; import android.accessibilityservice.IAccessibilityServiceClient; /** * Manages proxy connections. * * Currently this acts similarly to UiAutomationManager as a global manager, though ideally each * proxy connection will belong to a separate user state. * * TODO(241117292): Remove or cut down during simultaneous user refactoring. */ public class ProxyManager { private final Object mLock; ProxyManager(Object lock) { mLock = lock; } /** * TODO: Create the proxy service connection. */ public void registerProxy(IAccessibilityServiceClient client, int displayId) { } /** * TODO: Unregister the proxy service connection based on display id. */ public boolean unregisterProxy(int displayId) { return true; } }
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +46 −1 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ public class AccessibilityManagerServiceTest { @Mock private WindowMagnificationManager mMockWindowMagnificationMgr; @Mock private MagnificationController mMockMagnificationController; @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController; @Mock private ProxyManager mProxyManager; @Rule public final TestableContext mTestableContext = new TestableContext( Loading Loading @@ -184,7 +185,8 @@ public class AccessibilityManagerServiceTest { mMockA11yWindowManager, mMockA11yDisplayListener, mMockMagnificationController, mInputFilter); mInputFilter, mProxyManager); final AccessibilityUserState userState = new AccessibilityUserState( mA11yms.getCurrentUserIdLocked(), mTestableContext, mA11yms); Loading Loading @@ -276,6 +278,49 @@ public class AccessibilityManagerServiceTest { verify(mMockServiceClient).onSystemActionsChanged(); } @SmallTest @Test public void testRegisterProxy() throws Exception { mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY); verify(mProxyManager).registerProxy(mMockServiceClient, TEST_DISPLAY); } @SmallTest @Test public void testRegisterProxyWithoutPermission() throws Exception { doThrow(SecurityException.class).when(mMockSecurityPolicy) .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); try { mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY); Assert.fail(); } catch (SecurityException expected) { } verify(mProxyManager, never()).registerProxy(mMockServiceClient, TEST_DISPLAY); } @SmallTest @Test public void testRegisterProxyForDefaultDisplay() throws Exception { try { mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY); Assert.fail(); } catch (IllegalArgumentException expected) { } verify(mProxyManager, never()).registerProxy(mMockServiceClient, Display.DEFAULT_DISPLAY); } @SmallTest @Test public void testRegisterProxyForInvalidDisplay() throws Exception { try { mA11yms.registerProxyForDisplay(mMockServiceClient, Display.INVALID_DISPLAY); Assert.fail(); } catch (IllegalArgumentException expected) { } verify(mProxyManager, never()).registerProxy(mMockServiceClient, Display.INVALID_DISPLAY); } @SmallTest @Test public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() { Loading