Loading core/java/android/view/accessibility/AccessibilityEvent.java +3 −1 Original line number Diff line number Diff line Loading @@ -1332,6 +1332,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * Convenience method to obtain a {@link #TYPE_WINDOWS_CHANGED} event for a specific window and * change set. * * @param displayId The ID of the display from which the event comes from * @param windowId The ID of the window that changed * @param windowChangeTypes The changes to populate * @return An instance of a TYPE_WINDOWS_CHANGED, populated with the requested fields and with Loading @@ -1340,8 +1341,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * @hide */ public static AccessibilityEvent obtainWindowsChangedEvent( int windowId, int windowChangeTypes) { int displayId, int windowId, int windowChangeTypes) { final AccessibilityEvent event = new AccessibilityEvent(TYPE_WINDOWS_CHANGED); event.setDisplayId(displayId); event.setWindowId(windowId); event.setWindowChanges(windowChangeTypes); event.setImportantForAccessibility(true); Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +3 −2 Original line number Diff line number Diff line Loading @@ -957,10 +957,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // current state of the windows as the window manager may be delaying // the computation for performance reasons. boolean shouldComputeWindows = false; int displayId = Display.INVALID_DISPLAY; int displayId = event.getDisplayId(); synchronized (mLock) { final int windowId = event.getWindowId(); if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID && displayId == Display.INVALID_DISPLAY) { displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked( resolvedUserId, windowId); event.setDisplayId(displayId); Loading services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java +44 −24 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.server.accessibility; import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; Loading Loading @@ -275,22 +274,23 @@ public class AccessibilityWindowManager { * Sets the active flag of the window according to given windowId, others set to inactive. * * @param windowId The windowId * @return {@code true} if the window is in this display, {@code false} otherwise. */ void setActiveWindowLocked(int windowId) { boolean setActiveWindowLocked(int windowId) { boolean foundWindow = false; if (mWindows != null) { final int windowCount = mWindows.size(); for (int i = 0; i < windowCount; i++) { AccessibilityWindowInfo window = mWindows.get(i); if (window.getId() == windowId) { window.setActive(true); mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent(windowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)); foundWindow = true; } else { window.setActive(false); } } } return foundWindow; } /** Loading @@ -298,24 +298,23 @@ public class AccessibilityWindowManager { * unfocused. * * @param windowId The windowId * @return {@code true} if the window is in this display, {@code false} otherwise. */ void setAccessibilityFocusedWindowLocked(int windowId) { boolean setAccessibilityFocusedWindowLocked(int windowId) { boolean foundWindow = false; if (mWindows != null) { final int windowCount = mWindows.size(); for (int i = 0; i < windowCount; i++) { AccessibilityWindowInfo window = mWindows.get(i); if (window.getId() == windowId) { mAccessibilityFocusedDisplayId = mDisplayId; window.setAccessibilityFocused(true); mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent( windowId, WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); foundWindow = true; } else { window.setAccessibilityFocused(false); } } } return foundWindow; } /** Loading Loading @@ -704,7 +703,7 @@ public class AccessibilityWindowManager { final AccessibilityWindowInfo window = oldWindows.get(i); if (mA11yWindowInfoById.get(window.getId()) == null) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( window.getId(), AccessibilityEvent.WINDOWS_CHANGE_REMOVED)); mDisplayId, window.getId(), AccessibilityEvent.WINDOWS_CHANGE_REMOVED)); } } Loading @@ -714,13 +713,13 @@ public class AccessibilityWindowManager { final AccessibilityWindowInfo newWindow = mWindows.get(i); final AccessibilityWindowInfo oldWindow = oldWindowsById.get(newWindow.getId()); if (oldWindow == null) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( events.add(AccessibilityEvent.obtainWindowsChangedEvent(mDisplayId, newWindow.getId(), AccessibilityEvent.WINDOWS_CHANGE_ADDED)); } else { int changes = newWindow.differenceFrom(oldWindow); if (changes != 0) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( newWindow.getId(), changes)); mDisplayId, newWindow.getId(), changes)); } } } Loading Loading @@ -1522,37 +1521,58 @@ public class AccessibilityWindowManager { private void setActiveWindowLocked(int windowId) { if (mActiveWindowId != windowId) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent( List<AccessibilityEvent> events = new ArrayList<>(2); if (mActiveWindowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { final DisplayWindowsObserver observer = getDisplayWindowObserverByWindowIdLocked(mActiveWindowId); if (observer != null) { events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId, mActiveWindowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)); } } mActiveWindowId = windowId; // Goes through all windows for each display. final int count = mDisplayWindowsObservers.size(); for (int i = 0; i < count; i++) { final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i); if (observer != null) { observer.setActiveWindowLocked(windowId); if (observer != null && observer.setActiveWindowLocked(windowId)) { events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId, windowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)); } } for (final AccessibilityEvent event : events) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(event); } } } private void setAccessibilityFocusedWindowLocked(int windowId) { if (mAccessibilityFocusedWindowId != windowId) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent( mAccessibilityFocusedWindowId, WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); List<AccessibilityEvent> events = new ArrayList<>(2); if (mAccessibilityFocusedDisplayId != Display.INVALID_DISPLAY && mAccessibilityFocusedWindowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( mAccessibilityFocusedDisplayId, mAccessibilityFocusedWindowId, AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); } mAccessibilityFocusedWindowId = windowId; // Goes through all windows for each display. final int count = mDisplayWindowsObservers.size(); for (int i = 0; i < count; i++) { final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i); if (observer != null) { observer.setAccessibilityFocusedWindowLocked(windowId); if (observer != null && observer.setAccessibilityFocusedWindowLocked(windowId)) { mAccessibilityFocusedDisplayId = observer.mDisplayId; events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId, windowId, AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); } } for (final AccessibilityEvent event : events) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(event); } } } Loading services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java +157 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.accessibility; import static com.android.server.accessibility.AccessibilityWindowManagerTest.DisplayIdMatcher.displayId; import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowChangesMatcher.a11yWindowChanges; import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.a11yWindowId; Loading Loading @@ -587,10 +588,12 @@ public class AccessibilityWindowManagerTest { verify(mMockA11yEventSender, times(2)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(a11yWindowId(currentActiveWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(currentActiveWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); assertThat(captor.getAllValues().get(1), allOf(a11yWindowId(eventWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(eventWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); } Loading @@ -600,9 +603,58 @@ public class AccessibilityWindowManagerTest { DEFAULT_FOCUSED_INDEX); final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId( AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); assertThat(currentA11yFocusedWindowId, is(not(eventWindowId))); assertThat(currentA11yFocusedWindowId, is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)); final int noUse = 0; mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID, eventWindowId, AccessibilityNodeInfo.ROOT_NODE_ID, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, noUse); assertThat(mA11yWindowManager.getFocusedWindowId( AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId)); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(eventWindowId), a11yWindowChanges( AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED))); } @Test public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_defaultToSecondary() throws RemoteException { runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest( Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID); } @Test public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_SecondaryToDefault() throws RemoteException { runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest( SECONDARY_DISPLAY_ID, Display.DEFAULT_DISPLAY); } private void runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest( int initialDisplayId, int eventDisplayId) throws RemoteException { startTrackingPerDisplay(SECONDARY_DISPLAY_ID); final int initialWindowId = getWindowIdFromWindowInfosForDisplay( initialDisplayId, DEFAULT_FOCUSED_INDEX); final int noUse = 0; mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID, initialWindowId, AccessibilityNodeInfo.ROOT_NODE_ID, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, noUse); assertThat(mA11yWindowManager.getFocusedWindowId( AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(initialWindowId)); Mockito.reset(mMockA11yEventSender); final int eventWindowId = getWindowIdFromWindowInfosForDisplay( eventDisplayId, DEFAULT_FOCUSED_INDEX); mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID, eventWindowId, AccessibilityNodeInfo.ROOT_NODE_ID, Loading @@ -615,11 +667,13 @@ public class AccessibilityWindowManagerTest { verify(mMockA11yEventSender, times(2)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(a11yWindowId(currentA11yFocusedWindowId), allOf(displayId(initialDisplayId), a11yWindowId(initialWindowId), a11yWindowChanges( AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED))); assertThat(captor.getAllValues().get(1), allOf(a11yWindowId(eventWindowId), allOf(displayId(eventDisplayId), a11yWindowId(eventWindowId), a11yWindowChanges( AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED))); } Loading Loading @@ -674,10 +728,12 @@ public class AccessibilityWindowManagerTest { verify(mMockA11yEventSender, times(2)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(a11yWindowId(eventWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(eventWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); assertThat(captor.getAllValues().get(1), allOf(a11yWindowId(currentActiveWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(currentActiveWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); } Loading Loading @@ -861,6 +917,77 @@ public class AccessibilityWindowManagerTest { assertTrue(TextUtils.equals(layoutParams.accessibilityTitle, a11yWindow.getTitle())); } @Test public void sendAccessibilityEventOnWindowRemoval() { final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY); // Removing index 0 because it's not focused, and avoids unnecessary layer change. final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0); infos.remove(0); for (WindowInfo info : infos) { // Adjust layer number because it should start from 0. info.layer--; } onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(windowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED))); } @Test public void sendAccessibilityEventOnWindowAddition() throws RemoteException { final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY); for (WindowInfo info : infos) { // Adjust layer number because new window will have 0 so that layer number in // A11yWindowInfo in window won't be changed. info.layer++; } final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY, false, USER_SYSTEM_ID); addWindowInfo(infos, token, 0); final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, infos.size() - 1); onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(windowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED))); } @Test public void sendAccessibilityEventOnWindowChange() { final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY); infos.get(0).title = "new title"; final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0); onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(windowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE))); } private void registerLeashedTokenAndWindowId() { mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID); mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID); Loading Loading @@ -1018,6 +1145,29 @@ public class AccessibilityWindowManagerTest { } } static class DisplayIdMatcher extends TypeSafeMatcher<AccessibilityEvent> { private final int mDisplayId; DisplayIdMatcher(int displayId) { super(); mDisplayId = displayId; } static DisplayIdMatcher displayId(int displayId) { return new DisplayIdMatcher(displayId); } @Override protected boolean matchesSafely(AccessibilityEvent event) { return event.getDisplayId() == mDisplayId; } @Override public void describeTo(Description description) { description.appendText("Matching to displayId " + mDisplayId); } } static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> { private int mWindowId; Loading Loading
core/java/android/view/accessibility/AccessibilityEvent.java +3 −1 Original line number Diff line number Diff line Loading @@ -1332,6 +1332,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * Convenience method to obtain a {@link #TYPE_WINDOWS_CHANGED} event for a specific window and * change set. * * @param displayId The ID of the display from which the event comes from * @param windowId The ID of the window that changed * @param windowChangeTypes The changes to populate * @return An instance of a TYPE_WINDOWS_CHANGED, populated with the requested fields and with Loading @@ -1340,8 +1341,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * @hide */ public static AccessibilityEvent obtainWindowsChangedEvent( int windowId, int windowChangeTypes) { int displayId, int windowId, int windowChangeTypes) { final AccessibilityEvent event = new AccessibilityEvent(TYPE_WINDOWS_CHANGED); event.setDisplayId(displayId); event.setWindowId(windowId); event.setWindowChanges(windowChangeTypes); event.setImportantForAccessibility(true); Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +3 −2 Original line number Diff line number Diff line Loading @@ -957,10 +957,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // current state of the windows as the window manager may be delaying // the computation for performance reasons. boolean shouldComputeWindows = false; int displayId = Display.INVALID_DISPLAY; int displayId = event.getDisplayId(); synchronized (mLock) { final int windowId = event.getWindowId(); if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID && displayId == Display.INVALID_DISPLAY) { displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked( resolvedUserId, windowId); event.setDisplayId(displayId); Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java +44 −24 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.server.accessibility; import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; Loading Loading @@ -275,22 +274,23 @@ public class AccessibilityWindowManager { * Sets the active flag of the window according to given windowId, others set to inactive. * * @param windowId The windowId * @return {@code true} if the window is in this display, {@code false} otherwise. */ void setActiveWindowLocked(int windowId) { boolean setActiveWindowLocked(int windowId) { boolean foundWindow = false; if (mWindows != null) { final int windowCount = mWindows.size(); for (int i = 0; i < windowCount; i++) { AccessibilityWindowInfo window = mWindows.get(i); if (window.getId() == windowId) { window.setActive(true); mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent(windowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)); foundWindow = true; } else { window.setActive(false); } } } return foundWindow; } /** Loading @@ -298,24 +298,23 @@ public class AccessibilityWindowManager { * unfocused. * * @param windowId The windowId * @return {@code true} if the window is in this display, {@code false} otherwise. */ void setAccessibilityFocusedWindowLocked(int windowId) { boolean setAccessibilityFocusedWindowLocked(int windowId) { boolean foundWindow = false; if (mWindows != null) { final int windowCount = mWindows.size(); for (int i = 0; i < windowCount; i++) { AccessibilityWindowInfo window = mWindows.get(i); if (window.getId() == windowId) { mAccessibilityFocusedDisplayId = mDisplayId; window.setAccessibilityFocused(true); mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent( windowId, WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); foundWindow = true; } else { window.setAccessibilityFocused(false); } } } return foundWindow; } /** Loading Loading @@ -704,7 +703,7 @@ public class AccessibilityWindowManager { final AccessibilityWindowInfo window = oldWindows.get(i); if (mA11yWindowInfoById.get(window.getId()) == null) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( window.getId(), AccessibilityEvent.WINDOWS_CHANGE_REMOVED)); mDisplayId, window.getId(), AccessibilityEvent.WINDOWS_CHANGE_REMOVED)); } } Loading @@ -714,13 +713,13 @@ public class AccessibilityWindowManager { final AccessibilityWindowInfo newWindow = mWindows.get(i); final AccessibilityWindowInfo oldWindow = oldWindowsById.get(newWindow.getId()); if (oldWindow == null) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( events.add(AccessibilityEvent.obtainWindowsChangedEvent(mDisplayId, newWindow.getId(), AccessibilityEvent.WINDOWS_CHANGE_ADDED)); } else { int changes = newWindow.differenceFrom(oldWindow); if (changes != 0) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( newWindow.getId(), changes)); mDisplayId, newWindow.getId(), changes)); } } } Loading Loading @@ -1522,37 +1521,58 @@ public class AccessibilityWindowManager { private void setActiveWindowLocked(int windowId) { if (mActiveWindowId != windowId) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent( List<AccessibilityEvent> events = new ArrayList<>(2); if (mActiveWindowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { final DisplayWindowsObserver observer = getDisplayWindowObserverByWindowIdLocked(mActiveWindowId); if (observer != null) { events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId, mActiveWindowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)); } } mActiveWindowId = windowId; // Goes through all windows for each display. final int count = mDisplayWindowsObservers.size(); for (int i = 0; i < count; i++) { final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i); if (observer != null) { observer.setActiveWindowLocked(windowId); if (observer != null && observer.setActiveWindowLocked(windowId)) { events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId, windowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)); } } for (final AccessibilityEvent event : events) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(event); } } } private void setAccessibilityFocusedWindowLocked(int windowId) { if (mAccessibilityFocusedWindowId != windowId) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked( AccessibilityEvent.obtainWindowsChangedEvent( mAccessibilityFocusedWindowId, WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); List<AccessibilityEvent> events = new ArrayList<>(2); if (mAccessibilityFocusedDisplayId != Display.INVALID_DISPLAY && mAccessibilityFocusedWindowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { events.add(AccessibilityEvent.obtainWindowsChangedEvent( mAccessibilityFocusedDisplayId, mAccessibilityFocusedWindowId, AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); } mAccessibilityFocusedWindowId = windowId; // Goes through all windows for each display. final int count = mDisplayWindowsObservers.size(); for (int i = 0; i < count; i++) { final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i); if (observer != null) { observer.setAccessibilityFocusedWindowLocked(windowId); if (observer != null && observer.setAccessibilityFocusedWindowLocked(windowId)) { mAccessibilityFocusedDisplayId = observer.mDisplayId; events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId, windowId, AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)); } } for (final AccessibilityEvent event : events) { mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(event); } } } Loading
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java +157 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.accessibility; import static com.android.server.accessibility.AccessibilityWindowManagerTest.DisplayIdMatcher.displayId; import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowChangesMatcher.a11yWindowChanges; import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.a11yWindowId; Loading Loading @@ -587,10 +588,12 @@ public class AccessibilityWindowManagerTest { verify(mMockA11yEventSender, times(2)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(a11yWindowId(currentActiveWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(currentActiveWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); assertThat(captor.getAllValues().get(1), allOf(a11yWindowId(eventWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(eventWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); } Loading @@ -600,9 +603,58 @@ public class AccessibilityWindowManagerTest { DEFAULT_FOCUSED_INDEX); final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId( AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); assertThat(currentA11yFocusedWindowId, is(not(eventWindowId))); assertThat(currentA11yFocusedWindowId, is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)); final int noUse = 0; mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID, eventWindowId, AccessibilityNodeInfo.ROOT_NODE_ID, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, noUse); assertThat(mA11yWindowManager.getFocusedWindowId( AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId)); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(eventWindowId), a11yWindowChanges( AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED))); } @Test public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_defaultToSecondary() throws RemoteException { runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest( Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID); } @Test public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_SecondaryToDefault() throws RemoteException { runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest( SECONDARY_DISPLAY_ID, Display.DEFAULT_DISPLAY); } private void runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest( int initialDisplayId, int eventDisplayId) throws RemoteException { startTrackingPerDisplay(SECONDARY_DISPLAY_ID); final int initialWindowId = getWindowIdFromWindowInfosForDisplay( initialDisplayId, DEFAULT_FOCUSED_INDEX); final int noUse = 0; mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID, initialWindowId, AccessibilityNodeInfo.ROOT_NODE_ID, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, noUse); assertThat(mA11yWindowManager.getFocusedWindowId( AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(initialWindowId)); Mockito.reset(mMockA11yEventSender); final int eventWindowId = getWindowIdFromWindowInfosForDisplay( eventDisplayId, DEFAULT_FOCUSED_INDEX); mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID, eventWindowId, AccessibilityNodeInfo.ROOT_NODE_ID, Loading @@ -615,11 +667,13 @@ public class AccessibilityWindowManagerTest { verify(mMockA11yEventSender, times(2)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(a11yWindowId(currentA11yFocusedWindowId), allOf(displayId(initialDisplayId), a11yWindowId(initialWindowId), a11yWindowChanges( AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED))); assertThat(captor.getAllValues().get(1), allOf(a11yWindowId(eventWindowId), allOf(displayId(eventDisplayId), a11yWindowId(eventWindowId), a11yWindowChanges( AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED))); } Loading Loading @@ -674,10 +728,12 @@ public class AccessibilityWindowManagerTest { verify(mMockA11yEventSender, times(2)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(a11yWindowId(eventWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(eventWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); assertThat(captor.getAllValues().get(1), allOf(a11yWindowId(currentActiveWindowId), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(currentActiveWindowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE))); } Loading Loading @@ -861,6 +917,77 @@ public class AccessibilityWindowManagerTest { assertTrue(TextUtils.equals(layoutParams.accessibilityTitle, a11yWindow.getTitle())); } @Test public void sendAccessibilityEventOnWindowRemoval() { final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY); // Removing index 0 because it's not focused, and avoids unnecessary layer change. final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0); infos.remove(0); for (WindowInfo info : infos) { // Adjust layer number because it should start from 0. info.layer--; } onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(windowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED))); } @Test public void sendAccessibilityEventOnWindowAddition() throws RemoteException { final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY); for (WindowInfo info : infos) { // Adjust layer number because new window will have 0 so that layer number in // A11yWindowInfo in window won't be changed. info.layer++; } final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY, false, USER_SYSTEM_ID); addWindowInfo(infos, token, 0); final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, infos.size() - 1); onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(windowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED))); } @Test public void sendAccessibilityEventOnWindowChange() { final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY); infos.get(0).title = "new title"; final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0); onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND); final ArgumentCaptor<AccessibilityEvent> captor = ArgumentCaptor.forClass(AccessibilityEvent.class); verify(mMockA11yEventSender, times(1)) .sendAccessibilityEventForCurrentUserLocked(captor.capture()); assertThat(captor.getAllValues().get(0), allOf(displayId(Display.DEFAULT_DISPLAY), a11yWindowId(windowId), a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE))); } private void registerLeashedTokenAndWindowId() { mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID); mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID); Loading Loading @@ -1018,6 +1145,29 @@ public class AccessibilityWindowManagerTest { } } static class DisplayIdMatcher extends TypeSafeMatcher<AccessibilityEvent> { private final int mDisplayId; DisplayIdMatcher(int displayId) { super(); mDisplayId = displayId; } static DisplayIdMatcher displayId(int displayId) { return new DisplayIdMatcher(displayId); } @Override protected boolean matchesSafely(AccessibilityEvent event) { return event.getDisplayId() == mDisplayId; } @Override public void describeTo(Description description) { description.appendText("Matching to displayId " + mDisplayId); } } static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> { private int mWindowId; Loading