未验证 提交 b1ccc417 编写于 作者: Z Zachary Anderson 提交者: GitHub

Revert "Sets focus before sending a11y focus event in Android (#27992)" (#28092)

This reverts commit 56cf8198.
上级 5ba9ed51
...@@ -1020,33 +1020,28 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { ...@@ -1020,33 +1020,28 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
} }
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
{ {
// Focused semantics node must be reset before sending the
// TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED event. Otherwise,
// TalkBack may think the node is still focused.
accessibilityFocusedSemanticsNode = null;
embeddedAccessibilityFocusedNodeId = null;
accessibilityChannel.dispatchSemanticsAction( accessibilityChannel.dispatchSemanticsAction(
virtualViewId, Action.DID_LOSE_ACCESSIBILITY_FOCUS); virtualViewId, Action.DID_LOSE_ACCESSIBILITY_FOCUS);
sendAccessibilityEvent( sendAccessibilityEvent(
virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
accessibilityFocusedSemanticsNode = null;
embeddedAccessibilityFocusedNodeId = null;
return true; return true;
} }
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
{ {
accessibilityChannel.dispatchSemanticsAction(
virtualViewId, Action.DID_GAIN_ACCESSIBILITY_FOCUS);
sendAccessibilityEvent(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
if (accessibilityFocusedSemanticsNode == null) { if (accessibilityFocusedSemanticsNode == null) {
// When Android focuses a node, it doesn't invalidate the view. // When Android focuses a node, it doesn't invalidate the view.
// (It does when it sends ACTION_CLEAR_ACCESSIBILITY_FOCUS, so // (It does when it sends ACTION_CLEAR_ACCESSIBILITY_FOCUS, so
// we only have to worry about this when the focused node is null.) // we only have to worry about this when the focused node is null.)
rootAccessibilityView.invalidate(); rootAccessibilityView.invalidate();
} }
// Focused semantics node must be set before sending the TYPE_VIEW_ACCESSIBILITY_FOCUSED
// event. Otherwise, TalkBack may think the node is not focused yet.
accessibilityFocusedSemanticsNode = semanticsNode; accessibilityFocusedSemanticsNode = semanticsNode;
accessibilityChannel.dispatchSemanticsAction(
virtualViewId, Action.DID_GAIN_ACCESSIBILITY_FOCUS);
sendAccessibilityEvent(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
if (semanticsNode.hasAction(Action.INCREASE) if (semanticsNode.hasAction(Action.INCREASE)
|| semanticsNode.hasAction(Action.DECREASE)) { || semanticsNode.hasAction(Action.DECREASE)) {
// SeekBars only announce themselves after this event. // SeekBars only announce themselves after this event.
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package io.flutter.view; package io.flutter.view;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
...@@ -47,7 +46,6 @@ import java.util.List; ...@@ -47,7 +46,6 @@ import java.util.List;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
...@@ -800,122 +798,6 @@ public class AccessibilityBridgeTest { ...@@ -800,122 +798,6 @@ public class AccessibilityBridgeTest {
assertEquals(nodeInfo.getTextSelectionEnd(), expectedEnd); assertEquals(nodeInfo.getTextSelectionEnd(), expectedEnd);
} }
@Test
public void itSetsFocusedNodeBeforeSendingEvent() {
AccessibilityChannel mockChannel = mock(AccessibilityChannel.class);
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(
/*rootAccessibilityView=*/ mockRootView,
/*accessibilityChannel=*/ mockChannel,
/*accessibilityManager=*/ mockManager,
/*contentResolver=*/ null,
/*accessibilityViewEmbedder=*/ mockViewEmbedder,
/*platformViewsAccessibilityDelegate=*/ null);
ViewParent mockParent = mock(ViewParent.class);
when(mockRootView.getParent()).thenReturn(mockParent);
when(mockManager.isEnabled()).thenReturn(true);
TestSemanticsNode root = new TestSemanticsNode();
root.id = 0;
root.label = "root";
TestSemanticsUpdate testSemanticsUpdate = root.toUpdate();
testSemanticsUpdate.sendUpdateToBridge(accessibilityBridge);
class Verifier {
public Verifier(AccessibilityBridge accessibilityBridge) {
this.accessibilityBridge = accessibilityBridge;
}
public AccessibilityBridge accessibilityBridge;
public boolean verified = false;
public boolean verify(InvocationOnMock invocation) {
AccessibilityEvent event = (AccessibilityEvent) invocation.getArguments()[1];
assertEquals(event.getEventType(), AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
// The accessibility focus must be set before sending out
// the TYPE_VIEW_ACCESSIBILITY_FOCUSED event.
AccessibilityNodeInfo nodeInfo = accessibilityBridge.createAccessibilityNodeInfo(0);
assertTrue(nodeInfo.isAccessibilityFocused());
verified = true;
return true;
}
};
Verifier verifier = new Verifier(accessibilityBridge);
when(mockParent.requestSendAccessibilityEvent(eq(mockRootView), any(AccessibilityEvent.class)))
.thenAnswer(invocation -> verifier.verify(invocation));
accessibilityBridge.performAction(0, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
assertTrue(verifier.verified);
}
@Test
public void itClearsFocusedNodeBeforeSendingEvent() {
AccessibilityChannel mockChannel = mock(AccessibilityChannel.class);
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(
/*rootAccessibilityView=*/ mockRootView,
/*accessibilityChannel=*/ mockChannel,
/*accessibilityManager=*/ mockManager,
/*contentResolver=*/ null,
/*accessibilityViewEmbedder=*/ mockViewEmbedder,
/*platformViewsAccessibilityDelegate=*/ null);
ViewParent mockParent = mock(ViewParent.class);
when(mockRootView.getParent()).thenReturn(mockParent);
when(mockManager.isEnabled()).thenReturn(true);
TestSemanticsNode root = new TestSemanticsNode();
root.id = 0;
root.label = "root";
TestSemanticsUpdate testSemanticsUpdate = root.toUpdate();
testSemanticsUpdate.sendUpdateToBridge(accessibilityBridge);
// Set the focus on root.
accessibilityBridge.performAction(0, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
AccessibilityNodeInfo nodeInfo = accessibilityBridge.createAccessibilityNodeInfo(0);
assertTrue(nodeInfo.isAccessibilityFocused());
class Verifier {
public Verifier(AccessibilityBridge accessibilityBridge) {
this.accessibilityBridge = accessibilityBridge;
}
public AccessibilityBridge accessibilityBridge;
public boolean verified = false;
public boolean verify(InvocationOnMock invocation) {
AccessibilityEvent event = (AccessibilityEvent) invocation.getArguments()[1];
assertEquals(
event.getEventType(), AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
// The accessibility focus must be cleared before sending out
// the TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED event.
AccessibilityNodeInfo nodeInfo = accessibilityBridge.createAccessibilityNodeInfo(0);
assertFalse(nodeInfo.isAccessibilityFocused());
verified = true;
return true;
}
};
Verifier verifier = new Verifier(accessibilityBridge);
when(mockParent.requestSendAccessibilityEvent(eq(mockRootView), any(AccessibilityEvent.class)))
.thenAnswer(invocation -> verifier.verify(invocation));
accessibilityBridge.performAction(
0, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
assertTrue(verifier.verified);
}
@Test @Test
public void itCanPredictCursorMovementsWithGranularityWord() { public void itCanPredictCursorMovementsWithGranularityWord() {
AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); AccessibilityChannel mockChannel = mock(AccessibilityChannel.class);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册