Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Android] Send " did gain focus" message from engine to framework #47114

Merged
merged 8 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.dart.DartExecutor;
Expand Down Expand Up @@ -102,6 +103,13 @@ public AccessibilityChannel(@NonNull DartExecutor dartExecutor, @NonNull Flutter
this.flutterJNI = flutterJNI;
}

@VisibleForTesting
public AccessibilityChannel(
@NonNull BasicMessageChannel<Object> channel, @NonNull FlutterJNI flutterJNI) {
this.channel = channel;
this.flutterJNI = flutterJNI;
}

/**
* Informs Flutter that the Android OS currently has accessibility enabled.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,12 @@ public boolean performAction(

accessibilityChannel.dispatchSemanticsAction(
virtualViewId, Action.DID_GAIN_ACCESSIBILITY_FOCUS);

HashMap<String, Object> message = new HashMap<>();
message.put("type", "didGainFocus");
message.put("nodeId", semanticsNode.id);
accessibilityChannel.channel.send(message);

sendAccessibilityEvent(virtualViewId, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);

if (semanticsNode.hasAction(Action.INCREASE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1187,7 +1187,9 @@ public void itCanPredictSetSelection() {

@Test
public void itPerformsClearAccessibilityFocusCorrectly() {
AccessibilityChannel mockChannel = mock(AccessibilityChannel.class);
BasicMessageChannel mockChannel = mock(BasicMessageChannel.class);
AccessibilityChannel accessibilityChannel =
new AccessibilityChannel(mockChannel, mock(FlutterJNI.class));
AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class);
AccessibilityManager mockManager = mock(AccessibilityManager.class);
View mockRootView = mock(View.class);
Expand All @@ -1197,7 +1199,7 @@ public void itPerformsClearAccessibilityFocusCorrectly() {
AccessibilityBridge accessibilityBridge =
setUpBridge(
/*rootAccessibilityView=*/ mockRootView,
/*accessibilityChannel=*/ mockChannel,
/*accessibilityChannel=*/ accessibilityChannel,
/*accessibilityManager=*/ mockManager,
/*contentResolver=*/ null,
/*accessibilityViewEmbedder=*/ mockViewEmbedder,
Expand All @@ -1220,6 +1222,11 @@ public void itPerformsClearAccessibilityFocusCorrectly() {
accessibilityBridge.performAction(0, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
AccessibilityNodeInfo nodeInfo = accessibilityBridge.createAccessibilityNodeInfo(0);
assertTrue(nodeInfo.isAccessibilityFocused());

HashMap<String, Object> message = new HashMap<>();
message.put("type", "didGainFocus");
message.put("nodeId", 0);
verify(mockChannel).send(message);
// Clear focus on non-focused node shouldn't do anything
accessibilityBridge.performAction(
1, AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
Expand Down Expand Up @@ -1310,7 +1317,10 @@ public void itSetsBoldTextFlagCorrectly() {

@Test
public void itSetsFocusedNodeBeforeSendingEvent() {
AccessibilityChannel mockChannel = mock(AccessibilityChannel.class);
BasicMessageChannel mockChannel = mock(BasicMessageChannel.class);
AccessibilityChannel accessibilityChannel =
new AccessibilityChannel(mockChannel, mock(FlutterJNI.class));

AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class);
AccessibilityManager mockManager = mock(AccessibilityManager.class);
View mockRootView = mock(View.class);
Expand All @@ -1320,7 +1330,7 @@ public void itSetsFocusedNodeBeforeSendingEvent() {
AccessibilityBridge accessibilityBridge =
setUpBridge(
/*rootAccessibilityView=*/ mockRootView,
/*accessibilityChannel=*/ mockChannel,
/*accessibilityChannel=*/ accessibilityChannel,
/*accessibilityManager=*/ mockManager,
/*contentResolver=*/ null,
/*accessibilityViewEmbedder=*/ mockViewEmbedder,
Expand Down Expand Up @@ -1361,11 +1371,18 @@ public boolean verify(InvocationOnMock invocation) {
.thenAnswer(invocation -> verifier.verify(invocation));
accessibilityBridge.performAction(0, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
assertTrue(verifier.verified);

HashMap<String, Object> message = new HashMap<>();
message.put("type", "didGainFocus");
message.put("nodeId", 0);
verify(mockChannel).send(message);
}

@Test
public void itClearsFocusedNodeBeforeSendingEvent() {
AccessibilityChannel mockChannel = mock(AccessibilityChannel.class);
BasicMessageChannel mockChannel = mock(BasicMessageChannel.class);
AccessibilityChannel accessibilityChannel =
new AccessibilityChannel(mockChannel, mock(FlutterJNI.class));
AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class);
AccessibilityManager mockManager = mock(AccessibilityManager.class);
View mockRootView = mock(View.class);
Expand All @@ -1375,7 +1392,7 @@ public void itClearsFocusedNodeBeforeSendingEvent() {
AccessibilityBridge accessibilityBridge =
setUpBridge(
/*rootAccessibilityView=*/ mockRootView,
/*accessibilityChannel=*/ mockChannel,
/*accessibilityChannel=*/ accessibilityChannel,
/*accessibilityManager=*/ mockManager,
/*contentResolver=*/ null,
/*accessibilityViewEmbedder=*/ mockViewEmbedder,
Expand All @@ -1395,6 +1412,10 @@ public void itClearsFocusedNodeBeforeSendingEvent() {
accessibilityBridge.performAction(0, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
AccessibilityNodeInfo nodeInfo = accessibilityBridge.createAccessibilityNodeInfo(0);
assertTrue(nodeInfo.isAccessibilityFocused());
HashMap<String, Object> message = new HashMap<>();
message.put("type", "didGainFocus");
message.put("nodeId", 0);
verify(mockChannel).send(message);

class Verifier {
public Verifier(AccessibilityBridge accessibilityBridge) {
Expand Down