Flutter Engine
The Flutter Engine
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
15namespace flutter {
16
17namespace {
18
19static constexpr char kAccessibilityChannelName[] = "flutter/accessibility";
20static constexpr char kTypeKey[] = "type";
21static constexpr char kDataKey[] = "data";
22static constexpr char kMessageKey[] = "message";
23static constexpr char kAnnounceValue[] = "announce";
24
25// Handles messages like:
26// {"type": "announce", "data": {"message": "Hello"}}
27void HandleMessage(AccessibilityPlugin* plugin, const EncodableValue& message) {
28 const auto* map = std::get_if<EncodableMap>(&message);
29 if (!map) {
30 FML_LOG(ERROR) << "Accessibility message must be a map.";
31 return;
32 }
33 const auto& type_itr = map->find(EncodableValue{kTypeKey});
34 const auto& data_itr = map->find(EncodableValue{kDataKey});
35 if (type_itr == map->end()) {
36 FML_LOG(ERROR) << "Accessibility message must have a 'type' property.";
37 return;
38 }
39 if (data_itr == map->end()) {
40 FML_LOG(ERROR) << "Accessibility message must have a 'data' property.";
41 return;
42 }
43 const auto* type = std::get_if<std::string>(&type_itr->second);
44 const auto* data = std::get_if<EncodableMap>(&data_itr->second);
45 if (!type) {
46 FML_LOG(ERROR) << "Accessibility message 'type' property must be a string.";
47 return;
48 }
49 if (!data) {
50 FML_LOG(ERROR) << "Accessibility message 'data' property must be a map.";
51 return;
52 }
53
54 if (type->compare(kAnnounceValue) == 0) {
55 const auto& message_itr = data->find(EncodableValue{kMessageKey});
56 if (message_itr == data->end()) {
57 return;
58 }
59 const auto* message = std::get_if<std::string>(&message_itr->second);
60 if (!message) {
61 return;
62 }
63
64 plugin->Announce(*message);
65 } else {
66 FML_LOG(WARNING) << "Accessibility message type '" << *type
67 << "' is not supported.";
68 }
69}
70
71} // namespace
72
74 : engine_(engine) {}
75
77 AccessibilityPlugin* plugin) {
78 BasicMessageChannel<> channel{binary_messenger, kAccessibilityChannelName,
80
81 channel.SetMessageHandler(
82 [plugin](const EncodableValue& message,
83 const MessageReply<EncodableValue>& reply) {
84 HandleMessage(plugin, message);
85
86 // The accessibility channel does not support error handling.
87 // Always return an empty response even on failure.
88 reply(EncodableValue{std::monostate{}});
89 });
90}
91
92void AccessibilityPlugin::Announce(const std::string_view message) {
93 if (!engine_->semantics_enabled()) {
94 return;
95 }
96
97 // TODO(loicsharma): Remove implicit view assumption.
98 // https://github.com/flutter/flutter/issues/142845
99 auto view = engine_->view(kImplicitViewId);
100 if (!view) {
101 return;
102 }
103
104 std::wstring wide_text = fml::Utf8ToWideString(message);
105 view->AnnounceAlert(wide_text);
106}
107
108} // namespace flutter
GLenum type
AccessibilityPlugin(FlutterWindowsEngine *engine)
virtual void Announce(const std::string_view message)
static void SetUp(BinaryMessenger *binary_messenger, AccessibilityPlugin *plugin)
FlutterWindowsView * view(FlutterViewId view_id) const
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
FlutterEngine engine
Definition: main.cc:68
static constexpr char kAccessibilityChannelName[]
#define FML_LOG(severity)
Definition: logging.h:82
Win32Message message
constexpr FlutterViewId kImplicitViewId
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition: switches.h:41
constexpr char kTypeKey[]
Definition: shell.cc:50
std::function< void(const T &reply)> MessageReply
std::wstring Utf8ToWideString(const std::string_view str)
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680
#define ERROR(message)
Definition: elf_loader.cc:260