Accessibility null check to catch out of bounds hitTest (flutter/engine#17833)

This commit is contained in:
Gary Qian 2020-04-21 06:16:42 -07:00 committed by GitHub
parent 1a6e99b23d
commit 05434dc4a4
2 changed files with 30 additions and 1 deletions

View File

@ -1182,7 +1182,9 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
SemanticsNode semanticsNodeUnderCursor =
getRootSemanticsNode().hitTest(new float[] {event.getX(), event.getY(), 0, 1});
if (semanticsNodeUnderCursor.platformViewId != -1) {
// semanticsNodeUnderCursor can be null when hovering over non-flutter UI such as
// the Android navigation bar due to hitTest() bounds checking.
if (semanticsNodeUnderCursor != null && semanticsNodeUnderCursor.platformViewId != -1) {
return accessibilityViewEmbedder.onAccessibilityHoverEvent(
semanticsNodeUnderCursor.id, event);
}

View File

@ -13,6 +13,7 @@ import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
@ -130,6 +131,32 @@ public class AccessibilityBridgeTest {
assertEquals(event.getEventType(), AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
}
@Test
public void itHoverOverOutOfBoundsDoesNotCrash() {
// SementicsNode.hitTest() returns null when out of bounds.
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);
// Sent a11y tree with platform view.
TestSemanticsNode root = new TestSemanticsNode();
root.id = 0;
TestSemanticsNode platformView = new TestSemanticsNode();
platformView.id = 1;
platformView.platformViewId = 42;
root.children.add(platformView);
TestSemanticsUpdate testSemanticsUpdate = root.toUpdate();
accessibilityBridge.updateSemantics(testSemanticsUpdate.buffer, testSemanticsUpdate.strings);
// Pass an out of bounds MotionEvent.
accessibilityBridge.onAccessibilityHoverEvent(MotionEvent.obtain(1, 1, 1, -10, -10, 0));
}
AccessibilityBridge setUpBridge() {
return setUpBridge(null, null, null, null, null, null);
}