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 
6 
7 #include "gtest/gtest.h"
8 
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 
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  GdkModifierType state,
49  gboolean is_modifier) {
50  _g_key_event.is_press = is_press;
51  _g_key_event.time = time_in_milliseconds;
52  _g_key_event.state = state;
53  _g_key_event.keyval = keyval;
54  _g_key_event.keycode = keycode;
55  _g_key_event.origin = nullptr;
56  return &_g_key_event;
57 }
58 
59 // Test sending a letter "A";
60 TEST(FlKeyChannelResponderTest, SendKeyEvent) {
61  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
62 
63  g_autoptr(FlEngine) engine = make_mock_engine();
64  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
67  .channel_name = "test/echo",
68  };
69  g_autoptr(FlKeyResponder) responder =
70  FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
71 
73  responder,
74  fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04,
75  static_cast<GdkModifierType>(0), false),
76  responder_callback, loop);
78  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
79  "modifiers: 0, unicodeScalarValues: 65}";
80  expected_handled = FALSE;
81 
82  // Blocks here until echo_response_cb is called.
83  g_main_loop_run(loop);
84 
86  responder,
87  fl_key_event_new_by_mock(23456, false, GDK_KEY_A, 0x04,
88  static_cast<GdkModifierType>(0), false),
89  responder_callback, loop);
91  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
92  "modifiers: 0, unicodeScalarValues: 65}";
93  expected_handled = FALSE;
94 
95  // Blocks here until echo_response_cb is called.
96  g_main_loop_run(loop);
97 }
98 
99 void test_lock_event(guint key_code,
100  const char* down_expected,
101  const char* up_expected) {
102  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
103 
104  g_autoptr(FlEngine) engine = make_mock_engine();
105  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
108  .channel_name = "test/echo",
109  };
110  g_autoptr(FlKeyResponder) responder =
111  FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
112 
114  responder,
115  fl_key_event_new_by_mock(12345, true, key_code, 0x04,
116  static_cast<GdkModifierType>(0), false),
117  responder_callback, loop);
118  expected_value = down_expected;
119  expected_handled = FALSE;
120 
121  // Blocks here until echo_response_cb is called.
122  g_main_loop_run(loop);
123 
124  expected_value = up_expected;
125  expected_handled = FALSE;
127  responder,
128  fl_key_event_new_by_mock(12346, false, key_code, 0x04,
129  static_cast<GdkModifierType>(0), false),
130  responder_callback, loop);
131 
132  // Blocks here until echo_response_cb is called.
133  g_main_loop_run(loop);
134 }
135 
136 // Test sending a "NumLock" keypress.
137 TEST(FlKeyChannelResponderTest, SendNumLockKeyEvent) {
138  test_lock_event(GDK_KEY_Num_Lock,
139  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
140  "keyCode: 65407, modifiers: 16}",
141  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
142  "keyCode: 65407, modifiers: 0}");
143 }
144 
145 // Test sending a "CapsLock" keypress.
146 TEST(FlKeyChannelResponderTest, SendCapsLockKeyEvent) {
147  test_lock_event(GDK_KEY_Caps_Lock,
148  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
149  "keyCode: 65509, modifiers: 2}",
150  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
151  "keyCode: 65509, modifiers: 0}");
152 }
153 
154 // Test sending a "ShiftLock" keypress.
155 TEST(FlKeyChannelResponderTest, SendShiftLockKeyEvent) {
156  test_lock_event(GDK_KEY_Shift_Lock,
157  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
158  "keyCode: 65510, modifiers: 2}",
159  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
160  "keyCode: 65510, modifiers: 0}");
161 }
162 
163 TEST(FlKeyChannelResponderTest, TestKeyEventHandledByFramework) {
164  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
165 
166  g_autoptr(FlEngine) engine = make_mock_engine();
167  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
170  .channel_name = "test/echo",
171  };
172  g_autoptr(FlKeyResponder) responder =
173  FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
174 
176  responder,
177  fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04,
178  static_cast<GdkModifierType>(0), false),
179  responder_callback, loop);
182  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
183  "keyCode: 65, modifiers: 0, unicodeScalarValues: 65}";
184 
185  // Blocks here until echo_response_cb is called.
186  g_main_loop_run(loop);
187 }
188 
189 TEST(FlKeyChannelResponderTest, UseSpecifiedLogicalKey) {
190  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
191 
192  g_autoptr(FlEngine) engine = make_mock_engine();
193  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
196  .channel_name = "test/echo",
197  };
198  g_autoptr(FlKeyResponder) responder =
199  FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));
200 
202  responder,
203  fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04,
204  static_cast<GdkModifierType>(0), false),
205  responder_callback, loop, 888);
208  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
209  "keyCode: 65, modifiers: 0, unicodeScalarValues: 65, "
210  "specifiedLogicalKey: 888}";
211 
212  // Blocks here until echo_response_cb is called.
213  g_main_loop_run(loop);
214 }
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:650
fl_value_new_bool
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
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
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, GdkModifierType state, gboolean is_modifier)
Definition: fl_key_channel_responder_test.cc:44
_FlKeyEvent
Definition: fl_key_event.h:22
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:366
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
_FlKeyEvent::is_press
bool is_press
Definition: fl_key_event.h:26
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:60
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:26
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:99
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
fl_value_to_string
G_MODULE_EXPORT gchar * fl_value_to_string(FlValue *value)
Definition: fl_value.cc:846
expected_handled
static gboolean expected_handled
Definition: fl_key_channel_responder_test.cc:14