未验证 提交 9b4bb20a 编写于 作者: C chunhtai 提交者: GitHub

makes android semanticsnode to ignore hittest if it is not focusable (#22205)

上级 d3182bc2
...@@ -207,6 +207,11 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { ...@@ -207,6 +207,11 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
// beneath a stylus or mouse cursor. // beneath a stylus or mouse cursor.
@Nullable private SemanticsNode hoveredObject; @Nullable private SemanticsNode hoveredObject;
@VisibleForTesting
public int getHoveredObjectId() {
return hoveredObject.id;
}
// A Java/Android cached representation of the Flutter app's navigation stack. The Flutter // A Java/Android cached representation of the Flutter app's navigation stack. The Flutter
// navigation stack is tracked so that accessibility announcements can be made during Flutter's // navigation stack is tracked so that accessibility announcements can be made during Flutter's
// navigation changes. // navigation changes.
...@@ -2180,7 +2185,7 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { ...@@ -2180,7 +2185,7 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
return result; return result;
} }
} }
return this; return isFocusable() ? this : null;
} }
// TODO(goderbauer): This should be decided by the framework once we have more information // TODO(goderbauer): This should be decided by the framework once we have more information
......
...@@ -204,6 +204,70 @@ public class AccessibilityBridgeTest { ...@@ -204,6 +204,70 @@ public class AccessibilityBridgeTest {
assertEquals(sentences.get(0).toString(), "new_node2"); assertEquals(sentences.get(0).toString(), "new_node2");
} }
@Test
public void itIgnoresUnfocusableNodeDuringHitTest() {
AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class);
AccessibilityManager mockManager = mock(AccessibilityManager.class);
View mockRootView = mock(View.class);
Context context = mock(Context.class);
when(mockRootView.getContext()).thenReturn(context);
when(context.getPackageName()).thenReturn("test");
AccessibilityBridge accessibilityBridge =
setUpBridge(mockRootView, mockManager, mockViewEmbedder);
ViewParent mockParent = mock(ViewParent.class);
when(mockRootView.getParent()).thenReturn(mockParent);
when(mockManager.isEnabled()).thenReturn(true);
when(mockManager.isTouchExplorationEnabled()).thenReturn(true);
TestSemanticsNode root = new TestSemanticsNode();
root.id = 0;
root.left = 0;
root.top = 0;
root.bottom = 20;
root.right = 20;
TestSemanticsNode ignored = new TestSemanticsNode();
ignored.id = 1;
ignored.addFlag(AccessibilityBridge.Flag.SCOPES_ROUTE);
ignored.left = 0;
ignored.top = 0;
ignored.bottom = 20;
ignored.right = 20;
root.children.add(ignored);
TestSemanticsNode child = new TestSemanticsNode();
child.id = 2;
child.label = "label";
child.left = 0;
child.top = 0;
child.bottom = 20;
child.right = 20;
root.children.add(child);
TestSemanticsUpdate testSemanticsUpdate = root.toUpdate();
accessibilityBridge.updateSemantics(testSemanticsUpdate.buffer, testSemanticsUpdate.strings);
ArgumentCaptor<AccessibilityEvent> eventCaptor =
ArgumentCaptor.forClass(AccessibilityEvent.class);
verify(mockParent, times(2))
.requestSendAccessibilityEvent(eq(mockRootView), eventCaptor.capture());
AccessibilityEvent event = eventCaptor.getAllValues().get(0);
assertEquals(event.getEventType(), AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
// Synthesize an accessibility hit test event.
MotionEvent mockEvent = mock(MotionEvent.class);
when(mockEvent.getX()).thenReturn(10.0f);
when(mockEvent.getY()).thenReturn(10.0f);
when(mockEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
boolean hit = accessibilityBridge.onAccessibilityHoverEvent(mockEvent);
assertEquals(hit, true);
eventCaptor = ArgumentCaptor.forClass(AccessibilityEvent.class);
verify(mockParent, times(3))
.requestSendAccessibilityEvent(eq(mockRootView), eventCaptor.capture());
event = eventCaptor.getAllValues().get(2);
assertEquals(event.getEventType(), AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
assertEquals(accessibilityBridge.getHoveredObjectId(), 2);
}
@Test @Test
public void itAnnouncesRouteNameWhenRemoveARoute() { public void itAnnouncesRouteNameWhenRemoveARoute() {
AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class); AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册