Skip to content

Commit

Permalink
Plumb a reference of PlatformViewsController and AccessibilityBridge …
Browse files Browse the repository at this point in the history
…to each other (flutter#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
  • Loading branch information
amirh authored Mar 19, 2019
1 parent 7cbbdb4 commit 45f69ac
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 6 deletions.
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platfor
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewFactory.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistry.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistryImpl.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
Expand Down
1 change: 1 addition & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ java_library("flutter_shell_java") {
"io/flutter/plugin/platform/PlatformViewFactory.java",
"io/flutter/plugin/platform/PlatformViewRegistry.java",
"io/flutter/plugin/platform/PlatformViewRegistryImpl.java",
"io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java",
"io/flutter/plugin/platform/PlatformViewsController.java",
"io/flutter/plugin/platform/SingleViewPresentation.java",
"io/flutter/plugin/platform/VirtualDisplayController.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public void onPreEngineRestart() {
mPlatformViewsController.onPreEngineRestart();
}

public PlatformViewsController getPlatformViewsController() {
return mPlatformViewsController;
}

private class FlutterRegistrar implements Registrar {
private final String pluginKey;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,10 @@ public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) {
this,
flutterEngine.getAccessibilityChannel(),
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
getContext().getContentResolver()
getContext().getContentResolver(),
// TODO(mattcaroll): plumb the platform views controller to the accessibility bridge.
// https://github.com/flutter/flutter/issues/29618
null
);
accessibilityBridge.setOnAccessibilityChangeListener(onAccessibilityChangeListener);
resetWillNotDraw(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugin.platform;

/**
* Facilitates interaction between the accessibility bridge and embedded platform views.
*/
public interface PlatformViewsAccessibilityDelegate {
// TODO(amirh): add a View getViewById(int id) here.
// not filing a tracking issue as this is going to be done in the next PR.
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMethodCodec;
import io.flutter.view.AccessibilityBridge;
import io.flutter.view.TextureRegistry;

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

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

// The accessibility bridge to which accessibility events form the platform views will be dispatched.
private AccessibilityBridge accessibilityBridge;

private final HashMap<Integer, VirtualDisplayController> vdControllers;

public PlatformViewsController() {
Expand Down Expand Up @@ -94,6 +98,25 @@ public void detach() {
mTextureRegistry = null;
}

/**
* Attaches an accessibility bridge for this platform views controller.
*
* Accessibility events sent by platform views that belonging to this controller will be
* dispatched to this accessibility bridge.
*/
public void attachAccessibilityBridge(AccessibilityBridge accessibilityBridge) {
this.accessibilityBridge = accessibilityBridge;
}

/**
* Detaches the current accessibility bridge.
*
* Any accessibility events sent by platform views belonging to this controller will be ignored.
*/
public void detachAccessibiltyBridge() {
this.accessibilityBridge = null;
}

public PlatformViewRegistry getRegistry() {
return mRegistry;
}
Expand All @@ -106,6 +129,17 @@ public void onPreEngineRestart() {
flushAllViews();
}

/**
* Returns the embedded view with id, or null if no view with this id is registered.
*/
public View getPlatformViewById(Integer id) {
VirtualDisplayController controller = vdControllers.get(id);
if (controller == null) {
return null;
}
return controller.getView();
}

@Override
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
if (Build.VERSION.SDK_INT < MINIMAL_SDK) {
Expand Down
12 changes: 9 additions & 3 deletions shell/platform/android/io/flutter/view/AccessibilityBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
Expand All @@ -27,8 +26,8 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;

import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.systemchannels.AccessibilityChannel;
import io.flutter.plugin.platform.PlatformViewsAccessibilityDelegate;
import io.flutter.util.Predicate;

import java.nio.ByteBuffer;
Expand Down Expand Up @@ -90,6 +89,11 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
@NonNull
private final AccessibilityManager accessibilityManager;

// The delegate for interacting with embedded platform views. Used to embed accessibility data for an embedded
// view in the accessibility tree.
@NonNull
private final PlatformViewsAccessibilityDelegate platformViewsAccessibilityDelegate;

// Android's {@link ContentResolver}, which is used to observe the global TRANSITION_ANIMATION_SCALE,
// which determines whether Flutter's animations should be enabled or disabled for accessibility
// purposes.
Expand Down Expand Up @@ -307,12 +311,14 @@ public AccessibilityBridge(
@NonNull View rootAccessibilityView,
@NonNull AccessibilityChannel accessibilityChannel,
@NonNull AccessibilityManager accessibilityManager,
@NonNull ContentResolver contentResolver
@NonNull ContentResolver contentResolver,
@NonNull PlatformViewsAccessibilityDelegate platformViewsAccessibilityDelegate
) {
this.rootAccessibilityView = rootAccessibilityView;
this.accessibilityChannel = accessibilityChannel;
this.accessibilityManager = accessibilityManager;
this.contentResolver = contentResolver;
this.platformViewsAccessibilityDelegate = platformViewsAccessibilityDelegate;

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

Expand Down
7 changes: 6 additions & 1 deletion shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import io.flutter.plugin.common.*;
import io.flutter.plugin.editing.TextInputPlugin;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.plugin.platform.PlatformViewsController;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
Expand Down Expand Up @@ -660,12 +661,15 @@ public void onFirstFrame() {
protected void onAttachedToWindow() {
super.onAttachedToWindow();

PlatformViewsController platformViewsController = getPluginRegistry().getPlatformViewsController();
mAccessibilityNodeProvider = new AccessibilityBridge(
this,
new AccessibilityChannel(dartExecutor, getFlutterNativeView().getFlutterJNI()),
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
getContext().getContentResolver()
getContext().getContentResolver(),
platformViewsController
);
platformViewsController.attachAccessibilityBridge(mAccessibilityNodeProvider);
mAccessibilityNodeProvider.setOnAccessibilityChangeListener(onAccessibilityChangeListener);

resetWillNotDraw(
Expand All @@ -678,6 +682,7 @@ protected void onAttachedToWindow() {
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();

getPluginRegistry().getPlatformViewsController().detachAccessibiltyBridge();
mAccessibilityNodeProvider.release();
mAccessibilityNodeProvider = null;
}
Expand Down

0 comments on commit 45f69ac

Please sign in to comment.