Flutter Linux Embedder
fl_accessibility_handler_test.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 // Workaround missing C code compatibility in ATK header.
6 // Fixed in https://gitlab.gnome.org/GNOME/at-spi2-core/-/merge_requests/219
7 extern "C" {
8 #include <atk/atk.h>
9 }
10 
15 #include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
16 #include "flutter/shell/platform/linux/testing/fl_test_gtk_logs.h"
17 #include "flutter/testing/testing.h"
18 
19 #include "flutter/shell/platform/linux/testing/linux_test.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 
23 static constexpr int64_t kTextDirectionLtr = 0;
24 static constexpr int64_t kAssertivenessAssertive = 1;
25 
26 // Enum copied from ATK 2.50, as the version we are building against doesn't
27 // have this.
28 typedef enum {
33 
34 static void announcement_cb(FlViewAccessible* accessible,
35  const gchar* message,
36  gpointer user_data) {
37  EXPECT_STREQ(message, "MESSAGE");
38  gboolean* signalled = static_cast<gboolean*>(user_data);
39  *signalled = TRUE;
40 }
41 
42 static void notification_polite_cb(FlViewAccessible* accessible,
43  const gchar* message,
44  FlAtkLive politeness,
45  gpointer user_data) {
46  EXPECT_STREQ(message, "MESSAGE");
47  EXPECT_EQ(politeness, FL_ATK_LIVE_POLITE);
48  gboolean* signalled = static_cast<gboolean*>(user_data);
49  *signalled = TRUE;
50 }
51 
52 static void notification_assertive_cb(FlViewAccessible* accessible,
53  const gchar* message,
54  FlAtkLive politeness,
55  gpointer user_data) {
56  EXPECT_STREQ(message, "MESSAGE");
57  EXPECT_EQ(politeness, FL_ATK_LIVE_ASSERTIVE);
58  gboolean* signalled = static_cast<gboolean*>(user_data);
59  *signalled = TRUE;
60 }
61 
62 static gboolean atk_supports_announce() {
63  return atk_get_major_version() == 2 && atk_get_minor_version() >= 46;
64 }
65 
66 static void subscribe_signal(FlViewAccessible* accessible,
67  gboolean* signalled,
68  gboolean assertive) {
69  if (!atk_supports_announce()) {
70  return;
71  }
72 
73  if (atk_get_major_version() == 2 && atk_get_minor_version() < 50) {
74  g_signal_connect(accessible, "announcement", G_CALLBACK(announcement_cb),
75  signalled);
76  } else {
77  g_signal_connect(accessible, "notification",
78  G_CALLBACK(assertive ? notification_assertive_cb
80  signalled);
81  }
82 }
83 
84 class FlAccessibilityHandlerTest : public flutter::testing::LinuxTest {
85  protected:
86  void SetUp() override {
87  flutter::testing::fl_ensure_gtk_init();
88  messenger = fl_mock_binary_messenger_new();
89  g_clear_object(&engine);
90  engine =
91  fl_engine_new_with_binary_messenger(FL_BINARY_MESSENGER(messenger));
92  view = fl_view_new_for_engine(engine);
93  }
94 
96  fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
97  g_clear_object(&messenger);
98  }
99 
100  FlMockBinaryMessenger* messenger = nullptr;
101  FlView* view = nullptr;
102 };
103 
105  gboolean signalled = FALSE;
106  subscribe_signal(fl_view_get_accessible(view), &signalled, FALSE);
107 
111  fl_value_set_string(message, "data", data);
112  fl_value_set_string_take(data, "viewId",
114  fl_value_set_string_take(data, "message", fl_value_new_string("MESSAGE"));
115  fl_value_set_string_take(data, "textDirection",
117 
118  gboolean called = FALSE;
119  fl_mock_binary_messenger_send_standard_message(
120  messenger, "flutter/accessibility", message,
121  [](FlMockBinaryMessenger* messenger, FlValue* response,
122  gpointer user_data) {
123  EXPECT_EQ(fl_value_get_type(response), FL_VALUE_TYPE_NULL);
124  gboolean* called = static_cast<gboolean*>(user_data);
125  *called = TRUE;
126  },
127  &called);
128  EXPECT_TRUE(called);
129  if (atk_supports_announce()) {
130  EXPECT_TRUE(signalled);
131  }
132 }
133 
134 TEST_F(FlAccessibilityHandlerTest, AnnounceAssertive) {
135  gboolean signalled = FALSE;
137 
141  fl_value_set_string(message, "data", data);
142  fl_value_set_string_take(data, "viewId",
144  fl_value_set_string_take(data, "message", fl_value_new_string("MESSAGE"));
145  fl_value_set_string_take(data, "textDirection",
147  // Add optional assertiveness (not used in ATK)
148  fl_value_set_string_take(data, "assertiveness",
150 
151  gboolean called = FALSE;
152  fl_mock_binary_messenger_send_standard_message(
153  messenger, "flutter/accessibility", message,
154  [](FlMockBinaryMessenger* messenger, FlValue* response,
155  gpointer user_data) {
156  EXPECT_EQ(fl_value_get_type(response), FL_VALUE_TYPE_NULL);
157  gboolean* called = static_cast<gboolean*>(user_data);
158  *called = TRUE;
159  },
160  &called);
161  EXPECT_TRUE(called);
162  if (atk_supports_announce()) {
163  EXPECT_TRUE(signalled);
164  }
165 }
166 
167 TEST_F(FlAccessibilityHandlerTest, AnnounceUnknownView) {
168  gboolean signalled = FALSE;
169  subscribe_signal(fl_view_get_accessible(view), &signalled, FALSE);
170 
174  fl_value_set_string(message, "data", data);
175  fl_value_set_string_take(data, "viewId", fl_value_new_int(999));
176  fl_value_set_string_take(data, "message", fl_value_new_string("MESSAGE"));
177  fl_value_set_string_take(data, "textDirection",
179  // Add optional assertiveness (not used in ATK)
180  fl_value_set_string_take(data, "assertiveness",
182 
183  gboolean called = FALSE;
184  fl_mock_binary_messenger_send_standard_message(
185  messenger, "flutter/accessibility", message,
186  [](FlMockBinaryMessenger* messenger, FlValue* response,
187  gpointer user_data) {
188  EXPECT_EQ(fl_value_get_type(response), FL_VALUE_TYPE_NULL);
189  gboolean* called = static_cast<gboolean*>(user_data);
190  *called = TRUE;
191  },
192  &called);
193  EXPECT_TRUE(called);
194  EXPECT_FALSE(signalled);
195 }
196 
198  gboolean signalled = FALSE;
199  subscribe_signal(fl_view_get_accessible(view), &signalled, FALSE);
200 
201  // Unknown type, ignored by embedder.
205 
206  gboolean called = FALSE;
207  fl_mock_binary_messenger_send_standard_message(
208  messenger, "flutter/accessibility", message,
209  [](FlMockBinaryMessenger* messenger, FlValue* response,
210  gpointer user_data) {
211  EXPECT_EQ(fl_value_get_type(response), FL_VALUE_TYPE_NULL);
212  gboolean* called = static_cast<gboolean*>(user_data);
213  *called = TRUE;
214  },
215  &called);
216  EXPECT_TRUE(called);
217  EXPECT_FALSE(signalled);
218 }
FlViewAccessible * accessible
FlView * view
const char * message
g_autoptr(FlEngine) engine
const char FlTextDirection FlAssertiveness gpointer user_data
static void subscribe_signal(FlViewAccessible *accessible, gboolean *signalled, gboolean assertive)
static constexpr int64_t kAssertivenessAssertive
static void announcement_cb(FlViewAccessible *accessible, const gchar *message, gpointer user_data)
static void notification_polite_cb(FlViewAccessible *accessible, const gchar *message, FlAtkLive politeness, gpointer user_data)
static constexpr int64_t kTextDirectionLtr
TEST_F(FlAccessibilityHandlerTest, Announce)
static void notification_assertive_cb(FlViewAccessible *accessible, const gchar *message, FlAtkLive politeness, gpointer user_data)
static gboolean atk_supports_announce()
void fl_binary_messenger_shutdown(FlBinaryMessenger *self)
return TRUE
FlEngine * fl_engine_new_with_binary_messenger(FlBinaryMessenger *binary_messenger)
Definition: fl_engine.cc:734
G_MODULE_EXPORT void fl_value_set_string(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:639
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:650
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
@ FL_VALUE_TYPE_NULL
Definition: fl_value.h:64
FlViewAccessible * fl_view_get_accessible(FlView *self)
Definition: fl_view.cc:770
G_MODULE_EXPORT FlView * fl_view_new_for_engine(FlEngine *engine)
Definition: fl_view.cc:719
G_MODULE_EXPORT int64_t fl_view_get_id(FlView *self)
Definition: fl_view.cc:759