10 #include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
11 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
14 #include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
15 #include "flutter/shell/platform/linux/testing/mock_gtk.h"
17 #include "flutter/shell/platform/linux/testing/linux_test.h"
18 #include "gtest/gtest.h"
20 #define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR) \
21 EXPECT_EQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
23 kFlutterKeyEventTypeDown); \
24 EXPECT_EQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
27 EXPECT_STREQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
30 EXPECT_EQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
31 ->event_synthesized, \
33 g_ptr_array_set_size(call_records, 0)
46 FlutterKeyEventCallback callback,
47 void* callback_user_data) {
71 using ::flutter::testing::keycodes::kLogicalAltLeft;
72 using ::flutter::testing::keycodes::kLogicalBracketLeft;
73 using ::flutter::testing::keycodes::kLogicalComma;
74 using ::flutter::testing::keycodes::kLogicalControlLeft;
75 using ::flutter::testing::keycodes::kLogicalDigit1;
76 using ::flutter::testing::keycodes::kLogicalKeyA;
77 using ::flutter::testing::keycodes::kLogicalKeyB;
78 using ::flutter::testing::keycodes::kLogicalKeyM;
79 using ::flutter::testing::keycodes::kLogicalKeyQ;
80 using ::flutter::testing::keycodes::kLogicalMetaLeft;
81 using ::flutter::testing::keycodes::kLogicalMinus;
82 using ::flutter::testing::keycodes::kLogicalParenthesisRight;
83 using ::flutter::testing::keycodes::kLogicalSemicolon;
84 using ::flutter::testing::keycodes::kLogicalShiftLeft;
85 using ::flutter::testing::keycodes::kLogicalUnderscore;
87 using ::flutter::testing::keycodes::kPhysicalAltLeft;
88 using ::flutter::testing::keycodes::kPhysicalControlLeft;
89 using ::flutter::testing::keycodes::kPhysicalKeyA;
90 using ::flutter::testing::keycodes::kPhysicalKeyB;
91 using ::flutter::testing::keycodes::kPhysicalMetaLeft;
92 using ::flutter::testing::keycodes::kPhysicalShiftLeft;
95 constexpr guint16 kKeyCodeKeyM = 0x3au;
96 constexpr guint16 kKeyCodeDigit1 = 0x0au;
97 constexpr guint16 kKeyCodeMinus = 0x14u;
98 constexpr guint16 kKeyCodeSemicolon = 0x2fu;
99 constexpr guint16 kKeyCodeKeyLeftBracket = 0x22u;
106 typedef std::array<uint32_t, 256> MockGroupLayoutData;
107 typedef std::vector<const MockGroupLayoutData*> MockLayoutData;
109 extern const MockLayoutData kLayoutRussian;
110 extern const MockLayoutData kLayoutFrench;
112 class FlKeyboardManagerTest :
public flutter::testing::LinuxTest {
114 void SetUp()
override {
115 messenger = fl_mock_binary_messenger_new();
116 g_clear_object(&engine);
123 ~FlKeyboardManagerTest() {
124 g_clear_object(&manager);
125 g_clear_object(&messenger);
128 FlMockBinaryMessenger* messenger =
nullptr;
129 FlKeyboardManager* manager =
nullptr;
130 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
133 TEST_F(FlKeyboardManagerTest, EngineNoResponseChannelHandled) {
135 fl_mock_binary_messenger_set_json_message_channel(
136 messenger,
"flutter/keyevent",
137 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
148 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
149 FlutterKeyEventCallback callback,
153 gboolean first_event_completed = FALSE;
155 manager, event1,
nullptr,
156 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
157 gboolean* first_event_completed =
static_cast<gboolean*
>(
user_data);
158 *first_event_completed =
TRUE;
160 &first_event_completed);
164 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
165 FlutterKeyEventCallback callback,
void*
user_data) {
170 0, FALSE,
kKeyCodeKeyA, GDK_KEY_a,
static_cast<GdkModifierType
>(0), 0);
172 manager, event2,
nullptr,
173 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
174 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
176 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
177 EXPECT_EQ(redispatched_event,
nullptr);
178 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
181 g_main_loop_run(loop);
183 EXPECT_FALSE(first_event_completed);
188 TEST_F(FlKeyboardManagerTest, EngineHandledChannelNotHandledSync) {
190 fl_mock_binary_messenger_set_json_message_channel(
191 messenger,
"flutter/keyevent",
192 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
201 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
202 FlutterKeyEventCallback callback,
void*
user_data) {
210 manager, event,
nullptr,
211 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
212 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
214 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
215 EXPECT_EQ(redispatched_event,
nullptr);
216 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
219 g_main_loop_run(loop);
222 TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelHandledSync) {
224 fl_mock_binary_messenger_set_json_message_channel(
225 messenger,
"flutter/keyevent",
226 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
235 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
236 FlutterKeyEventCallback callback,
void*
user_data) {
244 manager, event,
nullptr,
245 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
246 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
248 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
249 EXPECT_EQ(redispatched_event,
nullptr);
250 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
253 g_main_loop_run(loop);
256 TEST_F(FlKeyboardManagerTest, EngineHandledChannelHandledSync) {
258 fl_mock_binary_messenger_set_json_message_channel(
259 messenger,
"flutter/keyevent",
260 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
269 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
270 FlutterKeyEventCallback callback,
void*
user_data) {
278 manager, event,
nullptr,
279 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
280 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
282 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
283 EXPECT_EQ(redispatched_event,
nullptr);
284 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
287 g_main_loop_run(loop);
290 TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledSync) {
292 fl_mock_binary_messenger_set_json_message_channel(
293 messenger,
"flutter/keyevent",
294 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
303 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
304 FlutterKeyEventCallback callback,
void*
user_data) {
312 manager, event,
nullptr,
313 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
314 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
316 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
317 EXPECT_NE(redispatched_event,
nullptr);
318 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
321 g_main_loop_run(loop);
324 static void channel_respond(FlMockBinaryMessenger* messenger,
329 fl_mock_binary_messenger_json_message_channel_respond(messenger, task,
value);
332 TEST_F(FlKeyboardManagerTest, EngineHandledChannelNotHandledAsync) {
335 g_ptr_array_new_with_free_func(g_object_unref);
336 fl_mock_binary_messenger_set_json_message_channel(
337 messenger,
"flutter/keyevent",
338 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
340 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
341 g_ptr_array_add(channel_calls, g_object_ref(task));
343 return static_cast<FlValue*
>(
nullptr);
346 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
349 SendKeyEvent, ([&embedder_call_records](
350 auto engine,
const FlutterKeyEvent* event,
351 FlutterKeyEventCallback callback,
void*
user_data) {
352 g_ptr_array_add(embedder_call_records,
360 manager, event,
nullptr,
361 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
362 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
364 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
365 EXPECT_EQ(redispatched_event,
nullptr);
366 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
370 EXPECT_EQ(embedder_call_records->len, 1u);
371 EXPECT_EQ(channel_calls->len, 1u);
374 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
376 channel_respond(messenger,
377 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
379 g_main_loop_run(loop);
382 TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelHandledAsync) {
385 g_ptr_array_new_with_free_func(g_object_unref);
386 fl_mock_binary_messenger_set_json_message_channel(
387 messenger,
"flutter/keyevent",
388 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
390 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
391 g_ptr_array_add(channel_calls, g_object_ref(task));
393 return static_cast<FlValue*
>(
nullptr);
396 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
399 SendKeyEvent, ([&embedder_call_records](
400 auto engine,
const FlutterKeyEvent* event,
401 FlutterKeyEventCallback callback,
void*
user_data) {
402 g_ptr_array_add(embedder_call_records,
410 manager, event,
nullptr,
411 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
412 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
414 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
415 EXPECT_EQ(redispatched_event,
nullptr);
416 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
420 EXPECT_EQ(embedder_call_records->len, 1u);
421 EXPECT_EQ(channel_calls->len, 1u);
424 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
426 channel_respond(messenger,
427 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
429 g_main_loop_run(loop);
432 TEST_F(FlKeyboardManagerTest, EngineHandledChannelHandledAsync) {
435 g_ptr_array_new_with_free_func(g_object_unref);
436 fl_mock_binary_messenger_set_json_message_channel(
437 messenger,
"flutter/keyevent",
438 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
440 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
441 g_ptr_array_add(channel_calls, g_object_ref(task));
443 return static_cast<FlValue*
>(
nullptr);
446 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
449 SendKeyEvent, ([&embedder_call_records](
450 auto engine,
const FlutterKeyEvent* event,
451 FlutterKeyEventCallback callback,
void*
user_data) {
452 g_ptr_array_add(embedder_call_records,
460 manager, event,
nullptr,
461 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
462 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
464 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
465 EXPECT_EQ(redispatched_event,
nullptr);
466 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
470 EXPECT_EQ(embedder_call_records->len, 1u);
471 EXPECT_EQ(channel_calls->len, 1u);
474 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
476 channel_respond(messenger,
477 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
479 g_main_loop_run(loop);
482 TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledAsync) {
485 g_ptr_array_new_with_free_func(g_object_unref);
486 fl_mock_binary_messenger_set_json_message_channel(
487 messenger,
"flutter/keyevent",
488 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
490 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
491 g_ptr_array_add(channel_calls, g_object_ref(task));
493 return static_cast<FlValue*
>(
nullptr);
496 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
499 SendKeyEvent, ([&embedder_call_records](
500 auto engine,
const FlutterKeyEvent* event,
501 FlutterKeyEventCallback callback,
void*
user_data) {
502 g_ptr_array_add(embedder_call_records,
510 manager, event,
nullptr,
511 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
512 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
514 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
515 EXPECT_NE(redispatched_event,
nullptr);
516 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
520 EXPECT_EQ(embedder_call_records->len, 1u);
521 EXPECT_EQ(channel_calls->len, 1u);
524 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
526 channel_respond(messenger,
527 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
529 g_main_loop_run(loop);
532 TEST_F(FlKeyboardManagerTest, CorrectLogicalKeyForLayouts) {
533 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
537 ([&call_records](
auto engine,
const FlutterKeyEvent* event,
538 FlutterKeyEventCallback callback,
void*
user_data) {
539 g_ptr_array_add(call_records,
546 fl_mock_binary_messenger_set_json_message_channel(
547 messenger,
"flutter/keyevent",
548 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
557 auto sendTap = [&](guint8 keycode, guint keyval, guint8 group) {
559 0,
TRUE, keycode, keyval,
static_cast<GdkModifierType
>(0), group);
563 0, FALSE, keycode, keyval,
static_cast<GdkModifierType
>(0), group);
576 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
579 sendTap(kKeyCodeDigit1, GDK_KEY_exclam, 0);
582 sendTap(kKeyCodeMinus, GDK_KEY_minus, 0);
585 sendTap(kKeyCodeMinus, GDK_KEY_underscore, 0);
593 [](
const GdkKeymapKey* key, gpointer
user_data) {
594 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
595 guint8 group =
static_cast<guint8
>(key->group);
596 EXPECT_LT(group, layout_data->size());
597 const MockGroupLayoutData* group_layout = (*layout_data)[group];
598 EXPECT_NE(group_layout,
nullptr);
599 EXPECT_TRUE(key->level == 0 || key->level == 1);
600 bool shift = key->level == 1;
601 return (*group_layout)[key->keycode * 2 + shift];
603 reinterpret_cast<gpointer
>(
const_cast<MockLayoutData*
>(&kLayoutFrench)));
611 sendTap(kKeyCodeSemicolon, GDK_KEY_m, 3);
614 sendTap(kKeyCodeKeyM, GDK_KEY_comma, 3);
617 sendTap(kKeyCodeDigit1, GDK_KEY_ampersand, 3);
620 sendTap(kKeyCodeDigit1, GDK_KEY_1, 3);
623 sendTap(kKeyCodeMinus, GDK_KEY_parenright, 3);
626 sendTap(kKeyCodeMinus, GDK_KEY_degree, 3);
635 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
641 [](
const GdkKeymapKey* key, gpointer
user_data) {
642 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
643 guint8 group =
static_cast<guint8
>(key->group);
644 EXPECT_LT(group, layout_data->size());
645 const MockGroupLayoutData* group_layout = (*layout_data)[group];
646 EXPECT_NE(group_layout,
nullptr);
647 EXPECT_TRUE(key->level == 0 || key->level == 1);
648 bool shift = key->level == 1;
649 return (*group_layout)[key->keycode * 2 + shift];
651 reinterpret_cast<gpointer
>(
const_cast<MockLayoutData*
>(&kLayoutRussian)));
656 sendTap(kKeyCodeDigit1, GDK_KEY_1, 2);
659 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_Cyrillic_ha, 2);
666 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_bracketleft, 0);
670 TEST_F(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
671 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
675 ([&call_records](
auto engine,
const FlutterKeyEvent* event,
676 FlutterKeyEventCallback callback,
void*
user_data) {
677 g_ptr_array_add(call_records,
682 auto verifyModifierIsSynthesized = [&](GdkModifierType mask,
683 uint64_t physical, uint64_t logical) {
687 EXPECT_EQ(call_records->len, 1u);
689 static_cast<CallRecord*
>(g_ptr_array_index(call_records, 0));
690 EXPECT_EQ(record->
event_type, kFlutterKeyEventTypeDown);
696 state = state ^ mask;
698 EXPECT_EQ(call_records->len, 2u);
699 record =
static_cast<CallRecord*
>(g_ptr_array_index(call_records, 1));
700 EXPECT_EQ(record->
event_type, kFlutterKeyEventTypeUp);
705 g_ptr_array_set_size(call_records, 0);
711 EXPECT_EQ(call_records->len, 0u);
712 g_ptr_array_set_size(call_records, 0);
715 verifyModifierIsSynthesized(GDK_CONTROL_MASK, kPhysicalControlLeft,
716 kLogicalControlLeft);
717 verifyModifierIsSynthesized(GDK_META_MASK, kPhysicalMetaLeft,
719 verifyModifierIsSynthesized(GDK_MOD1_MASK, kPhysicalAltLeft, kLogicalAltLeft);
720 verifyModifierIsSynthesized(GDK_SHIFT_MASK, kPhysicalShiftLeft,
724 TEST_F(FlKeyboardManagerTest, GetPressedState) {
726 fl_mock_binary_messenger_set_json_message_channel(
727 messenger,
"flutter/keyevent",
728 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
736 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
737 FlutterKeyEventCallback callback,
void*
user_data) {
744 manager, event,
nullptr,
745 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
746 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
748 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
749 EXPECT_NE(redispatched_event,
nullptr);
750 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
753 g_main_loop_run(loop);
756 EXPECT_EQ(g_hash_table_size(pressed_state), 1u);
758 gpointer physical_key =
765 const MockGroupLayoutData kLayoutRussian0{
767 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
768 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
769 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
770 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
771 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
772 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
773 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
774 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
775 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
776 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
777 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
778 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
779 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
780 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
781 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
782 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
783 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
784 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
785 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
786 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
787 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
788 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
789 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
790 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
791 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
792 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
793 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
794 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
795 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
796 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
797 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
798 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
801 const MockGroupLayoutData kLayoutRussian2{{
803 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
804 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
805 0xffff, 0x0031, 0x0021, 0x0000, 0x0031, 0x0021, 0x0032, 0x0022,
806 0x0033, 0x06b0, 0x0034, 0x003b, 0x0035, 0x0025, 0x0036, 0x003a,
807 0x0037, 0x003f, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
808 0x002d, 0x005f, 0x003d, 0x002b, 0x0071, 0x0051, 0x0000, 0x0000,
809 0x06ca, 0x06ea, 0x06c3, 0x06e3, 0x06d5, 0x06f5, 0x06cb, 0x06eb,
810 0x06c5, 0x06e5, 0x06ce, 0x06ee, 0x06c7, 0x06e7, 0x06db, 0x06fb,
811 0x06dd, 0x06fd, 0x06da, 0x06fa, 0x06c8, 0x06e8, 0x06df, 0x06ff,
812 0x0061, 0x0041, 0x0041, 0x0000, 0x06c6, 0x06e6, 0x06d9, 0x06f9,
813 0x06d7, 0x06f7, 0x06c1, 0x06e1, 0x06d0, 0x06f0, 0x06d2, 0x06f2,
814 0x06cf, 0x06ef, 0x06cc, 0x06ec, 0x06c4, 0x06e4, 0x06d6, 0x06f6,
815 0x06dc, 0x06fc, 0x06a3, 0x06b3, 0x007c, 0x0000, 0x005c, 0x002f,
816 0x06d1, 0x06f1, 0x06de, 0x06fe, 0x06d3, 0x06f3, 0x06cd, 0x06ed,
817 0x06c9, 0x06e9, 0x06d4, 0x06f4, 0x06d8, 0x06f8, 0x06c2, 0x06e2,
818 0x06c0, 0x06e0, 0x002e, 0x002c, 0xffff, 0xffff, 0xffff, 0xffff,
819 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
820 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
821 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
822 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
823 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
824 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
825 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
826 0xffff, 0xffff, 0x003c, 0x003e, 0x002f, 0x007c, 0xffff, 0xffff,
827 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
828 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
829 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0x0000,
830 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
831 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
832 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
833 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1,
834 0x00b1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
837 const MockGroupLayoutData kLayoutFrench0 = {
839 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
840 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
841 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
842 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
843 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
844 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
845 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
846 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
847 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
848 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
849 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
850 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
851 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
852 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
853 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
854 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
855 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
856 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
857 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
858 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
859 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
860 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
861 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
862 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
863 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
864 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
865 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
866 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
867 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
868 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
869 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
870 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
873 const MockGroupLayoutData kLayoutFrench3 = {
875 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
876 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
877 0x0000, 0xffff, 0x0000, 0x0000, 0x0026, 0x0031, 0x00e9, 0x0032,
878 0x0022, 0x0033, 0x0027, 0x0034, 0x0028, 0x0035, 0x002d, 0x0036,
879 0x00e8, 0x0037, 0x005f, 0x0038, 0x00e7, 0x0039, 0x00e0, 0x0030,
880 0x0029, 0x00b0, 0x003d, 0x002b, 0x0000, 0x0000, 0x0061, 0x0041,
881 0x0061, 0x0041, 0x007a, 0x005a, 0x0065, 0x0045, 0x0072, 0x0052,
882 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
883 0x006f, 0x004f, 0x0070, 0x0050, 0xffff, 0xffff, 0x0024, 0x00a3,
884 0x0041, 0x0000, 0x0000, 0x0000, 0x0071, 0x0051, 0x0073, 0x0053,
885 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
886 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x006d, 0x004d,
887 0x00f9, 0x0025, 0x00b2, 0x007e, 0x0000, 0x0000, 0x002a, 0x00b5,
888 0x0077, 0x0057, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
889 0x0062, 0x0042, 0x006e, 0x004e, 0x002c, 0x003f, 0x003b, 0x002e,
890 0x003a, 0x002f, 0x0021, 0x00a7, 0xffff, 0xffff, 0xffff, 0xffff,
891 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
892 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
893 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
894 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
895 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
896 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
897 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
898 0xffff, 0x003c, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
899 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
900 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
901 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
902 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
903 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
904 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
905 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff,
906 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
909 const MockLayoutData kLayoutRussian{&kLayoutRussian0,
nullptr,
911 const MockLayoutData kLayoutFrench{&kLayoutFrench0,
nullptr,
nullptr,
g_autoptr(FlEngine) engine
const char FlTextDirection FlAssertiveness gpointer user_data
TEST_F(FlAccessibilityHandlerTest, Announce)
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
FlEngine * fl_engine_new_with_binary_messenger(FlBinaryMessenger *binary_messenger)
FlKeyEvent * fl_key_event_new(guint32 time, gboolean is_press, guint16 keycode, guint keyval, GdkModifierType state, guint8 group)
gpointer uint64_to_gpointer(uint64_t number)
uint64_t gpointer_to_uint64(gpointer pointer)
constexpr guint16 kKeyCodeKeyA
FlKeyboardManager * fl_keyboard_manager_new(FlEngine *engine)
void fl_keyboard_manager_handle_event(FlKeyboardManager *self, FlKeyEvent *event, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
gboolean fl_keyboard_manager_handle_event_finish(FlKeyboardManager *self, GAsyncResult *result, FlKeyEvent **redispatched_event, GError **error)
void fl_keyboard_manager_set_lookup_key_handler(FlKeyboardManager *self, FlKeyboardManagerLookupKeyHandler lookup_key_handler, gpointer user_data)
GHashTable * fl_keyboard_manager_get_pressed_state(FlKeyboardManager *self)
void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager *self, guint state, double event_time)
static void call_record_respond(CallRecord *record, bool handled)
static void call_record_free(CallRecord *record)
#define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR)
static CallRecord * call_record_new(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data)
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
G_MODULE_EXPORT FlValue * fl_value_new_map()
typedefG_BEGIN_DECLS struct _FlValue FlValue
FlutterKeyEventCallback callback
FlutterKeyEventType event_type
void * callback_user_data