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 
10 #include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
11 
12 typedef struct {
13  const gchar* expected_message;
14  gboolean handled;
15 } KeyEventData;
16 
17 static void set_key_event_channel(FlMockBinaryMessenger* messenger,
18  const gchar* expected_message,
19  gboolean handled) {
20  KeyEventData* data = g_new0(KeyEventData, 1);
21  data->expected_message = expected_message;
22  data->handled = handled;
23  fl_mock_binary_messenger_set_json_message_channel(
24  messenger, "flutter/keyevent",
25  [](FlMockBinaryMessenger* messenger, GTask* task, FlValue* message,
26  gpointer user_data) {
27  g_autofree KeyEventData* data = static_cast<KeyEventData*>(user_data);
28 
29  g_autofree gchar* message_string = fl_value_to_string(message);
30  EXPECT_STREQ(message_string, data->expected_message);
31 
32  FlValue* response = fl_value_new_map();
33  fl_value_set_string_take(response, "handled",
34  fl_value_new_bool(data->handled));
35 
36  return response;
37  },
38  data);
39 }
40 
41 // Test sending a letter "A";
42 TEST(FlKeyChannelResponderTest, SendKeyEvent) {
43  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
44 
45  g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
46  g_autoptr(FlKeyChannelResponder) responder =
47  fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
48 
50  messenger,
51  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
52  "modifiers: 0, unicodeScalarValues: 65}",
53  FALSE);
54  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
55  12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
57  responder, event1, 0, nullptr,
58  [](GObject* object, GAsyncResult* result, gpointer user_data) {
59  gboolean handled;
61  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, nullptr));
62  EXPECT_FALSE(handled);
63  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
64  },
65  loop);
66  g_main_loop_run(loop);
67 
69  messenger,
70  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
71  "modifiers: 0, unicodeScalarValues: 65}",
72  FALSE);
73  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
74  23456, FALSE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
76  responder, event2, 0, nullptr,
77  [](GObject* object, GAsyncResult* result, gpointer user_data) {
78  gboolean handled;
80  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, nullptr));
81  EXPECT_FALSE(handled);
82  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
83  },
84  loop);
85  g_main_loop_run(loop);
86 
87  fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
88 }
89 
90 void test_lock_event(guint key_code,
91  const char* down_expected,
92  const char* up_expected) {
93  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
94 
95  g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
96  g_autoptr(FlKeyChannelResponder) responder =
97  fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
98 
99  set_key_event_channel(messenger, down_expected, FALSE);
100  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
101  12345, TRUE, 0x04, key_code, static_cast<GdkModifierType>(0), 0);
103  responder, event1, 0, nullptr,
104  [](GObject* object, GAsyncResult* result, gpointer user_data) {
105  gboolean handled;
107  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, nullptr));
108  EXPECT_FALSE(handled);
109  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
110  },
111  loop);
112  g_main_loop_run(loop);
113 
114  set_key_event_channel(messenger, up_expected, FALSE);
115  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
116  12346, FALSE, 0x04, key_code, static_cast<GdkModifierType>(0), 0);
118  responder, event2, 0, nullptr,
119  [](GObject* object, GAsyncResult* result, gpointer user_data) {
120  gboolean handled;
122  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, nullptr));
123  EXPECT_FALSE(handled);
124  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
125  },
126  loop);
127  g_main_loop_run(loop);
128 
129  fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
130 }
131 
132 // Test sending a "NumLock" keypress.
133 TEST(FlKeyChannelResponderTest, SendNumLockKeyEvent) {
134  test_lock_event(GDK_KEY_Num_Lock,
135  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
136  "keyCode: 65407, modifiers: 16}",
137  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
138  "keyCode: 65407, modifiers: 0}");
139 }
140 
141 // Test sending a "CapsLock" keypress.
142 TEST(FlKeyChannelResponderTest, SendCapsLockKeyEvent) {
143  test_lock_event(GDK_KEY_Caps_Lock,
144  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
145  "keyCode: 65509, modifiers: 2}",
146  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
147  "keyCode: 65509, modifiers: 0}");
148 }
149 
150 // Test sending a "ShiftLock" keypress.
151 TEST(FlKeyChannelResponderTest, SendShiftLockKeyEvent) {
152  test_lock_event(GDK_KEY_Shift_Lock,
153  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
154  "keyCode: 65510, modifiers: 2}",
155  "{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, "
156  "keyCode: 65510, modifiers: 0}");
157 }
158 
159 TEST(FlKeyChannelResponderTest, TestKeyEventHandledByFramework) {
160  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
161 
162  g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
163  g_autoptr(FlKeyChannelResponder) responder =
164  fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
165 
167  messenger,
168  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
169  "keyCode: 65, modifiers: 0, unicodeScalarValues: 65}",
170  TRUE);
171  g_autoptr(FlKeyEvent) event = fl_key_event_new(
172  12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
174  responder, event, 0, nullptr,
175  [](GObject* object, GAsyncResult* result, gpointer user_data) {
176  gboolean handled;
178  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, nullptr));
179  EXPECT_TRUE(handled);
180  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
181  },
182  loop);
183  g_main_loop_run(loop);
184 
185  fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
186 }
187 
188 TEST(FlKeyChannelResponderTest, UseSpecifiedLogicalKey) {
189  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
190 
191  g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
192  g_autoptr(FlKeyChannelResponder) responder =
193  fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
194 
196  messenger,
197  "{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
198  "keyCode: 65, modifiers: 0, unicodeScalarValues: 65, "
199  "specifiedLogicalKey: 888}",
200  TRUE);
201  g_autoptr(FlKeyEvent) event = fl_key_event_new(
202  12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
204  responder, event, 888, nullptr,
205  [](GObject* object, GAsyncResult* result, gpointer user_data) {
206  gboolean handled;
208  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, nullptr));
209  EXPECT_TRUE(handled);
210  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
211  },
212  loop);
213  g_main_loop_run(loop);
214 
215  fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
216 }
fl_binary_messenger_shutdown
void fl_binary_messenger_shutdown(FlBinaryMessenger *self)
Definition: fl_binary_messenger.cc:500
KeyEventData
Definition: fl_key_channel_responder_test.cc:12
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_key_channel_responder_new
FlKeyChannelResponder * fl_key_channel_responder_new(FlBinaryMessenger *messenger)
Definition: fl_key_channel_responder.cc:59
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
KeyEventData::handled
gboolean handled
Definition: fl_key_channel_responder_test.cc:14
set_key_event_channel
static void set_key_event_channel(FlMockBinaryMessenger *messenger, const gchar *expected_message, gboolean handled)
Definition: fl_key_channel_responder_test.cc:17
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
KeyEventData::expected_message
const gchar * expected_message
Definition: fl_key_channel_responder_test.cc:13
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_key_channel_responder_handle_event
void fl_key_channel_responder_handle_event(FlKeyChannelResponder *self, FlKeyEvent *event, uint64_t specified_logical_key, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_key_channel_responder.cc:71
fl_binary_messenger_private.h
fl_key_channel_responder_handle_event_finish
gboolean fl_key_channel_responder_handle_event_finish(FlKeyChannelResponder *self, GAsyncResult *result, gboolean *handled, GError **error)
Definition: fl_key_channel_responder.cc:139
TEST
TEST(FlKeyChannelResponderTest, SendKeyEvent)
Definition: fl_key_channel_responder_test.cc:42
fl_key_event_new
FlKeyEvent * fl_key_event_new(guint32 time, gboolean is_press, guint16 keycode, guint keyval, GdkModifierType state, guint8 group)
Definition: fl_key_event.cc:34
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:90
fl_value_to_string
G_MODULE_EXPORT gchar * fl_value_to_string(FlValue *value)
Definition: fl_value.cc:846