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

Commit 45f69ac

Browse files
authored
Plumb a reference of PlatformViewsController and AccessibilityBridge to each other (#8208)
This is in preparation for implementing platform views a11y on Android. And e2e working prototype is available here: https://github.com/amirh/engine/tree/a11y_hacks flutter/flutter#19418
1 parent 7cbbdb4 commit 45f69ac

File tree

8 files changed

+73
-6
lines changed

8 files changed

+73
-6
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platfor
516516
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewFactory.java
517517
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistry.java
518518
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistryImpl.java
519+
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java
519520
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java
520521
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java
521522
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java

shell/platform/android/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ java_library("flutter_shell_java") {
158158
"io/flutter/plugin/platform/PlatformViewFactory.java",
159159
"io/flutter/plugin/platform/PlatformViewRegistry.java",
160160
"io/flutter/plugin/platform/PlatformViewRegistryImpl.java",
161+
"io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java",
161162
"io/flutter/plugin/platform/PlatformViewsController.java",
162163
"io/flutter/plugin/platform/SingleViewPresentation.java",
163164
"io/flutter/plugin/platform/VirtualDisplayController.java",

shell/platform/android/io/flutter/app/FlutterPluginRegistry.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ public void onPreEngineRestart() {
9494
mPlatformViewsController.onPreEngineRestart();
9595
}
9696

97+
public PlatformViewsController getPlatformViewsController() {
98+
return mPlatformViewsController;
99+
}
100+
97101
private class FlutterRegistrar implements Registrar {
98102
private final String pluginKey;
99103

shell/platform/android/io/flutter/embedding/engine/android/FlutterView.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,10 @@ public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) {
447447
this,
448448
flutterEngine.getAccessibilityChannel(),
449449
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
450-
getContext().getContentResolver()
450+
getContext().getContentResolver(),
451+
// TODO(mattcaroll): plumb the platform views controller to the accessibility bridge.
452+
// https://github.com/flutter/flutter/issues/29618
453+
null
451454
);
452455
accessibilityBridge.setOnAccessibilityChangeListener(onAccessibilityChangeListener);
453456
resetWillNotDraw(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package io.flutter.plugin.platform;
6+
7+
/**
8+
* Facilitates interaction between the accessibility bridge and embedded platform views.
9+
*/
10+
public interface PlatformViewsAccessibilityDelegate {
11+
// TODO(amirh): add a View getViewById(int id) here.
12+
// not filing a tracking issue as this is going to be done in the next PR.
13+
}

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.flutter.plugin.common.MethodCall;
1515
import io.flutter.plugin.common.MethodChannel;
1616
import io.flutter.plugin.common.StandardMethodCodec;
17+
import io.flutter.view.AccessibilityBridge;
1718
import io.flutter.view.TextureRegistry;
1819

1920
import java.nio.ByteBuffer;
@@ -31,7 +32,7 @@
3132
* Each {@link io.flutter.app.FlutterPluginRegistry} has a single platform views controller.
3233
* A platform views controller can be attached to at most one Flutter view.
3334
*/
34-
public class PlatformViewsController implements MethodChannel.MethodCallHandler {
35+
public class PlatformViewsController implements MethodChannel.MethodCallHandler, PlatformViewsAccessibilityDelegate {
3536
private static final String TAG = "PlatformViewsController";
3637

3738
private static final String CHANNEL_NAME = "flutter/platform_views";
@@ -50,6 +51,9 @@ public class PlatformViewsController implements MethodChannel.MethodCallHandler
5051
// The messenger used to communicate with the framework over the platform views channel.
5152
private BinaryMessenger mMessenger;
5253

54+
// The accessibility bridge to which accessibility events form the platform views will be dispatched.
55+
private AccessibilityBridge accessibilityBridge;
56+
5357
private final HashMap<Integer, VirtualDisplayController> vdControllers;
5458

5559
public PlatformViewsController() {
@@ -94,6 +98,25 @@ public void detach() {
9498
mTextureRegistry = null;
9599
}
96100

101+
/**
102+
* Attaches an accessibility bridge for this platform views controller.
103+
*
104+
* Accessibility events sent by platform views that belonging to this controller will be
105+
* dispatched to this accessibility bridge.
106+
*/
107+
public void attachAccessibilityBridge(AccessibilityBridge accessibilityBridge) {
108+
this.accessibilityBridge = accessibilityBridge;
109+
}
110+
111+
/**
112+
* Detaches the current accessibility bridge.
113+
*
114+
* Any accessibility events sent by platform views belonging to this controller will be ignored.
115+
*/
116+
public void detachAccessibiltyBridge() {
117+
this.accessibilityBridge = null;
118+
}
119+
97120
public PlatformViewRegistry getRegistry() {
98121
return mRegistry;
99122
}
@@ -106,6 +129,17 @@ public void onPreEngineRestart() {
106129
flushAllViews();
107130
}
108131

132+
/**
133+
* Returns the embedded view with id, or null if no view with this id is registered.
134+
*/
135+
public View getPlatformViewById(Integer id) {
136+
VirtualDisplayController controller = vdControllers.get(id);
137+
if (controller == null) {
138+
return null;
139+
}
140+
return controller.getView();
141+
}
142+
109143
@Override
110144
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
111145
if (Build.VERSION.SDK_INT < MINIMAL_SDK) {

shell/platform/android/io/flutter/view/AccessibilityBridge.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import android.os.Bundle;
1616
import android.os.Handler;
1717
import android.provider.Settings;
18-
import android.support.annotation.NonNull;
1918
import android.support.annotation.Nullable;
2019
import android.support.annotation.NonNull;
2120
import android.support.annotation.RequiresApi;
@@ -27,8 +26,8 @@
2726
import android.view.accessibility.AccessibilityNodeInfo;
2827
import android.view.accessibility.AccessibilityNodeProvider;
2928

30-
import io.flutter.embedding.engine.FlutterJNI;
3129
import io.flutter.embedding.engine.systemchannels.AccessibilityChannel;
30+
import io.flutter.plugin.platform.PlatformViewsAccessibilityDelegate;
3231
import io.flutter.util.Predicate;
3332

3433
import java.nio.ByteBuffer;
@@ -90,6 +89,11 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
9089
@NonNull
9190
private final AccessibilityManager accessibilityManager;
9291

92+
// The delegate for interacting with embedded platform views. Used to embed accessibility data for an embedded
93+
// view in the accessibility tree.
94+
@NonNull
95+
private final PlatformViewsAccessibilityDelegate platformViewsAccessibilityDelegate;
96+
9397
// Android's {@link ContentResolver}, which is used to observe the global TRANSITION_ANIMATION_SCALE,
9498
// which determines whether Flutter's animations should be enabled or disabled for accessibility
9599
// purposes.
@@ -307,12 +311,14 @@ public AccessibilityBridge(
307311
@NonNull View rootAccessibilityView,
308312
@NonNull AccessibilityChannel accessibilityChannel,
309313
@NonNull AccessibilityManager accessibilityManager,
310-
@NonNull ContentResolver contentResolver
314+
@NonNull ContentResolver contentResolver,
315+
@NonNull PlatformViewsAccessibilityDelegate platformViewsAccessibilityDelegate
311316
) {
312317
this.rootAccessibilityView = rootAccessibilityView;
313318
this.accessibilityChannel = accessibilityChannel;
314319
this.accessibilityManager = accessibilityManager;
315320
this.contentResolver = contentResolver;
321+
this.platformViewsAccessibilityDelegate = platformViewsAccessibilityDelegate;
316322

317323
decorView = ((Activity) rootAccessibilityView.getContext()).getWindow().getDecorView();
318324

shell/platform/android/io/flutter/view/FlutterView.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import io.flutter.plugin.common.*;
4444
import io.flutter.plugin.editing.TextInputPlugin;
4545
import io.flutter.plugin.platform.PlatformPlugin;
46+
import io.flutter.plugin.platform.PlatformViewsController;
4647

4748
import java.nio.ByteBuffer;
4849
import java.nio.ByteOrder;
@@ -660,12 +661,15 @@ public void onFirstFrame() {
660661
protected void onAttachedToWindow() {
661662
super.onAttachedToWindow();
662663

664+
PlatformViewsController platformViewsController = getPluginRegistry().getPlatformViewsController();
663665
mAccessibilityNodeProvider = new AccessibilityBridge(
664666
this,
665667
new AccessibilityChannel(dartExecutor, getFlutterNativeView().getFlutterJNI()),
666668
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
667-
getContext().getContentResolver()
669+
getContext().getContentResolver(),
670+
platformViewsController
668671
);
672+
platformViewsController.attachAccessibilityBridge(mAccessibilityNodeProvider);
669673
mAccessibilityNodeProvider.setOnAccessibilityChangeListener(onAccessibilityChangeListener);
670674

671675
resetWillNotDraw(
@@ -678,6 +682,7 @@ protected void onAttachedToWindow() {
678682
protected void onDetachedFromWindow() {
679683
super.onDetachedFromWindow();
680684

685+
getPluginRegistry().getPlatformViewsController().detachAccessibiltyBridge();
681686
mAccessibilityNodeProvider.release();
682687
mAccessibilityNodeProvider = null;
683688
}

0 commit comments

Comments
 (0)