33 {
35 uint64_t event_physical;
36 uint64_t event_logical;
37 gchar* event_character;
38 bool event_synthesized;
40 void* callback_user_data;
42
45 void* callback_user_data) {
54 return record;
55}
56
59 g_free(record);
60}
61
65 }
66}
67
68namespace {
69using ::flutter::testing::keycodes::kLogicalAltLeft;
70using ::flutter::testing::keycodes::kLogicalBracketLeft;
71using ::flutter::testing::keycodes::kLogicalComma;
72using ::flutter::testing::keycodes::kLogicalControlLeft;
73using ::flutter::testing::keycodes::kLogicalDigit1;
74using ::flutter::testing::keycodes::kLogicalKeyA;
75using ::flutter::testing::keycodes::kLogicalKeyB;
76using ::flutter::testing::keycodes::kLogicalKeyM;
77using ::flutter::testing::keycodes::kLogicalKeyQ;
78using ::flutter::testing::keycodes::kLogicalMetaLeft;
79using ::flutter::testing::keycodes::kLogicalMinus;
80using ::flutter::testing::keycodes::kLogicalParenthesisRight;
81using ::flutter::testing::keycodes::kLogicalSemicolon;
82using ::flutter::testing::keycodes::kLogicalShiftLeft;
83using ::flutter::testing::keycodes::kLogicalUnderscore;
84
85using ::flutter::testing::keycodes::kPhysicalAltLeft;
86using ::flutter::testing::keycodes::kPhysicalControlLeft;
87using ::flutter::testing::keycodes::kPhysicalKeyA;
88using ::flutter::testing::keycodes::kPhysicalKeyB;
89using ::flutter::testing::keycodes::kPhysicalMetaLeft;
90using ::flutter::testing::keycodes::kPhysicalShiftLeft;
91
93constexpr guint16 kKeyCodeKeyM = 0x3au;
94constexpr guint16 kKeyCodeDigit1 = 0x0au;
95constexpr guint16 kKeyCodeMinus = 0x14u;
96constexpr guint16 kKeyCodeSemicolon = 0x2fu;
97constexpr guint16 kKeyCodeKeyLeftBracket = 0x22u;
98
99
100
101
102
103
104typedef std::array<uint32_t, 256> MockGroupLayoutData;
105typedef std::vector<const MockGroupLayoutData*> MockLayoutData;
106
107extern const MockLayoutData kLayoutRussian;
108extern const MockLayoutData kLayoutFrench;
109
110TEST(FlKeyboardManagerTest, EngineNoResponseChannelHandled) {
111 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
112
114
116 messenger, "flutter/keyevent",
117 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
123 },
124 nullptr);
125
129
131
132
139 gboolean first_event_completed = FALSE;
141 manager, event1, nullptr,
142 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
143 gboolean* first_event_completed =
static_cast<gboolean*
>(
user_data);
144 *first_event_completed =
TRUE;
145 },
146 &first_event_completed);
147
148
154 }));
156 0, FALSE,
kKeyCodeKeyA, GDK_KEY_a,
static_cast<GdkModifierType
>(0), 0);
157 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
159 manager, event2, nullptr,
160 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
161 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
163 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
164 EXPECT_EQ(redispatched_event, nullptr);
165 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
166 },
167 loop);
168 g_main_loop_run(loop);
169
170 EXPECT_FALSE(first_event_completed);
171
172
173}
174
175TEST(FlKeyboardManagerTest, EngineHandledChannelNotHandledSync) {
176 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
177
179
183
185
186
188 messenger, "flutter/keyevent",
189 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
195 },
196 nullptr);
202 }));
203
206 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
208 manager, event, nullptr,
209 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
210 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
212 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
213 EXPECT_EQ(redispatched_event, nullptr);
214 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
215 },
216 loop);
217 g_main_loop_run(loop);
218}
219
220TEST(FlKeyboardManagerTest, EngineNotHandledChannelHandledSync) {
221 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
222
224
228
230
231
233 messenger, "flutter/keyevent",
234 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
240 },
241 nullptr);
247 }));
248
251 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
253 manager, event, nullptr,
254 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
255 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
257 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
258 EXPECT_EQ(redispatched_event, nullptr);
259 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
260 },
261 loop);
262 g_main_loop_run(loop);
263}
264
265TEST(FlKeyboardManagerTest, EngineHandledChannelHandledSync) {
266 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
267
269
273
275
276
278 messenger, "flutter/keyevent",
279 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
285 },
286 nullptr);
292 }));
293
296 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
298 manager, event, nullptr,
299 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
300 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
302 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
303 EXPECT_EQ(redispatched_event, nullptr);
304 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
305 },
306 loop);
307 g_main_loop_run(loop);
308}
309
310TEST(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledSync) {
311 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
312
314
318
320
321
323 messenger, "flutter/keyevent",
324 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
330 },
331 nullptr);
337 }));
338
341 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
343 manager, event, nullptr,
344 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
345 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
347 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
348 EXPECT_NE(redispatched_event, nullptr);
349 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
350 },
351 loop);
352 g_main_loop_run(loop);
353}
354
355static void channel_respond(FlMockBinaryMessenger* messenger,
356 GTask* task,
357 gboolean handled) {
361}
362
363TEST(FlKeyboardManagerTest, EngineHandledChannelNotHandledAsync) {
364 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
365
367
371
373
374
376 g_ptr_array_new_with_free_func(g_object_unref);
378 messenger, "flutter/keyevent",
379 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
381 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
382 g_ptr_array_add(channel_calls, g_object_ref(task));
383
384 return static_cast<FlValue*
>(
nullptr);
385 },
386 channel_calls);
387 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
390 SendKeyEvent, ([&embedder_call_records](
393 g_ptr_array_add(embedder_call_records,
396 }));
397
400 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
402 manager, event, nullptr,
403 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
404 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
406 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
407 EXPECT_EQ(redispatched_event, nullptr);
408 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
409 },
410 loop);
411
412 EXPECT_EQ(embedder_call_records->len, 1u);
413 EXPECT_EQ(channel_calls->len, 1u);
414
416 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
417 true);
418 channel_respond(messenger,
419 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
420 FALSE);
421 g_main_loop_run(loop);
422}
423
424TEST(FlKeyboardManagerTest, EngineNotHandledChannelHandledAsync) {
425 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
426
428
432
434
435
437 g_ptr_array_new_with_free_func(g_object_unref);
439 messenger, "flutter/keyevent",
440 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
442 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
443 g_ptr_array_add(channel_calls, g_object_ref(task));
444
445 return static_cast<FlValue*
>(
nullptr);
446 },
447 channel_calls);
448 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
451 SendKeyEvent, ([&embedder_call_records](
454 g_ptr_array_add(embedder_call_records,
457 }));
458
461 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
463 manager, event, nullptr,
464 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
465 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
467 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
468 EXPECT_EQ(redispatched_event, nullptr);
469 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
470 },
471 loop);
472
473 EXPECT_EQ(embedder_call_records->len, 1u);
474 EXPECT_EQ(channel_calls->len, 1u);
475
477 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
478 false);
479 channel_respond(messenger,
480 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
482 g_main_loop_run(loop);
483}
484
485TEST(FlKeyboardManagerTest, EngineHandledChannelHandledAsync) {
486 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
487
489
493
495
496
498 g_ptr_array_new_with_free_func(g_object_unref);
500 messenger, "flutter/keyevent",
501 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
503 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
504 g_ptr_array_add(channel_calls, g_object_ref(task));
505
506 return static_cast<FlValue*
>(
nullptr);
507 },
508 channel_calls);
509 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
512 SendKeyEvent, ([&embedder_call_records](
515 g_ptr_array_add(embedder_call_records,
518 }));
519
522 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
524 manager, event, nullptr,
525 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
526 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
528 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
529 EXPECT_EQ(redispatched_event, nullptr);
530 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
531 },
532 loop);
533
534 EXPECT_EQ(embedder_call_records->len, 1u);
535 EXPECT_EQ(channel_calls->len, 1u);
536
538 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
539 true);
540 channel_respond(messenger,
541 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
543 g_main_loop_run(loop);
544}
545
546TEST(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledAsync) {
547 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
548
550
554
556
557
559 g_ptr_array_new_with_free_func(g_object_unref);
561 messenger, "flutter/keyevent",
562 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
564 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
565 g_ptr_array_add(channel_calls, g_object_ref(task));
566
567 return static_cast<FlValue*
>(
nullptr);
568 },
569 channel_calls);
570 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
573 SendKeyEvent, ([&embedder_call_records](
576 g_ptr_array_add(embedder_call_records,
579 }));
580
583 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
585 manager, event, nullptr,
586 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
587 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
589 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
590 EXPECT_NE(redispatched_event, nullptr);
591 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
592 },
593 loop);
594
595 EXPECT_EQ(embedder_call_records->len, 1u);
596 EXPECT_EQ(channel_calls->len, 1u);
597
599 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
600 false);
601 channel_respond(messenger,
602 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
603 FALSE);
604 g_main_loop_run(loop);
605}
606
607TEST(FlKeyboardManagerTest, CorrectLogicalKeyForLayouts) {
608 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
609
613
615
616 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
619 SendKeyEvent,
622 g_ptr_array_add(call_records,
625 }));
626
627 auto sendTap = [&](guint8 keycode, guint keyval, guint8 group) {
629 0,
TRUE, keycode, keyval,
static_cast<GdkModifierType
>(0), group);
631 nullptr);
633 0, FALSE, keycode, keyval, static_cast<GdkModifierType>(0), group);
635 nullptr);
636 };
637
638
639
642
645
646 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
648
649 sendTap(kKeyCodeDigit1, GDK_KEY_exclam, 0);
651
652 sendTap(kKeyCodeMinus, GDK_KEY_minus, 0);
654
655 sendTap(kKeyCodeMinus, GDK_KEY_underscore, 0);
657
658
659
660
662 manager,
664 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
665 guint8 group =
static_cast<guint8
>(
key->group);
666 EXPECT_LT(group, layout_data->size());
667 const MockGroupLayoutData* group_layout = (*layout_data)[group];
668 EXPECT_NE(group_layout, nullptr);
669 EXPECT_TRUE(
key->level == 0 ||
key->level == 1);
670 bool shift =
key->level == 1;
671 return (*group_layout)[
key->keycode * 2 + shift];
672 },
673 reinterpret_cast<gpointer>(const_cast<MockLayoutData*>(&kLayoutFrench)));
674
677
680
681 sendTap(kKeyCodeSemicolon, GDK_KEY_m, 3);
683
684 sendTap(kKeyCodeKeyM, GDK_KEY_comma, 3);
686
687 sendTap(kKeyCodeDigit1, GDK_KEY_ampersand, 3);
689
690 sendTap(kKeyCodeDigit1, GDK_KEY_1, 3);
692
693 sendTap(kKeyCodeMinus, GDK_KEY_parenright, 3);
695
696 sendTap(kKeyCodeMinus, GDK_KEY_degree, 3);
698
699
700
701
704
705 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
707
708
710 manager,
712 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
713 guint8 group =
static_cast<guint8
>(
key->group);
714 EXPECT_LT(group, layout_data->size());
715 const MockGroupLayoutData* group_layout = (*layout_data)[group];
716 EXPECT_NE(group_layout, nullptr);
717 EXPECT_TRUE(
key->level == 0 ||
key->level == 1);
718 bool shift =
key->level == 1;
719 return (*group_layout)[
key->keycode * 2 + shift];
720 },
721 reinterpret_cast<gpointer>(const_cast<MockLayoutData*>(&kLayoutRussian)));
722
725
726 sendTap(kKeyCodeDigit1, GDK_KEY_1, 2);
728
729 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_Cyrillic_ha, 2);
731
732
735
736 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_bracketleft, 0);
738}
739
740TEST(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
741 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
742
746
748
749 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
752 SendKeyEvent,
755 g_ptr_array_add(call_records,
758 }));
759
760 auto verifyModifierIsSynthesized = [&](GdkModifierType mask,
761 uint64_t physical, uint64_t logical) {
762
763 guint state = mask;
765 EXPECT_EQ(call_records->len, 1u);
767 static_cast<CallRecord*
>(g_ptr_array_index(call_records, 0));
773
774 state = state ^ mask;
776 EXPECT_EQ(call_records->len, 2u);
777 record =
static_cast<CallRecord*
>(g_ptr_array_index(call_records, 1));
783 g_ptr_array_set_size(call_records, 0);
784 };
785
786
787 guint state = 0;
789 EXPECT_EQ(call_records->len, 0u);
790 g_ptr_array_set_size(call_records, 0);
791
792
793 verifyModifierIsSynthesized(GDK_CONTROL_MASK, kPhysicalControlLeft,
794 kLogicalControlLeft);
795 verifyModifierIsSynthesized(GDK_META_MASK, kPhysicalMetaLeft,
796 kLogicalMetaLeft);
797 verifyModifierIsSynthesized(GDK_MOD1_MASK, kPhysicalAltLeft, kLogicalAltLeft);
798 verifyModifierIsSynthesized(GDK_SHIFT_MASK, kPhysicalShiftLeft,
799 kLogicalShiftLeft);
800}
801
802TEST(FlKeyboardManagerTest, GetPressedState) {
803 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
804
809
811
812
814 messenger, "flutter/keyevent",
815 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
819 return response;
820 },
821 nullptr);
827 }));
830 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
832 manager, event, nullptr,
833 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
834 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
836 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
837 EXPECT_NE(redispatched_event, nullptr);
838 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
839 },
840 loop);
841 g_main_loop_run(loop);
842
844 EXPECT_EQ(g_hash_table_size(pressed_state), 1u);
845
846 gpointer physical_key =
849}
850
851
852
853const MockGroupLayoutData kLayoutRussian0{
854
855 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
856 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
857 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
858 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
859 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
860 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
861 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
862 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
863 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
864 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
865 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
866 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
867 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
868 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
869 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
870 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
871 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
872 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
873 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
874 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
875 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
876 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
877 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
878 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
879 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
880 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
881 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
882 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
883 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
884 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
885 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
886 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
887};
888
889const MockGroupLayoutData kLayoutRussian2{{
890
891 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
892 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
893 0xffff, 0x0031, 0x0021, 0x0000, 0x0031, 0x0021, 0x0032, 0x0022,
894 0x0033, 0x06b0, 0x0034, 0x003b, 0x0035, 0x0025, 0x0036, 0x003a,
895 0x0037, 0x003f, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
896 0x002d, 0x005f, 0x003d, 0x002b, 0x0071, 0x0051, 0x0000, 0x0000,
897 0x06ca, 0x06ea, 0x06c3, 0x06e3, 0x06d5, 0x06f5, 0x06cb, 0x06eb,
898 0x06c5, 0x06e5, 0x06ce, 0x06ee, 0x06c7, 0x06e7, 0x06db, 0x06fb,
899 0x06dd, 0x06fd, 0x06da, 0x06fa, 0x06c8, 0x06e8, 0x06df, 0x06ff,
900 0x0061, 0x0041, 0x0041, 0x0000, 0x06c6, 0x06e6, 0x06d9, 0x06f9,
901 0x06d7, 0x06f7, 0x06c1, 0x06e1, 0x06d0, 0x06f0, 0x06d2, 0x06f2,
902 0x06cf, 0x06ef, 0x06cc, 0x06ec, 0x06c4, 0x06e4, 0x06d6, 0x06f6,
903 0x06dc, 0x06fc, 0x06a3, 0x06b3, 0x007c, 0x0000, 0x005c, 0x002f,
904 0x06d1, 0x06f1, 0x06de, 0x06fe, 0x06d3, 0x06f3, 0x06cd, 0x06ed,
905 0x06c9, 0x06e9, 0x06d4, 0x06f4, 0x06d8, 0x06f8, 0x06c2, 0x06e2,
906 0x06c0, 0x06e0, 0x002e, 0x002c, 0xffff, 0xffff, 0xffff, 0xffff,
907 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
908 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
909 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
910 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
911 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
912 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
913 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
914 0xffff, 0xffff, 0x003c, 0x003e, 0x002f, 0x007c, 0xffff, 0xffff,
915 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
916 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
917 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0x0000,
918 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
919 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
920 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
921 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1,
922 0x00b1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
923}};
924
925const MockGroupLayoutData kLayoutFrench0 = {
926
927 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
928 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
929 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
930 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
931 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
932 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
933 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
934 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
935 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
936 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
937 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
938 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
939 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
940 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
941 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
942 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
943 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
944 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
945 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
946 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
947 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
948 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
949 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
950 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
951 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
952 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
953 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
954 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
955 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
956 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
957 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
958 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
959};
960
961const MockGroupLayoutData kLayoutFrench3 = {
962
963 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
964 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
965 0x0000, 0xffff, 0x0000, 0x0000, 0x0026, 0x0031, 0x00e9, 0x0032,
966 0x0022, 0x0033, 0x0027, 0x0034, 0x0028, 0x0035, 0x002d, 0x0036,
967 0x00e8, 0x0037, 0x005f, 0x0038, 0x00e7, 0x0039, 0x00e0, 0x0030,
968 0x0029, 0x00b0, 0x003d, 0x002b, 0x0000, 0x0000, 0x0061, 0x0041,
969 0x0061, 0x0041, 0x007a, 0x005a, 0x0065, 0x0045, 0x0072, 0x0052,
970 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
971 0x006f, 0x004f, 0x0070, 0x0050, 0xffff, 0xffff, 0x0024, 0x00a3,
972 0x0041, 0x0000, 0x0000, 0x0000, 0x0071, 0x0051, 0x0073, 0x0053,
973 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
974 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x006d, 0x004d,
975 0x00f9, 0x0025, 0x00b2, 0x007e, 0x0000, 0x0000, 0x002a, 0x00b5,
976 0x0077, 0x0057, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
977 0x0062, 0x0042, 0x006e, 0x004e, 0x002c, 0x003f, 0x003b, 0x002e,
978 0x003a, 0x002f, 0x0021, 0x00a7, 0xffff, 0xffff, 0xffff, 0xffff,
979 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
980 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
981 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
982 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
983 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
984 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
985 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
986 0xffff, 0x003c, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
987 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
988 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
989 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
990 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
991 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
992 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
993 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff,
994 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
995};
996
997const MockLayoutData kLayoutRussian{&kLayoutRussian0, nullptr,
998 &kLayoutRussian2};
999const MockLayoutData kLayoutFrench{&kLayoutFrench0, nullptr, nullptr,
1000 &kLayoutFrench3};
1001
1002}
TEST(AsciiTableTest, Simple)
void(* FlutterKeyEventCallback)(bool, void *)
g_autoptr(GMutexLocker) locker
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
FlEngine * fl_engine_new_with_binary_messenger(FlBinaryMessenger *binary_messenger)
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
gboolean fl_engine_start(FlEngine *self, GError **error)
FlKeyEvent * fl_key_event_new(guint32 time, gboolean is_press, guint16 keycode, guint keyval, GdkModifierType state, guint8 group)
constexpr guint16 kKeyCodeKeyA
void fl_keyboard_manager_handle_event(FlKeyboardManager *self, FlKeyEvent *event, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
GHashTable * fl_keyboard_manager_get_pressed_state(FlKeyboardManager *self)
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)
FlKeyboardManager * fl_keyboard_manager_new(FlEngine *engine)
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)
FlMockBinaryMessenger * fl_mock_binary_messenger_new()
void fl_mock_binary_messenger_json_message_channel_respond(FlMockBinaryMessenger *self, GTask *task, FlValue *value)
void fl_mock_binary_messenger_set_json_message_channel(FlMockBinaryMessenger *self, const gchar *channel, FlMockBinaryMessengerMessageChannelHandler handler, gpointer user_data)
G_BEGIN_DECLS GBytes * message
G_MODULE_EXPORT FlValue * fl_value_new_map()
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
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)
typedefG_BEGIN_DECLS struct _FlValue FlValue
FlutterDesktopBinaryReply callback
gpointer uint64_to_gpointer(uint64_t number)
uint64_t gpointer_to_uint64(gpointer pointer)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
#define MOCK_ENGINE_PROC(proc, mock_impl)
FlutterKeyEventCallback callback
FlutterKeyEventType event_type
void * callback_user_data
FlutterEngineSendKeyEventFnPtr SendKeyEvent