| Flutter Windows Embedder |

accessibility_plugin.cc
Go to the documentation of this file.
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 #include "flutter/shell/platform/windows/accessibility_plugin.h"
6
7 #include <variant>
8
9 #include "flutter/fml/logging.h"
10 #include "flutter/fml/platform/win/wstring_conversion.h"
11 #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h"
12 #include "flutter/shell/platform/windows/flutter_windows_engine.h"
13 #include "flutter/shell/platform/windows/flutter_windows_view.h"
14
15 namespace flutter {
16
17 namespace {
18
19 static constexpr char kAccessibilityChannelName[] = "flutter/accessibility";
20 static constexpr char kTypeKey[] = "type";
21 static constexpr char kDataKey[] = "data";
22 static constexpr char kMessageKey[] = "message";
23 static constexpr char kViewIdKey[] = "viewId";
24 static constexpr char kAnnounceValue[] = "announce";
25
26 // Handles messages like:
27 // {"type": "announce", "data": {"message": "Hello"}}
28 void HandleMessage(AccessibilityPlugin* plugin, const EncodableValue& message) {
29 const auto* map = std::get_if<EncodableMap>(&message);
30 if (!map) {
31 FML_LOG(ERROR) << "Accessibility message must be a map.";
32 return;
33 }
34 const auto& type_itr = map->find(EncodableValue{kTypeKey});
35 const auto& data_itr = map->find(EncodableValue{kDataKey});
36 if (type_itr == map->end()) {
37 FML_LOG(ERROR) << "Accessibility message must have a 'type' property.";
38 return;
39 }
40 if (data_itr == map->end()) {
41 FML_LOG(ERROR) << "Accessibility message must have a 'data' property.";
42 return;
43 }
44 const auto* type = std::get_if<std::string>(&type_itr->second);
45 const auto* data = std::get_if<EncodableMap>(&data_itr->second);
46 if (!type) {
47 FML_LOG(ERROR) << "Accessibility message 'type' property must be a string.";
48 return;
49 }
50 if (!data) {
51 FML_LOG(ERROR) << "Accessibility message 'data' property must be a map.";
52 return;
53 }
54
55 if (type->compare(kAnnounceValue) == 0) {
56 const auto& message_itr = data->find(EncodableValue{kMessageKey});
57 if (message_itr == data->end()) {
58 return;
59 }
60 const auto* message = std::get_if<std::string>(&message_itr->second);
61 if (!message) {
62 return;
63 }
64
65 const auto& view_itr = data->find(EncodableValue{kViewIdKey});
66 if (view_itr == data->end()) {
67 FML_LOG(ERROR) << "Announce message 'viewId' property is missing.";
68 return;
69 }
70
71 const auto* view_id_val = std::get_if<FlutterViewId>(&view_itr->second);
72 if (!view_id_val) {
73 FML_LOG(ERROR)
74 << "Announce message 'viewId' property must be a FlutterViewId.";
75 return;
76 }
77
78 plugin->Announce(*view_id_val, *message);
79 } else {
80 FML_LOG(WARNING) << "Accessibility message type '" << *type
81 << "' is not supported.";
82 }
83 }
84
85 } // namespace
86
87 AccessibilityPlugin::AccessibilityPlugin(FlutterWindowsEngine* engine)
88 : engine_(engine) {}
89
90 void AccessibilityPlugin::SetUp(BinaryMessenger* binary_messenger,
91 AccessibilityPlugin* plugin) {
92 BasicMessageChannel<> channel{binary_messenger, kAccessibilityChannelName,
93 &StandardMessageCodec::GetInstance()};
94
95 channel.SetMessageHandler(
96 [plugin](const EncodableValue& message,
97 const MessageReply<EncodableValue>& reply) {
98 HandleMessage(plugin, message);
99
100 // The accessibility channel does not support error handling.
101 // Always return an empty response even on failure.
102 reply(EncodableValue{std::monostate{}});
103 });
104 }
105
106 void AccessibilityPlugin::Announce(const FlutterViewId view_id,
107 const std::string_view message) {
108 if (!engine_->semantics_enabled()) {
109 return;
110 }
111
112 auto view = engine_->view(view_id);
113 if (!view) {
114 return;
115 }
116
117 std::wstring wide_text = fml::Utf8ToWideString(message);
118 view->AnnounceAlert(wide_text);
119 }
120
121 } // namespace flutter
accessibility_plugin.h
flutter::AccessibilityPlugin
Definition: accessibility_plugin.h:22
flutter::AccessibilityPlugin::AccessibilityPlugin
AccessibilityPlugin(FlutterWindowsEngine *engine)
Definition: accessibility_plugin.cc:87
flutter::AccessibilityPlugin::SetUp
static void SetUp(BinaryMessenger *binary_messenger, AccessibilityPlugin *plugin)
Definition: accessibility_plugin.cc:90
flutter::AccessibilityPlugin::Announce
virtual void Announce(const FlutterViewId view_id, const std::string_view message)
Definition: accessibility_plugin.cc:106
flutter::BasicMessageChannel
Definition: basic_message_channel.h:56
flutter::BinaryMessenger
Definition: binary_messenger.h:28
flutter::EncodableValue
Definition: encodable_value.h:165
flutter::FlutterWindowsEngine
Definition: flutter_windows_engine.h:92
flutter::FlutterWindowsEngine::view
FlutterWindowsView * view(FlutterViewId view_id) const
Definition: flutter_windows_engine.cc:688
flutter::FlutterWindowsEngine::semantics_enabled
bool semantics_enabled() const
Definition: flutter_windows_engine.h:258
flutter::StandardMessageCodec::GetInstance
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:293
kAccessibilityChannelName
static constexpr char kAccessibilityChannelName[]
Definition: flutter_windows_engine.cc:36
flutter_windows_engine.h
flutter_windows_view.h
message
Win32Message message
Definition: keyboard_unittests.cc:137
type
enum flutter::testing::@97::KeyboardChange::Type type
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::FlutterViewId
int64_t FlutterViewId
Definition: accessibility_plugin.h:15
flutter::MessageReply
std::function< void(const T &reply)> MessageReply
Definition: basic_message_channel.h:43
standard_message_codec.h