Loading services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +16 −11 Original line number Diff line number Diff line Loading @@ -352,7 +352,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ @Override public List<AccessibilityWindowInfo> getWindows() { ensureWindowsAvailableTimed(); ensureWindowsAvailableTimed(Display.DEFAULT_DISPLAY); synchronized (mLock) { if (!hasRightsToCurrentUserLocked()) { return null; Loading @@ -362,8 +362,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ if (!permissionGranted) { return null; } // TODO [Multi-Display] (b/134891479) : // using correct display Id to replace DEFAULT_DISPLAY. List<AccessibilityWindowInfo> internalWindowList = mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY); if (internalWindowList == null) { Loading @@ -387,7 +385,14 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ @Override public AccessibilityWindowInfo getWindow(int windowId) { ensureWindowsAvailableTimed(); int displayId = Display.INVALID_DISPLAY; synchronized (mLock) { if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked( mSystemSupport.getCurrentUserIdLocked(), windowId); } } ensureWindowsAvailableTimed(displayId); synchronized (mLock) { if (!hasRightsToCurrentUserLocked()) { return null; Loading Loading @@ -1308,28 +1313,28 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ /** * Request that the system make sure windows are available to interrogate. * * @param displayId The logical display id. */ private void ensureWindowsAvailableTimed() { private void ensureWindowsAvailableTimed(int displayId) { synchronized (mLock) { // TODO [Multi-Display] (b/134891479) : // using correct display Id to replace DEFAULT_DISPLAY. if (mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY) != null) { if (mA11yWindowManager.getWindowListLocked(displayId) != null) { return; } // If we have no registered callback, update the state we // we may have to register one but it didn't happen yet. if (!mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY)) { if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) { // Invokes client change to make sure tracking window enabled. mSystemSupport.onClientChangeLocked(false); } // We have no windows but do not care about them, done. if (!mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY)) { if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) { return; } // Wait for the windows with a timeout. final long startMillis = SystemClock.uptimeMillis(); while (mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY) == null) { while (mA11yWindowManager.getWindowListLocked(displayId) == null) { final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis; if (remainMillis <= 0) { Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +11 −4 Original line number Diff line number Diff line Loading @@ -580,17 +580,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // Make sure clients receiving this event will be able to get the // current state of the windows as the window manager may be delaying // the computation for performance reasons. // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY. boolean shouldComputeWindows = false; int displayId = Display.INVALID_DISPLAY; synchronized (mLock) { final int windowId = event.getWindowId(); if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY)) { && windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked( mCurrentUserId, windowId); } if (displayId != Display.INVALID_DISPLAY && mA11yWindowManager.isTrackingWindowsLocked(displayId)) { shouldComputeWindows = true; } } if (shouldComputeWindows) { WindowManagerInternal wm = LocalServices.getService(WindowManagerInternal.class); wm.computeWindowsForAccessibility(Display.DEFAULT_DISPLAY); final WindowManagerInternal wm = LocalServices.getService( WindowManagerInternal.class); wm.computeWindowsForAccessibility(displayId); } synchronized (mLock) { notifyAccessibilityServicesDelayedLocked(event, false); Loading services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -1462,6 +1462,20 @@ public class AccessibilityWindowManager { } } /** * Returns the display ID according to given userId and windowId. * * @param userId The userId * @param windowId The windowId * @return The display ID */ public int getDisplayIdByUserIdAndWindowIdLocked(int userId, int windowId) { final IBinder windowToken = getWindowTokenForUserAndWindowIdLocked(userId, windowId); final int displayId = mWindowManagerInternal.getDisplayIdForWindow(windowToken); return displayId; } /** * Gets current input focused window token from window manager, and returns its windowId. * Loading services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java +21 −3 Original line number Diff line number Diff line Loading @@ -111,6 +111,8 @@ public class AbstractAccessibilityServiceConnectionTest { private static final String VIEW_TEXT = "test_view_text"; private static final int WINDOWID = 12; private static final int PIP_WINDOWID = 13; private static final int WINDOWID_ONSECONDDISPLAY = 14; private static final int SECONDARY_DISPLAY_ID = Display.DEFAULT_DISPLAY + 1; private static final int SERVICE_ID = 42; private static final int A11Y_SERVICE_CAPABILITY = CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT | CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION Loading @@ -135,6 +137,7 @@ public class AbstractAccessibilityServiceConnectionTest { private AbstractAccessibilityServiceConnection mServiceConnection; private MessageCapturingHandler mHandler = new MessageCapturingHandler(null); private final List<AccessibilityWindowInfo> mA11yWindowInfos = new ArrayList<>(); private final List<AccessibilityWindowInfo> mA11yWindowInfosOnSecondDisplay = new ArrayList<>(); private Callable[] mFindA11yNodesFunctions; private Callable<Boolean> mPerformA11yAction; Loading Loading @@ -177,14 +180,22 @@ public class AbstractAccessibilityServiceConnectionTest { when(mMockPackageManager.hasSystemFeature(FEATURE_FINGERPRINT)).thenReturn(true); // Fake a11yWindowInfo and remote a11y connection for tests. addA11yWindowInfo(mA11yWindowInfos, WINDOWID, false); addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true); addA11yWindowInfo(mA11yWindowInfos, WINDOWID, false, Display.DEFAULT_DISPLAY); addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true, Display.DEFAULT_DISPLAY); addA11yWindowInfo(mA11yWindowInfosOnSecondDisplay, WINDOWID_ONSECONDDISPLAY, false, SECONDARY_DISPLAY_ID); when(mMockA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)) .thenReturn(mA11yWindowInfos); when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID)) .thenReturn(mA11yWindowInfos.get(0)); when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(PIP_WINDOWID)) .thenReturn(mA11yWindowInfos.get(1)); when(mMockA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked(USER_ID, WINDOWID_ONSECONDDISPLAY)).thenReturn(SECONDARY_DISPLAY_ID); when(mMockA11yWindowManager.getWindowListLocked(SECONDARY_DISPLAY_ID)) .thenReturn(mA11yWindowInfosOnSecondDisplay); when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID_ONSECONDDISPLAY)) .thenReturn(mA11yWindowInfosOnSecondDisplay.get(0)); final RemoteAccessibilityConnection conn = getRemoteA11yConnection( WINDOWID, mMockIA11yInteractionConnection, PACKAGE_NAME1); final RemoteAccessibilityConnection connPip = getRemoteA11yConnection( Loading Loading @@ -326,6 +337,12 @@ public class AbstractAccessibilityServiceConnectionTest { verify(mMockSystemSupport).onClientChangeLocked(false); } @Test public void getWindow_onNonDefaultDisplay() { assertThat(mServiceConnection.getWindow(WINDOWID_ONSECONDDISPLAY), is(mA11yWindowInfosOnSecondDisplay.get(0))); } @Test public void accessAccessibilityNodeInfo_whenCantGetInfo_returnNullOrFalse() throws Exception { Loading Loading @@ -674,9 +691,10 @@ public class AbstractAccessibilityServiceConnectionTest { } private AccessibilityWindowInfo addA11yWindowInfo(List<AccessibilityWindowInfo> infos, int windowId, boolean isPip) { int windowId, boolean isPip, int displayId) { final AccessibilityWindowInfo info = AccessibilityWindowInfo.obtain(); info.setId(windowId); info.setDisplayId(displayId); info.setPictureInPicture(isPip); infos.add(info); return info; Loading Loading
services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +16 −11 Original line number Diff line number Diff line Loading @@ -352,7 +352,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ @Override public List<AccessibilityWindowInfo> getWindows() { ensureWindowsAvailableTimed(); ensureWindowsAvailableTimed(Display.DEFAULT_DISPLAY); synchronized (mLock) { if (!hasRightsToCurrentUserLocked()) { return null; Loading @@ -362,8 +362,6 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ if (!permissionGranted) { return null; } // TODO [Multi-Display] (b/134891479) : // using correct display Id to replace DEFAULT_DISPLAY. List<AccessibilityWindowInfo> internalWindowList = mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY); if (internalWindowList == null) { Loading @@ -387,7 +385,14 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ @Override public AccessibilityWindowInfo getWindow(int windowId) { ensureWindowsAvailableTimed(); int displayId = Display.INVALID_DISPLAY; synchronized (mLock) { if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked( mSystemSupport.getCurrentUserIdLocked(), windowId); } } ensureWindowsAvailableTimed(displayId); synchronized (mLock) { if (!hasRightsToCurrentUserLocked()) { return null; Loading Loading @@ -1308,28 +1313,28 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ /** * Request that the system make sure windows are available to interrogate. * * @param displayId The logical display id. */ private void ensureWindowsAvailableTimed() { private void ensureWindowsAvailableTimed(int displayId) { synchronized (mLock) { // TODO [Multi-Display] (b/134891479) : // using correct display Id to replace DEFAULT_DISPLAY. if (mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY) != null) { if (mA11yWindowManager.getWindowListLocked(displayId) != null) { return; } // If we have no registered callback, update the state we // we may have to register one but it didn't happen yet. if (!mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY)) { if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) { // Invokes client change to make sure tracking window enabled. mSystemSupport.onClientChangeLocked(false); } // We have no windows but do not care about them, done. if (!mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY)) { if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) { return; } // Wait for the windows with a timeout. final long startMillis = SystemClock.uptimeMillis(); while (mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY) == null) { while (mA11yWindowManager.getWindowListLocked(displayId) == null) { final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis; if (remainMillis <= 0) { Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +11 −4 Original line number Diff line number Diff line Loading @@ -580,17 +580,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // Make sure clients receiving this event will be able to get the // current state of the windows as the window manager may be delaying // the computation for performance reasons. // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY. boolean shouldComputeWindows = false; int displayId = Display.INVALID_DISPLAY; synchronized (mLock) { final int windowId = event.getWindowId(); if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY)) { && windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked( mCurrentUserId, windowId); } if (displayId != Display.INVALID_DISPLAY && mA11yWindowManager.isTrackingWindowsLocked(displayId)) { shouldComputeWindows = true; } } if (shouldComputeWindows) { WindowManagerInternal wm = LocalServices.getService(WindowManagerInternal.class); wm.computeWindowsForAccessibility(Display.DEFAULT_DISPLAY); final WindowManagerInternal wm = LocalServices.getService( WindowManagerInternal.class); wm.computeWindowsForAccessibility(displayId); } synchronized (mLock) { notifyAccessibilityServicesDelayedLocked(event, false); Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -1462,6 +1462,20 @@ public class AccessibilityWindowManager { } } /** * Returns the display ID according to given userId and windowId. * * @param userId The userId * @param windowId The windowId * @return The display ID */ public int getDisplayIdByUserIdAndWindowIdLocked(int userId, int windowId) { final IBinder windowToken = getWindowTokenForUserAndWindowIdLocked(userId, windowId); final int displayId = mWindowManagerInternal.getDisplayIdForWindow(windowToken); return displayId; } /** * Gets current input focused window token from window manager, and returns its windowId. * Loading
services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java +21 −3 Original line number Diff line number Diff line Loading @@ -111,6 +111,8 @@ public class AbstractAccessibilityServiceConnectionTest { private static final String VIEW_TEXT = "test_view_text"; private static final int WINDOWID = 12; private static final int PIP_WINDOWID = 13; private static final int WINDOWID_ONSECONDDISPLAY = 14; private static final int SECONDARY_DISPLAY_ID = Display.DEFAULT_DISPLAY + 1; private static final int SERVICE_ID = 42; private static final int A11Y_SERVICE_CAPABILITY = CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT | CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION Loading @@ -135,6 +137,7 @@ public class AbstractAccessibilityServiceConnectionTest { private AbstractAccessibilityServiceConnection mServiceConnection; private MessageCapturingHandler mHandler = new MessageCapturingHandler(null); private final List<AccessibilityWindowInfo> mA11yWindowInfos = new ArrayList<>(); private final List<AccessibilityWindowInfo> mA11yWindowInfosOnSecondDisplay = new ArrayList<>(); private Callable[] mFindA11yNodesFunctions; private Callable<Boolean> mPerformA11yAction; Loading Loading @@ -177,14 +180,22 @@ public class AbstractAccessibilityServiceConnectionTest { when(mMockPackageManager.hasSystemFeature(FEATURE_FINGERPRINT)).thenReturn(true); // Fake a11yWindowInfo and remote a11y connection for tests. addA11yWindowInfo(mA11yWindowInfos, WINDOWID, false); addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true); addA11yWindowInfo(mA11yWindowInfos, WINDOWID, false, Display.DEFAULT_DISPLAY); addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true, Display.DEFAULT_DISPLAY); addA11yWindowInfo(mA11yWindowInfosOnSecondDisplay, WINDOWID_ONSECONDDISPLAY, false, SECONDARY_DISPLAY_ID); when(mMockA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)) .thenReturn(mA11yWindowInfos); when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID)) .thenReturn(mA11yWindowInfos.get(0)); when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(PIP_WINDOWID)) .thenReturn(mA11yWindowInfos.get(1)); when(mMockA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked(USER_ID, WINDOWID_ONSECONDDISPLAY)).thenReturn(SECONDARY_DISPLAY_ID); when(mMockA11yWindowManager.getWindowListLocked(SECONDARY_DISPLAY_ID)) .thenReturn(mA11yWindowInfosOnSecondDisplay); when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID_ONSECONDDISPLAY)) .thenReturn(mA11yWindowInfosOnSecondDisplay.get(0)); final RemoteAccessibilityConnection conn = getRemoteA11yConnection( WINDOWID, mMockIA11yInteractionConnection, PACKAGE_NAME1); final RemoteAccessibilityConnection connPip = getRemoteA11yConnection( Loading Loading @@ -326,6 +337,12 @@ public class AbstractAccessibilityServiceConnectionTest { verify(mMockSystemSupport).onClientChangeLocked(false); } @Test public void getWindow_onNonDefaultDisplay() { assertThat(mServiceConnection.getWindow(WINDOWID_ONSECONDDISPLAY), is(mA11yWindowInfosOnSecondDisplay.get(0))); } @Test public void accessAccessibilityNodeInfo_whenCantGetInfo_returnNullOrFalse() throws Exception { Loading Loading @@ -674,9 +691,10 @@ public class AbstractAccessibilityServiceConnectionTest { } private AccessibilityWindowInfo addA11yWindowInfo(List<AccessibilityWindowInfo> infos, int windowId, boolean isPip) { int windowId, boolean isPip, int displayId) { final AccessibilityWindowInfo info = AccessibilityWindowInfo.obtain(); info.setId(windowId); info.setDisplayId(displayId); info.setPictureInPicture(isPip); infos.add(info); return info; Loading