| Flutter Linux Embedder |

fl_key_channel_responder_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 #include "flutter/shell/platform/linux/fl_key_channel_responder.h"
6
7 #include "gtest/gtest.h"
8
9 #include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
10 #include "flutter/shell/platform/linux/fl_engine_private.h"
11 #include "flutter/shell/platform/linux/testing/fl_test.h"
12
13 static const char* expected_value = nullptr;
14 static gboolean expected_handled = FALSE;
15
16 static FlValue* echo_response_cb(FlValue* echoed_value) {
17 gchar* text = fl_value_to_string(echoed_value);
18 EXPECT_STREQ(text, expected_value);
19 g_free(text);
20
21 FlValue* value = fl_value_new_map();
22 fl_value_set_string_take(value, "handled",
23 fl_value_new_bool(expected_handled));
24 return value;
25 }
26
27 static void responder_callback(bool handled, gpointer user_data) {
28 EXPECT_EQ(handled, expected_handled);
29 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
30 }
31
32 namespace {
33 // A global variable to store new event. It is a global variable so that it can
34 // be returned by #fl_key_event_new_by_mock for easy use.
35 FlKeyEvent _g_key_event;
36 } // namespace
37
38 // Create a new #FlKeyEvent with the given information.
39 //
40 // This event is passed to #fl_key_responder_handle_event,
41 // which assumes that the event is managed by callee.
42 // Therefore #fl_key_event_new_by_mock doesn't need to
43 // dynamically allocate, but reuses the same global object.
44 static FlKeyEvent* fl_key_event_new_by_mock(guint32 time_in_milliseconds,
45 bool is_press,
46 guint keyval,
47 guint16 keycode,
48 int state,
49 const char* string,
50 gboolean is_modifier) {
51 if (_g_key_event.string != nullptr) {
52 g_free(const_cast<char*>(_g_key_event.string));
53 }
54 _g_key_event.is_press = is_press;
55 _g_key_event.time = time_in_milliseconds;
56 _g_key_event.state = state;
57 _g_key_event.keyval = keyval;
58 _g_key_event.string = g_strdup(string);
59 _g_key_event.keycode = keycode;
60 _g_key_event.origin = nullptr;
61 _g_key_event.dispose_origin = nullptr;
62 return &_g_key_event;
63 }
64
65 // Test sending a letter "A";
66 TEST(FlKeyChannelResponderTest, SendKeyEvent) {
67 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
68
69 g_autoptr(FlEngine) engine = make_mock_engine();
70 g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
71 FlKeyChannelResponderMock mock{
72 .value_converter = echo_response_cb,
73 .channel_name = "test/echo",
74 };
75 g_autoptr(FlKeyResponder) responder =
76 FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
77
78 fl_key_responder_handle_event(
79 responder,
80 fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04, 0x0, "A", false),
81 responder_callback, loop);
82 expected_value =
83 "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
84 "modifiers: 0, unicodeScalarValues: 65}";
85 expected_handled = FALSE;
86
87 // Blocks here until echo_response_cb is called.
88 g_main_loop_run(loop);
89
90 fl_key_responder_handle_event(
91 responder,
92 fl_key_event_new_by_mock(23456, false, GDK_KEY_A, 0x04, 0x0, "A", false),
93 responder_callback, loop);
94 expected_value =
95 "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
96 "modifiers: 0, unicodeScalarValues: 65}";
97 expected_handled = FALSE;
98
99 // Blocks here until echo_response_cb is called.
100 g_main_loop_run(loop);
101 }
102
103 void test_lock_event(guint key_code,
104 const char* down_expected,
105 const char* up_expected) {
106 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
107
108 g_autoptr(FlEngine) engine = make_mock_engine();
109 g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
110 FlKeyChannelResponderMock mock{
111 .value_converter = echo_response_cb,
112 .channel_name = "test/echo",
113 };
114 g_autoptr(FlKeyResponder) responder =
115 FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
116
117 fl_key_responder_handle_event(
118 responder,
119 fl_key_event_new_by_mock(12345, true, key_code, 0x04, 0x0, nullptr,
120 false),
121 responder_callback, loop);
122 expected_value = down_expected;
123 expected_handled = FALSE;
124
125 // Blocks here until echo_response_cb is called.
126 g_main_loop_run(loop);
127
128 expected_value = up_expected;
129 expected_handled = FALSE;
130 fl_key_responder_handle_event(
131 responder,
132 fl_key_event_new_by_mock(12346, false, key_code, 0x04, 0x0, nullptr,
133 false),
134 responder_callback, loop);
135
136 // Blocks here until echo_response_cb is called.
137 g_main_loop_run(loop);
138 }
139
140 // Test sending a "NumLock" keypress.
141 TEST(FlKeyChannelResponderTest, SendNumLockKeyEvent) {
142 test_lock_event(GDK_KEY_Num_Lock,
143 "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
144 "keyCode: 65407, modifiers: 16}",
145 "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
146 "keyCode: 65407, modifiers: 0}");
147 }
148
149 // Test sending a "CapsLock" keypress.
150 TEST(FlKeyChannelResponderTest, SendCapsLockKeyEvent) {
151 test_lock_event(GDK_KEY_Caps_Lock,
152 "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
153 "keyCode: 65509, modifiers: 2}",
154 "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
155 "keyCode: 65509, modifiers: 0}");
156 }
157
158 // Test sending a "ShiftLock" keypress.
159 TEST(FlKeyChannelResponderTest, SendShiftLockKeyEvent) {
160 test_lock_event(GDK_KEY_Shift_Lock,
161 "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
162 "keyCode: 65510, modifiers: 2}",
163 "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
164 "keyCode: 65510, modifiers: 0}");
165 }
166
167 TEST(FlKeyChannelResponderTest, TestKeyEventHandledByFramework) {
168 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
169
170 g_autoptr(FlEngine) engine = make_mock_engine();
171 g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
172 FlKeyChannelResponderMock mock{
173 .value_converter = echo_response_cb,
174 .channel_name = "test/echo",
175 };
176 g_autoptr(FlKeyResponder) responder =
177 FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
178
179 fl_key_responder_handle_event(
180 responder,
181 fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04, 0x0, nullptr,
182 false),
183 responder_callback, loop);
184 expected_handled = TRUE;
185 expected_value =
186 "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
187 "keyCode: 65, modifiers: 0, unicodeScalarValues: 65}";
188
189 // Blocks here until echo_response_cb is called.
190 g_main_loop_run(loop);
191 }
192
193 TEST(FlKeyChannelResponderTest, UseSpecifiedLogicalKey) {
194 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
195
196 g_autoptr(FlEngine) engine = make_mock_engine();
197 g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
198 FlKeyChannelResponderMock mock{
199 .value_converter = echo_response_cb,
200 .channel_name = "test/echo",
201 };
202 g_autoptr(FlKeyResponder) responder =
203 FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
204
205 fl_key_responder_handle_event(
206 responder,
207 fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04, 0x0, nullptr,
208 false),
209 responder_callback, loop, 888);
210 expected_handled = TRUE;
211 expected_value =
212 "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
213 "keyCode: 65, modifiers: 0, unicodeScalarValues: 65, "
214 "specifiedLogicalKey: 888}";
215
216 // Blocks here until echo_response_cb is called.
217 g_main_loop_run(loop);
218 }
responder_callback
static void responder_callback(bool handled, gpointer user_data)
Definition: fl_key_channel_responder_test.cc:27
fl_value_set_string_take
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:610
fl_key_event_new_by_mock
static FlKeyEvent * fl_key_event_new_by_mock(guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, int state, const char *string, gboolean is_modifier)
Definition: fl_key_channel_responder_test.cc:44
fl_value_new_bool
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:244
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:40
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
expected_value
static const char * expected_value
Definition: fl_key_channel_responder_test.cc:13
_FlKeyEvent
Definition: fl_key_event.h:31
state
AtkStateType state
Definition: fl_accessible_node.cc:10
fl_binary_messenger_new
FlBinaryMessenger * fl_binary_messenger_new(FlEngine *engine)
Definition: fl_binary_messenger.cc:406
fl_key_channel_responder_new
FlKeyChannelResponder * fl_key_channel_responder_new(FlBinaryMessenger *messenger, FlKeyChannelResponderMock *mock)
Definition: fl_key_channel_responder.cc:186
make_mock_engine
static FlEngine * make_mock_engine()
Definition: fl_event_channel_test.cc:24
_FlKeyChannelResponderMock::value_converter
FlValueConverter value_converter
Definition: fl_key_channel_responder.h:29
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:355
fl_key_responder_handle_event
void fl_key_responder_handle_event(FlKeyResponder *self, FlKeyEvent *event, FlKeyResponderAsyncCallback callback, gpointer user_data, uint64_t specified_logical_key)
Definition: fl_key_responder.cc:11
fl_engine_private.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_binary_messenger_private.h
TEST
TEST(FlKeyChannelResponderTest, SendKeyEvent)
Definition: fl_key_channel_responder_test.cc:66
echo_response_cb
static FlValue * echo_response_cb(FlValue *echoed_value)
Definition: fl_key_channel_responder_test.cc:16
_FlKeyChannelResponderMock
Definition: fl_key_channel_responder.h:23
engine
FlEngine * engine
Definition: fl_view_accessible.cc:29
fl_key_channel_responder.h
test_lock_event
void test_lock_event(guint key_code, const char *down_expected, const char *up_expected)
Definition: fl_key_channel_responder_test.cc:103
value
uint8_t value
Definition: fl_standard_message_codec.cc:41
fl_value_to_string
G_MODULE_EXPORT gchar * fl_value_to_string(FlValue *value)
Definition: fl_value.cc:781
expected_handled
static gboolean expected_handled
Definition: fl_key_channel_responder_test.cc:14