From 2b61dc51a010c49fb2726b7c46e5864c8a9966ce Mon Sep 17 00:00:00 2001 From: Alexander Brusher Date: Thu, 7 Jan 2021 10:42:19 -0800 Subject: [PATCH] Adds a mechanism for announce events to be forwarded to a11y. --- shell/platform/fuchsia/flutter/BUILD.gn | 1 + .../fuchsia/flutter/accessibility_bridge.cc | 9 ++++++++ .../fuchsia/flutter/accessibility_bridge.h | 3 +++ .../flutter/accessibility_bridge_unittest.cc | 10 +++++++++ .../fuchsia/flutter/flutter_runner_fakes.h | 13 ++++++++++++ .../platform/fuchsia/flutter/platform_view.cc | 21 +++++++++++++++++++ 6 files changed, 57 insertions(+) diff --git a/shell/platform/fuchsia/flutter/BUILD.gn b/shell/platform/fuchsia/flutter/BUILD.gn index dc6d225b1468c..f5fcd59470994 100644 --- a/shell/platform/fuchsia/flutter/BUILD.gn +++ b/shell/platform/fuchsia/flutter/BUILD.gn @@ -111,6 +111,7 @@ template("runner_sources") { "//flutter/lib/ui", "//flutter/runtime", "//flutter/shell/common", + "//flutter/shell/platform/common/cpp/client_wrapper:client_wrapper", ] flutter_deps = [ ":fuchsia_gpu_configuration", diff --git a/shell/platform/fuchsia/flutter/accessibility_bridge.cc b/shell/platform/fuchsia/flutter/accessibility_bridge.cc index 1a8088e6a3574..9a0039f50fa24 100644 --- a/shell/platform/fuchsia/flutter/accessibility_bridge.cc +++ b/shell/platform/fuchsia/flutter/accessibility_bridge.cc @@ -431,6 +431,15 @@ fuchsia::accessibility::semantics::Node AccessibilityBridge::GetRootNodeUpdate( return root_fuchsia_node; } +void AccessibilityBridge::RequestAnnounce(const std::string message) { + fuchsia::accessibility::semantics::SemanticEvent semantic_event; + fuchsia::accessibility::semantics::AnnounceEvent announce_event; + announce_event.set_message(message); + semantic_event.set_announce(std::move(announce_event)); + + tree_ptr_->SendSemanticEvent(std::move(semantic_event), []() {}); +} + void AccessibilityBridge::UpdateScreenRects() { std::unordered_set visited_nodes; UpdateScreenRects(kRootNodeId, SkM44{}, &visited_nodes); diff --git a/shell/platform/fuchsia/flutter/accessibility_bridge.h b/shell/platform/fuchsia/flutter/accessibility_bridge.h index 5ba1d981b0aaa..4328c8b46d660 100644 --- a/shell/platform/fuchsia/flutter/accessibility_bridge.h +++ b/shell/platform/fuchsia/flutter/accessibility_bridge.h @@ -85,6 +85,9 @@ class AccessibilityBridge void AddSemanticsNodeUpdate(const flutter::SemanticsNodeUpdates update, float view_pixel_ratio); + // Requests a message announcement from the accessibility TTS system. + void RequestAnnounce(const std::string message); + // Notifies the bridge of a 'hover move' touch exploration event. zx_status_t OnHoverMove(double x, double y); diff --git a/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc b/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc index 00303c5f6ccd2..c9de9f75cb51f 100644 --- a/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc +++ b/shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc @@ -103,6 +103,16 @@ TEST_F(AccessibilityBridgeTest, EnableDisable) { EXPECT_TRUE(accessibility_delegate_.enabled()); } +TEST_F(AccessibilityBridgeTest, RequestAnnounce) { + accessibility_bridge_->RequestAnnounce("message"); + RunLoopUntilIdle(); + + auto& last_events = semantics_manager_.GetLastEvents(); + ASSERT_EQ(last_events.size(), 1u); + ASSERT_TRUE(last_events[0].is_announce()); + EXPECT_EQ(last_events[0].announce().message(), "message"); +} + TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) { flutter::SemanticsNodeUpdates updates; diff --git a/shell/platform/fuchsia/flutter/flutter_runner_fakes.h b/shell/platform/fuchsia/flutter/flutter_runner_fakes.h index 4516d00f26c15..53ad3e6c4a955 100644 --- a/shell/platform/fuchsia/flutter/flutter_runner_fakes.h +++ b/shell/platform/fuchsia/flutter/flutter_runner_fakes.h @@ -90,6 +90,18 @@ class MockSemanticsManager commit_count_++; } + void SendSemanticEvent( + fuchsia::accessibility::semantics::SemanticEvent semantic_event, + SendSemanticEventCallback callback) override { + last_events_.emplace_back(std::move(semantic_event)); + callback(); + } + + std::vector& + GetLastEvents() { + return last_events_; + } + private: bool has_view_ref_ = false; fidl::BindingSet bindings_; @@ -102,6 +114,7 @@ class MockSemanticsManager bool delete_overflowed_; std::vector last_deleted_node_ids_; int commit_count_; + std::vector last_events_; }; } // namespace flutter_runner_test diff --git a/shell/platform/fuchsia/flutter/platform_view.cc b/shell/platform/fuchsia/flutter/platform_view.cc index d18c8c1ff5b88..19f1080165542 100644 --- a/shell/platform/fuchsia/flutter/platform_view.cc +++ b/shell/platform/fuchsia/flutter/platform_view.cc @@ -15,6 +15,8 @@ #include "flutter/fml/logging.h" #include "flutter/lib/ui/window/pointer_data.h" #include "flutter/lib/ui/window/window.h" +#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/encodable_value.h" +#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_message_codec.h" #include "third_party/rapidjson/include/rapidjson/document.h" #include "third_party/rapidjson/include/rapidjson/stringbuffer.h" #include "third_party/rapidjson/include/rapidjson/writer.h" @@ -658,6 +660,25 @@ void PlatformView::UpdateSemantics( void PlatformView::HandleAccessibilityChannelPlatformMessage( fml::RefPtr message) { FML_DCHECK(message->channel() == kAccessibilityChannel); + + const flutter::StandardMessageCodec& standard_message_codec = + flutter::StandardMessageCodec::GetInstance(nullptr); + std::unique_ptr decoded = + standard_message_codec.DecodeMessage(message->data()); + + flutter::EncodableMap map = std::get(*decoded); + std::string type = + std::get(map.at(flutter::EncodableValue("type"))); + if (type == "announce") { + flutter::EncodableMap data_map = std::get( + map.at(flutter::EncodableValue("data"))); + std::string text = + std::get(data_map.at(flutter::EncodableValue("message"))); + + accessibility_bridge_->RequestAnnounce(text); + } + + message->response()->CompleteEmpty(); } // Channel handler for kFlutterPlatformChannel