34 {
36 uint64_t event_physical;
37 uint64_t event_logical;
38 gchar* event_character;
39 bool event_synthesized;
41 void* callback_user_data;
43
46 void* callback_user_data) {
55 return record;
56}
57
60 g_free(record);
61}
62
66 }
67}
68
69namespace {
70using ::flutter::testing::keycodes::kLogicalAltLeft;
71using ::flutter::testing::keycodes::kLogicalBracketLeft;
72using ::flutter::testing::keycodes::kLogicalComma;
73using ::flutter::testing::keycodes::kLogicalControlLeft;
74using ::flutter::testing::keycodes::kLogicalDigit1;
75using ::flutter::testing::keycodes::kLogicalKeyA;
76using ::flutter::testing::keycodes::kLogicalKeyB;
77using ::flutter::testing::keycodes::kLogicalKeyM;
78using ::flutter::testing::keycodes::kLogicalKeyQ;
79using ::flutter::testing::keycodes::kLogicalMetaLeft;
80using ::flutter::testing::keycodes::kLogicalMinus;
81using ::flutter::testing::keycodes::kLogicalParenthesisRight;
82using ::flutter::testing::keycodes::kLogicalSemicolon;
83using ::flutter::testing::keycodes::kLogicalShiftLeft;
84using ::flutter::testing::keycodes::kLogicalUnderscore;
85
86using ::flutter::testing::keycodes::kPhysicalAltLeft;
87using ::flutter::testing::keycodes::kPhysicalControlLeft;
88using ::flutter::testing::keycodes::kPhysicalKeyA;
89using ::flutter::testing::keycodes::kPhysicalKeyB;
90using ::flutter::testing::keycodes::kPhysicalMetaLeft;
91using ::flutter::testing::keycodes::kPhysicalShiftLeft;
92
94constexpr guint16 kKeyCodeKeyM = 0x3au;
95constexpr guint16 kKeyCodeDigit1 = 0x0au;
96constexpr guint16 kKeyCodeMinus = 0x14u;
97constexpr guint16 kKeyCodeSemicolon = 0x2fu;
98constexpr guint16 kKeyCodeKeyLeftBracket = 0x22u;
99
100
101
102
103
104
105typedef std::array<uint32_t, 256> MockGroupLayoutData;
106typedef std::vector<const MockGroupLayoutData*> MockLayoutData;
107
108extern const MockLayoutData kLayoutRussian;
109extern const MockLayoutData kLayoutFrench;
110
112 protected:
113 void SetUp() override {
120 }
121
122 ~FlKeyboardManagerTest() {
123 g_clear_object(&manager);
124 g_clear_object(&messenger);
125 }
126
127 FlMockBinaryMessenger* messenger = nullptr;
128 FlKeyboardManager*
manager =
nullptr;
129 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
130};
131
132TEST_F(FlKeyboardManagerTest, EngineNoResponseChannelHandled) {
133
135 messenger, "flutter/keyevent",
136 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
142 },
143 nullptr);
144
145
152 gboolean first_event_completed = FALSE;
154 manager, event1, nullptr,
155 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
156 gboolean* first_event_completed =
static_cast<gboolean*
>(
user_data);
157 *first_event_completed =
TRUE;
158 },
159 &first_event_completed);
160
161
167 }));
169 0, FALSE,
kKeyCodeKeyA, GDK_KEY_a,
static_cast<GdkModifierType
>(0), 0);
171 manager, event2, nullptr,
172 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
173 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
175 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
176 EXPECT_EQ(redispatched_event, nullptr);
177 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
178 },
179 loop);
180 g_main_loop_run(loop);
181
182 EXPECT_FALSE(first_event_completed);
183
184
185}
186
187TEST_F(FlKeyboardManagerTest, EngineHandledChannelNotHandledSync) {
188
190 messenger, "flutter/keyevent",
191 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
197 },
198 nullptr);
204 }));
205
209 manager, event, nullptr,
210 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
211 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
213 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
214 EXPECT_EQ(redispatched_event, nullptr);
215 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
216 },
217 loop);
218 g_main_loop_run(loop);
219}
220
221TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelHandledSync) {
222
224 messenger, "flutter/keyevent",
225 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
231 },
232 nullptr);
238 }));
239
243 manager, event, nullptr,
244 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
245 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
247 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
248 EXPECT_EQ(redispatched_event, nullptr);
249 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
250 },
251 loop);
252 g_main_loop_run(loop);
253}
254
255TEST_F(FlKeyboardManagerTest, EngineHandledChannelHandledSync) {
256
258 messenger, "flutter/keyevent",
259 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
265 },
266 nullptr);
272 }));
273
277 manager, event, nullptr,
278 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
279 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
281 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
282 EXPECT_EQ(redispatched_event, nullptr);
283 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
284 },
285 loop);
286 g_main_loop_run(loop);
287}
288
289TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledSync) {
290
292 messenger, "flutter/keyevent",
293 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
299 },
300 nullptr);
306 }));
307
311 manager, event, nullptr,
312 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
313 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
315 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
316 EXPECT_NE(redispatched_event, nullptr);
317 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
318 },
319 loop);
320 g_main_loop_run(loop);
321}
322
323static void channel_respond(FlMockBinaryMessenger* messenger,
324 GTask* task,
325 gboolean handled) {
329}
330
331TEST_F(FlKeyboardManagerTest, EngineHandledChannelNotHandledAsync) {
332
334 g_ptr_array_new_with_free_func(g_object_unref);
336 messenger, "flutter/keyevent",
337 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
339 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
340 g_ptr_array_add(channel_calls, g_object_ref(task));
341
342 return static_cast<FlValue*
>(
nullptr);
343 },
344 channel_calls);
345 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
348 SendKeyEvent, ([&embedder_call_records](
351 g_ptr_array_add(embedder_call_records,
354 }));
355
359 manager, event, nullptr,
360 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
361 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
363 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
364 EXPECT_EQ(redispatched_event, nullptr);
365 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
366 },
367 loop);
368
369 EXPECT_EQ(embedder_call_records->len, 1u);
370 EXPECT_EQ(channel_calls->len, 1u);
371
373 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
374 true);
375 channel_respond(messenger,
376 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
377 FALSE);
378 g_main_loop_run(loop);
379}
380
381TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelHandledAsync) {
382
384 g_ptr_array_new_with_free_func(g_object_unref);
386 messenger, "flutter/keyevent",
387 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
389 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
390 g_ptr_array_add(channel_calls, g_object_ref(task));
391
392 return static_cast<FlValue*
>(
nullptr);
393 },
394 channel_calls);
395 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
398 SendKeyEvent, ([&embedder_call_records](
401 g_ptr_array_add(embedder_call_records,
404 }));
405
409 manager, event, nullptr,
410 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
411 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
413 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
414 EXPECT_EQ(redispatched_event, nullptr);
415 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
416 },
417 loop);
418
419 EXPECT_EQ(embedder_call_records->len, 1u);
420 EXPECT_EQ(channel_calls->len, 1u);
421
423 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
424 false);
425 channel_respond(messenger,
426 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
428 g_main_loop_run(loop);
429}
430
431TEST_F(FlKeyboardManagerTest, EngineHandledChannelHandledAsync) {
432
434 g_ptr_array_new_with_free_func(g_object_unref);
436 messenger, "flutter/keyevent",
437 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
439 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
440 g_ptr_array_add(channel_calls, g_object_ref(task));
441
442 return static_cast<FlValue*
>(
nullptr);
443 },
444 channel_calls);
445 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
448 SendKeyEvent, ([&embedder_call_records](
451 g_ptr_array_add(embedder_call_records,
454 }));
455
459 manager, event, nullptr,
460 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
461 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
463 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
464 EXPECT_EQ(redispatched_event, nullptr);
465 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
466 },
467 loop);
468
469 EXPECT_EQ(embedder_call_records->len, 1u);
470 EXPECT_EQ(channel_calls->len, 1u);
471
473 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
474 true);
475 channel_respond(messenger,
476 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
478 g_main_loop_run(loop);
479}
480
481TEST_F(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledAsync) {
482
484 g_ptr_array_new_with_free_func(g_object_unref);
486 messenger, "flutter/keyevent",
487 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
489 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
490 g_ptr_array_add(channel_calls, g_object_ref(task));
491
492 return static_cast<FlValue*
>(
nullptr);
493 },
494 channel_calls);
495 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
498 SendKeyEvent, ([&embedder_call_records](
501 g_ptr_array_add(embedder_call_records,
504 }));
505
509 manager, event, nullptr,
510 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
511 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
513 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
514 EXPECT_NE(redispatched_event, nullptr);
515 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
516 },
517 loop);
518
519 EXPECT_EQ(embedder_call_records->len, 1u);
520 EXPECT_EQ(channel_calls->len, 1u);
521
523 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
524 false);
525 channel_respond(messenger,
526 static_cast<GTask*>(g_ptr_array_index(channel_calls, 0)),
527 FALSE);
528 g_main_loop_run(loop);
529}
530
531TEST_F(FlKeyboardManagerTest, CorrectLogicalKeyForLayouts) {
532 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
535 SendKeyEvent,
538 g_ptr_array_add(call_records,
541 }));
542
543
544
546 messenger, "flutter/keyevent",
547 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
553 },
554 nullptr);
555
556 auto sendTap = [&](guint8 keycode, guint keyval, guint8 group) {
558 0,
TRUE, keycode, keyval,
static_cast<GdkModifierType
>(0), group);
560 nullptr);
562 0, FALSE, keycode, keyval, static_cast<GdkModifierType>(0), group);
564 nullptr);
565 };
566
567
568
571
574
575 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
577
578 sendTap(kKeyCodeDigit1, GDK_KEY_exclam, 0);
580
581 sendTap(kKeyCodeMinus, GDK_KEY_minus, 0);
583
584 sendTap(kKeyCodeMinus, GDK_KEY_underscore, 0);
586
587
588
589
591 manager,
593 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
594 guint8 group =
static_cast<guint8
>(
key->group);
595 EXPECT_LT(group, layout_data->size());
596 const MockGroupLayoutData* group_layout = (*layout_data)[group];
597 EXPECT_NE(group_layout, nullptr);
598 EXPECT_TRUE(
key->level == 0 ||
key->level == 1);
599 bool shift =
key->level == 1;
600 return (*group_layout)[
key->keycode * 2 + shift];
601 },
602 reinterpret_cast<gpointer>(const_cast<MockLayoutData*>(&kLayoutFrench)));
603
606
609
610 sendTap(kKeyCodeSemicolon, GDK_KEY_m, 3);
612
613 sendTap(kKeyCodeKeyM, GDK_KEY_comma, 3);
615
616 sendTap(kKeyCodeDigit1, GDK_KEY_ampersand, 3);
618
619 sendTap(kKeyCodeDigit1, GDK_KEY_1, 3);
621
622 sendTap(kKeyCodeMinus, GDK_KEY_parenright, 3);
624
625 sendTap(kKeyCodeMinus, GDK_KEY_degree, 3);
627
628
629
630
633
634 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
636
637
639 manager,
641 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
642 guint8 group =
static_cast<guint8
>(
key->group);
643 EXPECT_LT(group, layout_data->size());
644 const MockGroupLayoutData* group_layout = (*layout_data)[group];
645 EXPECT_NE(group_layout, nullptr);
646 EXPECT_TRUE(
key->level == 0 ||
key->level == 1);
647 bool shift =
key->level == 1;
648 return (*group_layout)[
key->keycode * 2 + shift];
649 },
650 reinterpret_cast<gpointer>(const_cast<MockLayoutData*>(&kLayoutRussian)));
651
654
655 sendTap(kKeyCodeDigit1, GDK_KEY_1, 2);
657
658 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_Cyrillic_ha, 2);
660
661
664
665 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_bracketleft, 0);
667}
668
669TEST_F(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
670 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
673 SendKeyEvent,
676 g_ptr_array_add(call_records,
679 }));
680
681 auto verifyModifierIsSynthesized = [&](GdkModifierType mask,
682 uint64_t physical, uint64_t logical) {
683
684 guint state = mask;
686 EXPECT_EQ(call_records->len, 1u);
688 static_cast<CallRecord*
>(g_ptr_array_index(call_records, 0));
694
695 state = state ^ mask;
697 EXPECT_EQ(call_records->len, 2u);
698 record =
static_cast<CallRecord*
>(g_ptr_array_index(call_records, 1));
704 g_ptr_array_set_size(call_records, 0);
705 };
706
707
708 guint state = 0;
710 EXPECT_EQ(call_records->len, 0u);
711 g_ptr_array_set_size(call_records, 0);
712
713
714 verifyModifierIsSynthesized(GDK_CONTROL_MASK, kPhysicalControlLeft,
715 kLogicalControlLeft);
716 verifyModifierIsSynthesized(GDK_META_MASK, kPhysicalMetaLeft,
717 kLogicalMetaLeft);
718 verifyModifierIsSynthesized(GDK_MOD1_MASK, kPhysicalAltLeft, kLogicalAltLeft);
719 verifyModifierIsSynthesized(GDK_SHIFT_MASK, kPhysicalShiftLeft,
720 kLogicalShiftLeft);
721}
722
723TEST_F(FlKeyboardManagerTest, GetPressedState) {
724
726 messenger, "flutter/keyevent",
727 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue*
message,
731 return response;
732 },
733 nullptr);
739 }));
743 manager, event, nullptr,
744 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
745 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
747 FL_KEYBOARD_MANAGER(object), result, &redispatched_event, nullptr));
748 EXPECT_NE(redispatched_event, nullptr);
749 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
750 },
751 loop);
752 g_main_loop_run(loop);
753
755 EXPECT_EQ(g_hash_table_size(pressed_state), 1u);
756
757 gpointer physical_key =
760}
761
762
763
764const MockGroupLayoutData kLayoutRussian0{
765
766 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
767 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
768 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
769 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
770 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
771 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
772 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
773 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
774 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
775 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
776 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
777 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
778 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
779 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
780 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
781 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
782 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
783 0xffff, 0xffff, 0xffff, 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, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
790 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
791 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
792 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 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 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
797 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
798};
799
800const MockGroupLayoutData kLayoutRussian2{{
801
802 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
803 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
804 0xffff, 0x0031, 0x0021, 0x0000, 0x0031, 0x0021, 0x0032, 0x0022,
805 0x0033, 0x06b0, 0x0034, 0x003b, 0x0035, 0x0025, 0x0036, 0x003a,
806 0x0037, 0x003f, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
807 0x002d, 0x005f, 0x003d, 0x002b, 0x0071, 0x0051, 0x0000, 0x0000,
808 0x06ca, 0x06ea, 0x06c3, 0x06e3, 0x06d5, 0x06f5, 0x06cb, 0x06eb,
809 0x06c5, 0x06e5, 0x06ce, 0x06ee, 0x06c7, 0x06e7, 0x06db, 0x06fb,
810 0x06dd, 0x06fd, 0x06da, 0x06fa, 0x06c8, 0x06e8, 0x06df, 0x06ff,
811 0x0061, 0x0041, 0x0041, 0x0000, 0x06c6, 0x06e6, 0x06d9, 0x06f9,
812 0x06d7, 0x06f7, 0x06c1, 0x06e1, 0x06d0, 0x06f0, 0x06d2, 0x06f2,
813 0x06cf, 0x06ef, 0x06cc, 0x06ec, 0x06c4, 0x06e4, 0x06d6, 0x06f6,
814 0x06dc, 0x06fc, 0x06a3, 0x06b3, 0x007c, 0x0000, 0x005c, 0x002f,
815 0x06d1, 0x06f1, 0x06de, 0x06fe, 0x06d3, 0x06f3, 0x06cd, 0x06ed,
816 0x06c9, 0x06e9, 0x06d4, 0x06f4, 0x06d8, 0x06f8, 0x06c2, 0x06e2,
817 0x06c0, 0x06e0, 0x002e, 0x002c, 0xffff, 0xffff, 0xffff, 0xffff,
818 0xffff, 0xffff, 0xffff, 0xffff, 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, 0x003c, 0x003e, 0x002f, 0x007c, 0xffff, 0xffff,
826 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
827 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
828 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0x0000,
829 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
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, 0x00b1,
833 0x00b1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
834}};
835
836const MockGroupLayoutData kLayoutFrench0 = {
837
838 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
839 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
840 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
841 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
842 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
843 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
844 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
845 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
846 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
847 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
848 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
849 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
850 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
851 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
852 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
853 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
854 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
855 0xffff, 0xffff, 0xffff, 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, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
862 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
863 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
864 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 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 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
869 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
870};
871
872const MockGroupLayoutData kLayoutFrench3 = {
873
874 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
875 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
876 0x0000, 0xffff, 0x0000, 0x0000, 0x0026, 0x0031, 0x00e9, 0x0032,
877 0x0022, 0x0033, 0x0027, 0x0034, 0x0028, 0x0035, 0x002d, 0x0036,
878 0x00e8, 0x0037, 0x005f, 0x0038, 0x00e7, 0x0039, 0x00e0, 0x0030,
879 0x0029, 0x00b0, 0x003d, 0x002b, 0x0000, 0x0000, 0x0061, 0x0041,
880 0x0061, 0x0041, 0x007a, 0x005a, 0x0065, 0x0045, 0x0072, 0x0052,
881 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
882 0x006f, 0x004f, 0x0070, 0x0050, 0xffff, 0xffff, 0x0024, 0x00a3,
883 0x0041, 0x0000, 0x0000, 0x0000, 0x0071, 0x0051, 0x0073, 0x0053,
884 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
885 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x006d, 0x004d,
886 0x00f9, 0x0025, 0x00b2, 0x007e, 0x0000, 0x0000, 0x002a, 0x00b5,
887 0x0077, 0x0057, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
888 0x0062, 0x0042, 0x006e, 0x004e, 0x002c, 0x003f, 0x003b, 0x002e,
889 0x003a, 0x002f, 0x0021, 0x00a7, 0xffff, 0xffff, 0xffff, 0xffff,
890 0xffff, 0xffff, 0xffff, 0xffff, 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, 0x003c, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
898 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
899 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
900 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
901 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
902 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
903 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
904 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff,
905 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
906};
907
908const MockLayoutData kLayoutRussian{&kLayoutRussian0, nullptr,
909 &kLayoutRussian2};
910const MockLayoutData kLayoutFrench{&kLayoutFrench0, nullptr, nullptr,
911 &kLayoutFrench3};
912
913}
TEST_F(FlutterDisplayLinkTest, ViewAddedToWindowFirst)
void StartEngine(FlEngine *engine=nullptr)
void(* FlutterKeyEventCallback)(bool, void *)
g_autoptr(FlEngine) engine
FlEngine * fl_engine_new_with_binary_messenger(FlBinaryMessenger *binary_messenger)
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
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
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_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
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