Merge "Populate display id in A11yWindowManager"
This commit is contained in:
committed by
Android (Google) Code Review
commit
7b1c680e16
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1522,38 +1521,59 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -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)));
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user