43 {
44using ::flutter::testing::keycodes::kLogicalAltLeft;
45using ::flutter::testing::keycodes::kLogicalBracketLeft;
46using ::flutter::testing::keycodes::kLogicalComma;
47using ::flutter::testing::keycodes::kLogicalControlLeft;
48using ::flutter::testing::keycodes::kLogicalDigit1;
49using ::flutter::testing::keycodes::kLogicalKeyA;
50using ::flutter::testing::keycodes::kLogicalKeyB;
51using ::flutter::testing::keycodes::kLogicalKeyM;
52using ::flutter::testing::keycodes::kLogicalKeyQ;
53using ::flutter::testing::keycodes::kLogicalMetaLeft;
54using ::flutter::testing::keycodes::kLogicalMinus;
55using ::flutter::testing::keycodes::kLogicalParenthesisRight;
56using ::flutter::testing::keycodes::kLogicalSemicolon;
57using ::flutter::testing::keycodes::kLogicalShiftLeft;
58using ::flutter::testing::keycodes::kLogicalUnderscore;
59
60using ::flutter::testing::keycodes::kPhysicalAltLeft;
61using ::flutter::testing::keycodes::kPhysicalControlLeft;
62using ::flutter::testing::keycodes::kPhysicalKeyA;
63using ::flutter::testing::keycodes::kPhysicalKeyB;
64using ::flutter::testing::keycodes::kPhysicalMetaLeft;
65using ::flutter::testing::keycodes::kPhysicalShiftLeft;
66
67
68typedef std::function<void(bool handled)> AsyncKeyCallback;
69typedef std::function<void(AsyncKeyCallback
callback)> ChannelCallHandler;
72 EmbedderCallHandler;
73typedef std::function<void(std::unique_ptr<FlKeyEvent>)> RedispatchHandler;
74
75
76
77
78
79typedef struct {
80 enum {
81 kKeyCallEmbedder,
82 kKeyCallChannel,
84
86 std::unique_ptr<FlutterKeyEvent>
event;
87 std::unique_ptr<char[]> event_character;
88} CallRecord;
89
90
91
92
93char* cloneString(
const char*
source) {
95 return nullptr;
96 }
97 size_t charLen = strlen(
source);
98 char*
target =
new char[charLen + 1];
101}
102
103constexpr guint16 kKeyCodeKeyA = 0x26u;
104constexpr guint16 kKeyCodeKeyB = 0x38u;
105constexpr guint16 kKeyCodeKeyM = 0x3au;
106constexpr guint16 kKeyCodeDigit1 = 0x0au;
107constexpr guint16 kKeyCodeMinus = 0x14u;
108constexpr guint16 kKeyCodeSemicolon = 0x2fu;
109constexpr guint16 kKeyCodeKeyLeftBracket = 0x22u;
110
111static constexpr char kKeyEventChannelName[] = "flutter/keyevent";
112static constexpr char kKeyboardChannelName[] = "flutter/keyboard";
114static constexpr uint64_t kMockPhysicalKey = 42;
115static constexpr uint64_t kMockLogicalKey = 42;
116
117
118
119
120
121
122typedef std::array<uint32_t, 256> MockGroupLayoutData;
123typedef std::vector<const MockGroupLayoutData*> MockLayoutData;
124
125extern const MockLayoutData kLayoutUs;
126extern const MockLayoutData kLayoutRussian;
127extern const MockLayoutData kLayoutFrench;
128
129G_BEGIN_DECLS
130
132 fl_mock_view_delegate,
134 MOCK_VIEW_DELEGATE,
135 GObject);
136
138 fl_mock_key_binary_messenger,
140 MOCK_KEY_BINARY_MESSENGER,
141 GObject)
142
143G_END_DECLS
144
147 g_autoptr(FlMethodResponse) response =
152 return true;
153 }
154 *result_listener << ::testing::PrintToString(response);
155 return false;
156}
157
158
159
160
161
162
163struct _FlMockKeyBinaryMessenger {
164 GObject parent_instance;
165};
166
167struct FlMockKeyBinaryMessengerPrivate {
169};
170
171static void fl_mock_key_binary_messenger_iface_init(
172 FlBinaryMessengerInterface* iface);
173
175 FlMockKeyBinaryMessenger,
176 fl_mock_key_binary_messenger,
177 G_TYPE_OBJECT,
178 G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
179 fl_mock_key_binary_messenger_iface_init);
180 G_ADD_PRIVATE(FlMockKeyBinaryMessenger))
181
183 static_cast<FlMockKeyBinaryMessengerPrivate*>( \
184 fl_mock_key_binary_messenger_get_instance_private( \
185 FL_MOCK_KEY_BINARY_MESSENGER(obj)))
186
187static void fl_mock_key_binary_messenger_init(FlMockKeyBinaryMessenger* self) {
188 FlMockKeyBinaryMessengerPrivate*
priv =
190 new (
priv) FlMockKeyBinaryMessengerPrivate();
191}
192
193static void fl_mock_key_binary_messenger_finalize(GObject* object) {
195 ->~FlMockKeyBinaryMessengerPrivate();
196}
197
198static void fl_mock_key_binary_messenger_class_init(
199 FlMockKeyBinaryMessengerClass* klass) {
200 G_OBJECT_CLASS(klass)->finalize = fl_mock_key_binary_messenger_finalize;
201}
202
203static void fl_mock_key_binary_messenger_send_on_channel(
204 FlBinaryMessenger* messenger,
205 const gchar* channel,
207 GCancellable* cancellable,
210 FlMockKeyBinaryMessenger* self = FL_MOCK_KEY_BINARY_MESSENGER(messenger);
211
213 EXPECT_STREQ(channel, kKeyEventChannelName);
216 g_autoptr(GTask) task =
222 g_autoptr(GError)
error =
nullptr;
225
226 g_task_return_pointer(
227 task, data, reinterpret_cast<GDestroyNotify>(g_bytes_unref));
228 });
229 }
230}
231
232static GBytes* fl_mock_key_binary_messenger_send_on_channel_finish(
233 FlBinaryMessenger* messenger,
236 return static_cast<GBytes*
>(g_task_propagate_pointer(G_TASK(
result),
error));
237}
238
240 FlBinaryMessenger* messenger,
241 const gchar* channel,
242 int64_t new_size) {
243
244}
245
247 FlBinaryMessenger* messenger,
248 const gchar* channel,
249 bool warns) {
250
251}
252
253static void fl_mock_key_binary_messenger_iface_init(
254 FlBinaryMessengerInterface* iface) {
255 iface->set_message_handler_on_channel =
256 [](FlBinaryMessenger* messenger, const gchar* channel,
258 GDestroyNotify destroy_notify) {
259 EXPECT_STREQ(channel, kKeyEventChannelName);
260
261
262 };
263 iface->send_response = [](FlBinaryMessenger* messenger,
264 FlBinaryMessengerResponseHandle* response_handle,
265 GBytes* response, GError**
error) -> gboolean {
266
267
268 g_return_val_if_reached(
TRUE);
270 };
271 iface->send_on_channel = fl_mock_key_binary_messenger_send_on_channel;
272 iface->send_on_channel_finish =
273 fl_mock_key_binary_messenger_send_on_channel_finish;
275 iface->set_warns_on_channel_overflow =
277}
278
279static FlMockKeyBinaryMessenger* fl_mock_key_binary_messenger_new() {
280 FlMockKeyBinaryMessenger* self = FL_MOCK_KEY_BINARY_MESSENGER(
281 g_object_new(fl_mock_key_binary_messenger_get_type(), NULL));
282
283
284 FL_IS_MOCK_KEY_BINARY_MESSENGER(self);
285
286 return self;
287}
288
289static void fl_mock_key_binary_messenger_set_callback_handler(
290 FlMockKeyBinaryMessenger* self,
291 ChannelCallHandler handler) {
293 std::move(handler);
294}
295
296
297
298struct _FlMockViewDelegate {
299 GObject parent_instance;
300};
301
302struct FlMockViewDelegatePrivate {
303 FlMockKeyBinaryMessenger* messenger;
304 EmbedderCallHandler embedder_handler;
305 bool text_filter_result;
306 RedispatchHandler redispatch_handler;
308 const MockLayoutData* layout_data;
309};
310
311static void fl_mock_view_keyboard_delegate_iface_init(
312 FlKeyboardViewDelegateInterface* iface);
313
315 FlMockViewDelegate,
316 fl_mock_view_delegate,
317 G_TYPE_OBJECT,
318 G_IMPLEMENT_INTERFACE(fl_keyboard_view_delegate_get_type(),
319 fl_mock_view_keyboard_delegate_iface_init);
320 G_ADD_PRIVATE(FlMockViewDelegate))
321
323 static_cast<FlMockViewDelegatePrivate*>( \
324 fl_mock_view_delegate_get_instance_private(FL_MOCK_VIEW_DELEGATE(obj)))
325
326static void fl_mock_view_delegate_init(FlMockViewDelegate* self) {
328 new (
priv) FlMockViewDelegatePrivate();
329}
330
331static void fl_mock_view_delegate_finalize(GObject* object) {
333}
334
335static void fl_mock_view_delegate_dispose(GObject* object) {
337
338 g_clear_object(&
priv->messenger);
339
340 G_OBJECT_CLASS(fl_mock_view_delegate_parent_class)->dispose(object);
341}
342
343static void fl_mock_view_delegate_class_init(FlMockViewDelegateClass* klass) {
344 G_OBJECT_CLASS(klass)->dispose = fl_mock_view_delegate_dispose;
345 G_OBJECT_CLASS(klass)->finalize = fl_mock_view_delegate_finalize;
346}
347
348static void fl_mock_view_keyboard_send_key_event(
349 FlKeyboardViewDelegate* view_delegate,
353 FlMockViewDelegatePrivate*
priv =
358 }
359 });
360}
361
362static gboolean fl_mock_view_keyboard_text_filter_key_press(
363 FlKeyboardViewDelegate* view_delegate,
365 FlMockViewDelegatePrivate*
priv =
367 return priv->text_filter_result;
368}
369
370static FlBinaryMessenger* fl_mock_view_keyboard_get_messenger(
371 FlKeyboardViewDelegate* view_delegate) {
372 FlMockViewDelegatePrivate*
priv =
374 return FL_BINARY_MESSENGER(
priv->messenger);
375}
376
377static void fl_mock_view_keyboard_redispatch_event(
378 FlKeyboardViewDelegate* view_delegate,
379 std::unique_ptr<FlKeyEvent>
event) {
380 FlMockViewDelegatePrivate*
priv =
382 if (
priv->redispatch_handler) {
383 priv->redispatch_handler(std::move(
event));
384 }
385}
386
387static void fl_mock_view_keyboard_subscribe_to_layout_change(
388 FlKeyboardViewDelegate* delegate,
391 priv->layout_notifier = std::move(notifier);
392}
393
394static guint fl_mock_view_keyboard_lookup_key(FlKeyboardViewDelegate* delegate,
395 const GdkKeymapKey*
key) {
397 guint8
group =
static_cast<guint8
>(
key->group);
398 EXPECT_LT(group,
priv->layout_data->size());
399 const MockGroupLayoutData* group_layout = (*
priv->layout_data)[group];
402 bool shift =
key->level == 1;
403 return (*group_layout)[
key->keycode * 2 + shift];
404}
405
406static GHashTable* fl_mock_view_keyboard_get_keyboard_state(
407 FlKeyboardViewDelegate* view_delegate) {
408 GHashTable*
result = g_hash_table_new(g_direct_hash, g_direct_equal);
409 g_hash_table_insert(
result,
reinterpret_cast<gpointer
>(kMockPhysicalKey),
410 reinterpret_cast<gpointer>(kMockLogicalKey));
411
413}
414
415static void fl_mock_view_keyboard_delegate_iface_init(
416 FlKeyboardViewDelegateInterface* iface) {
417 iface->send_key_event = fl_mock_view_keyboard_send_key_event;
418 iface->text_filter_key_press = fl_mock_view_keyboard_text_filter_key_press;
419 iface->get_messenger = fl_mock_view_keyboard_get_messenger;
420 iface->redispatch_event = fl_mock_view_keyboard_redispatch_event;
421 iface->subscribe_to_layout_change =
422 fl_mock_view_keyboard_subscribe_to_layout_change;
423 iface->lookup_key = fl_mock_view_keyboard_lookup_key;
424 iface->get_keyboard_state = fl_mock_view_keyboard_get_keyboard_state;
425}
426
427static FlMockViewDelegate* fl_mock_view_delegate_new() {
428 FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(
429 g_object_new(fl_mock_view_delegate_get_type(), nullptr));
430
431
432 FL_IS_MOCK_VIEW_DELEGATE(self);
433
435 priv->messenger = fl_mock_key_binary_messenger_new();
436
437 return self;
438}
439
440static void fl_mock_view_set_embedder_handler(FlMockViewDelegate* self,
441 EmbedderCallHandler handler) {
443 priv->embedder_handler = std::move(handler);
444}
445
446static void fl_mock_view_set_text_filter_result(FlMockViewDelegate* self,
450}
451
452static void fl_mock_view_set_redispatch_handler(FlMockViewDelegate* self,
453 RedispatchHandler handler) {
455 priv->redispatch_handler = std::move(handler);
456}
457
458static void fl_mock_view_set_layout(FlMockViewDelegate* self,
459 const MockLayoutData* layout) {
461 priv->layout_data = layout;
462 if (
priv->layout_notifier !=
nullptr) {
463 priv->layout_notifier();
464 }
465}
466
467
468
469
471 guint keyval,
472 guint16 keycode,
473 GdkModifierType
state,
474 gboolean is_modifier,
475 guint8 group = 0) {
477 event->is_press = is_press;
478 event->time = 0;
479 event->state =
state;
480 event->keyval = keyval;
481 event->group =
group;
482 event->keycode = keycode;
484}
485
487 public:
489 ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
490
491 view_ = fl_mock_view_delegate_new();
492 respondToEmbedderCallsWith(false);
493 respondToChannelCallsWith(false);
494 respondToTextInputWith(false);
495 setLayout(kLayoutUs);
496
497 manager_ =
499 }
500
502 g_clear_object(&view_);
503 g_clear_object(&manager_);
504 }
505
507
508
509
510 void flushChannelMessages() {
511 GMainLoop* loop = g_main_loop_new(nullptr, 0);
512 g_idle_add(_flushChannelMessagesCb, loop);
513 g_main_loop_run(loop);
514 }
515
516
517
518
519
520
521
522 int redispatchEventsAndClear(
523 std::vector<std::unique_ptr<FlKeyEvent>>& events) {
524 size_t event_count = events.size();
525 int first_error = -1;
526 during_redispatch_ = true;
527 for (size_t event_id = 0; event_id < event_count; event_id += 1) {
529 manager_, events[event_id].release());
530 EXPECT_FALSE(handled);
531 if (handled) {
532 first_error = first_error == -1 ? event_id : first_error;
533 }
534 }
535 during_redispatch_ = false;
536 events.clear();
537 return first_error < 0 ? event_count : -first_error;
538 }
539
540 void respondToEmbedderCallsWith(bool response) {
541 fl_mock_view_set_embedder_handler(
544 EXPECT_FALSE(during_redispatch_);
546 });
547 }
548
549 void recordEmbedderCallsTo(std::vector<CallRecord>& storage) {
550 fl_mock_view_set_embedder_handler(
553 EXPECT_FALSE(during_redispatch_);
554 auto new_event = std::make_unique<FlutterKeyEvent>(*
event);
555 char* new_event_character = cloneString(
event->character);
556 new_event->character = new_event_character;
557 storage.push_back(CallRecord{
558 .type = CallRecord::kKeyCallEmbedder,
560 .event = std::move(new_event),
561 .event_character = std::unique_ptr<char[]>(new_event_character),
562 });
563 });
564 }
565
566 void respondToEmbedderCallsWithAndRecordsTo(
567 bool response,
568 std::vector<CallRecord>& storage) {
569 fl_mock_view_set_embedder_handler(
572 EXPECT_FALSE(during_redispatch_);
573 auto new_event = std::make_unique<FlutterKeyEvent>(*
event);
574 char* new_event_character = cloneString(
event->character);
575 new_event->character = new_event_character;
576 storage.push_back(CallRecord{
577 .type = CallRecord::kKeyCallEmbedder,
578 .event = std::move(new_event),
579 .event_character = std::unique_ptr<char[]>(new_event_character),
580 });
582 });
583 }
584
585 void respondToChannelCallsWith(bool response) {
587
588 fl_mock_key_binary_messenger_set_callback_handler(
589 priv->messenger, [response,
this](
const AsyncKeyCallback&
callback) {
590 EXPECT_FALSE(during_redispatch_);
591 callback(response);
592 });
593 }
594
595 void recordChannelCallsTo(std::vector<CallRecord>& storage) {
597
598 fl_mock_key_binary_messenger_set_callback_handler(
599 priv->messenger, [&storage,
this](AsyncKeyCallback
callback) {
600 EXPECT_FALSE(during_redispatch_);
601 storage.push_back(CallRecord{
602 .type = CallRecord::kKeyCallChannel,
603 .callback = std::move(callback),
604 });
605 });
606 }
607
608 void respondToTextInputWith(bool response) {
609 fl_mock_view_set_text_filter_result(view_, response);
610 }
611
612 void recordRedispatchedEventsTo(
613 std::vector<std::unique_ptr<FlKeyEvent>>& storage) {
614 fl_mock_view_set_redispatch_handler(
615 view_, [&storage](std::unique_ptr<FlKeyEvent>
key) {
616 storage.push_back(std::move(
key));
617 });
618 }
619
620 void setLayout(const MockLayoutData& layout) {
621 fl_mock_view_set_layout(view_, &layout);
622 }
623
624 private:
625 FlMockViewDelegate* view_;
627 bool during_redispatch_ = false;
628
629 static gboolean _flushChannelMessagesCb(gpointer data) {
630 g_autoptr(GMainLoop) loop =
reinterpret_cast<GMainLoop*
>(
data);
631 g_main_loop_quit(loop);
633 }
634};
635
636
637
638TEST(FlKeyboardManagerTest, DisposeWithUnresolvedPends) {
640 std::vector<CallRecord> call_records;
641
642
643 tester.recordEmbedderCallsTo(call_records);
647 static_cast<GdkModifierType>(0), false));
648
649 tester.respondToEmbedderCallsWith(
true);
653 static_cast<GdkModifierType>(0), false));
654
655 tester.flushChannelMessages();
656
657
658}
659
660TEST(FlKeyboardManagerTest, SingleDelegateWithAsyncResponds) {
662 std::vector<CallRecord> call_records;
663 std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
664
665 gboolean manager_handled = false;
666
667
668 tester.recordEmbedderCallsTo(call_records);
669 tester.recordRedispatchedEventsTo(redispatched);
670
671
675 static_cast<GdkModifierType>(0), false));
676 tester.flushChannelMessages();
677 EXPECT_EQ(manager_handled, true);
678 EXPECT_EQ(redispatched.size(), 0u);
679 EXPECT_EQ(call_records.size(), 1u);
681 kLogicalKeyA, "a", false);
682
683 call_records[0].callback(true);
684 tester.flushChannelMessages();
685 EXPECT_EQ(redispatched.size(), 0u);
687 call_records.clear();
688
689
693 static_cast<GdkModifierType>(0), false));
694 tester.flushChannelMessages();
695 EXPECT_EQ(manager_handled, true);
696 EXPECT_EQ(redispatched.size(), 0u);
697 EXPECT_EQ(call_records.size(), 1u);
699 kLogicalKeyA, nullptr, false);
700
701
705 static_cast<GdkModifierType>(0), false));
706 tester.flushChannelMessages();
707 EXPECT_EQ(manager_handled, true);
708 EXPECT_EQ(redispatched.size(), 0u);
709 EXPECT_EQ(call_records.size(), 2u);
711 kLogicalKeyB, "b", false);
712
713
714 call_records[1].callback(false);
715 EXPECT_EQ(redispatched.size(), 1u);
716 EXPECT_EQ(redispatched[0]->keyval, 0x62u);
717 call_records[0].callback(false);
718 tester.flushChannelMessages();
719 EXPECT_EQ(redispatched.size(), 2u);
720 EXPECT_EQ(redispatched[1]->keyval, 0x61u);
721
723 call_records.clear();
724
725
726 EXPECT_EQ(
tester.redispatchEventsAndClear(redispatched), 2);
727 tester.flushChannelMessages();
728 EXPECT_EQ(call_records.size(), 0u);
730
731
732
736 static_cast<GdkModifierType>(0), false));
737 tester.flushChannelMessages();
738 EXPECT_EQ(manager_handled, true);
739 EXPECT_EQ(redispatched.size(), 0u);
740 EXPECT_EQ(call_records.size(), 1u);
741
742 call_records[0].callback(true);
744}
745
746TEST(FlKeyboardManagerTest, SingleDelegateWithSyncResponds) {
748 gboolean manager_handled = false;
749 std::vector<CallRecord> call_records;
750 std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
751
752
753 tester.respondToEmbedderCallsWithAndRecordsTo(
true, call_records);
754 tester.recordRedispatchedEventsTo(redispatched);
755
756
760 static_cast<GdkModifierType>(0), false));
761 tester.flushChannelMessages();
762 EXPECT_EQ(manager_handled, true);
763 EXPECT_EQ(call_records.size(), 1u);
765 kLogicalKeyA, "a", false);
766 EXPECT_EQ(redispatched.size(), 0u);
767 call_records.clear();
768
770 redispatched.clear();
771
772
773 tester.respondToEmbedderCallsWithAndRecordsTo(
false, call_records);
777 static_cast<GdkModifierType>(0), false));
778 tester.flushChannelMessages();
779 EXPECT_EQ(manager_handled, true);
780 EXPECT_EQ(call_records.size(), 1u);
782 kLogicalKeyA, nullptr, false);
783 EXPECT_EQ(redispatched.size(), 1u);
784 call_records.clear();
785
787
788 EXPECT_EQ(
tester.redispatchEventsAndClear(redispatched), 1);
789 EXPECT_EQ(call_records.size(), 0u);
790
792}
793
794TEST(FlKeyboardManagerTest, WithTwoAsyncDelegates) {
796 std::vector<CallRecord> call_records;
797 std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
798
799 gboolean manager_handled = false;
800
801 tester.recordEmbedderCallsTo(call_records);
802 tester.recordChannelCallsTo(call_records);
803 tester.recordRedispatchedEventsTo(redispatched);
804
805
806
810 static_cast<GdkModifierType>(0), false));
811
812 EXPECT_EQ(manager_handled, true);
813 EXPECT_EQ(redispatched.size(), 0u);
814 EXPECT_EQ(call_records.size(), 2u);
815
816 EXPECT_EQ(call_records[0].
type, CallRecord::kKeyCallEmbedder);
817 EXPECT_EQ(call_records[1].
type, CallRecord::kKeyCallChannel);
818
819 call_records[0].callback(true);
820 call_records[1].callback(false);
821 tester.flushChannelMessages();
822 EXPECT_EQ(redispatched.size(), 0u);
823
825 call_records.clear();
826
827
831 static_cast<GdkModifierType>(0), false));
832
833 EXPECT_EQ(manager_handled, true);
834 EXPECT_EQ(redispatched.size(), 0u);
835 EXPECT_EQ(call_records.size(), 2u);
836
837 EXPECT_EQ(call_records[0].
type, CallRecord::kKeyCallEmbedder);
838 EXPECT_EQ(call_records[1].
type, CallRecord::kKeyCallChannel);
839
840 call_records[0].callback(false);
841 call_records[1].callback(false);
842
843 call_records.clear();
844
845
846 tester.flushChannelMessages();
847 EXPECT_EQ(redispatched.size(), 1u);
848 EXPECT_EQ(
tester.redispatchEventsAndClear(redispatched), 1);
849 EXPECT_EQ(call_records.size(), 0u);
850
852}
853
854TEST(FlKeyboardManagerTest, TextInputPluginReturnsFalse) {
856 std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
857 gboolean manager_handled = false;
858 tester.recordRedispatchedEventsTo(redispatched);
859 tester.respondToTextInputWith(
false);
860
861
865 static_cast<GdkModifierType>(0), false));
866 tester.flushChannelMessages();
867 EXPECT_EQ(manager_handled, true);
868
869 EXPECT_EQ(redispatched.size(), 1u);
870
871
872 EXPECT_EQ(
tester.redispatchEventsAndClear(redispatched), 1);
873
875}
876
877TEST(FlKeyboardManagerTest, TextInputPluginReturnsTrue) {
879 std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
880 gboolean manager_handled = false;
881 tester.recordRedispatchedEventsTo(redispatched);
882 tester.respondToTextInputWith(
true);
883
884
888 static_cast<GdkModifierType>(0), false));
889 tester.flushChannelMessages();
890 EXPECT_EQ(manager_handled, true);
891
892 EXPECT_EQ(redispatched.size(), 0u);
893
895}
896
897TEST(FlKeyboardManagerTest, CorrectLogicalKeyForLayouts) {
899
900 std::vector<CallRecord> call_records;
901 tester.recordEmbedderCallsTo(call_records);
902
903 auto sendTap = [&](guint8 keycode, guint keyval, guint8
group) {
906 true, keyval, keycode,
907 static_cast<GdkModifierType>(0), false, group));
910 false, keyval, keycode,
911 static_cast<GdkModifierType>(0), false, group));
912 };
913
914
915
916 sendTap(kKeyCodeKeyA, GDK_KEY_a, 0);
918
919 sendTap(kKeyCodeKeyA, GDK_KEY_A, 0);
921
922 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
924
925 sendTap(kKeyCodeDigit1, GDK_KEY_exclam, 0);
927
928 sendTap(kKeyCodeMinus, GDK_KEY_minus, 0);
930
931 sendTap(kKeyCodeMinus, GDK_KEY_underscore, 0);
933
934
935
936
937 tester.setLayout(kLayoutFrench);
938
939 sendTap(kKeyCodeKeyA, GDK_KEY_q, 3);
941
942 sendTap(kKeyCodeKeyA, GDK_KEY_Q, 3);
944
945 sendTap(kKeyCodeSemicolon, GDK_KEY_m, 3);
947
948 sendTap(kKeyCodeKeyM, GDK_KEY_comma, 3);
950
951 sendTap(kKeyCodeDigit1, GDK_KEY_ampersand, 3);
953
954 sendTap(kKeyCodeDigit1, GDK_KEY_1, 3);
956
957 sendTap(kKeyCodeMinus, GDK_KEY_parenright, 3);
959
960 sendTap(kKeyCodeMinus, GDK_KEY_degree, 3);
962
963
964
965
966 sendTap(kKeyCodeKeyA, GDK_KEY_a, 0);
968
969 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
971
972
973 tester.setLayout(kLayoutRussian);
974
975 sendTap(kKeyCodeKeyA, GDK_KEY_Cyrillic_ef, 2);
977
978 sendTap(kKeyCodeDigit1, GDK_KEY_1, 2);
980
981 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_Cyrillic_ha, 2);
983
984
985 sendTap(kKeyCodeKeyA, GDK_KEY_a, 0);
987
988 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_bracketleft, 0);
990}
991
992TEST(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
994 std::vector<CallRecord> call_records;
995 tester.recordEmbedderCallsTo(call_records);
996
997 auto verifyModifierIsSynthesized = [&](GdkModifierType mask,
998 uint64_t physical, uint64_t logical) {
999
1002 EXPECT_EQ(call_records.size(), 1u);
1004 logical, NULL, true);
1005
1008 EXPECT_EQ(call_records.size(), 2u);
1010 NULL, true);
1011 call_records.clear();
1012 };
1013
1014
1017 EXPECT_EQ(call_records.size(), 0u);
1018 call_records.clear();
1019
1020
1021 verifyModifierIsSynthesized(GDK_CONTROL_MASK, kPhysicalControlLeft,
1022 kLogicalControlLeft);
1023 verifyModifierIsSynthesized(GDK_META_MASK, kPhysicalMetaLeft,
1024 kLogicalMetaLeft);
1025 verifyModifierIsSynthesized(GDK_MOD1_MASK, kPhysicalAltLeft, kLogicalAltLeft);
1026 verifyModifierIsSynthesized(GDK_SHIFT_MASK, kPhysicalShiftLeft,
1027 kLogicalShiftLeft);
1028}
1029
1030TEST(FlKeyboardManagerTest, GetPressedState) {
1032 tester.respondToTextInputWith(
true);
1033
1034
1038 static_cast<GdkModifierType>(0), false));
1039
1040 GHashTable* pressedState =
1042 EXPECT_EQ(g_hash_table_size(pressedState), 1u);
1043
1044 gpointer physical_key =
1047}
1048
1049TEST(FlKeyboardPluginTest, KeyboardChannelGetPressedState) {
1050 ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
1051
1053 messenger, FL_KEYBOARD_VIEW_DELEGATE(fl_mock_view_delegate_new()));
1054 EXPECT_NE(manager, nullptr);
1055
1059
1063 EXPECT_CALL(messenger,
1065 ::testing::Eq<FlBinaryMessenger*>(messenger), ::testing::_,
1066 MethodSuccessResponse(response), ::testing::_))
1067 .WillOnce(::testing::Return(true));
1068
1069 messenger.ReceiveMessage(kKeyboardChannelName,
message);
1070}
1071
1072
1073
1074const MockGroupLayoutData kLayoutUs0{{
1075
1076 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1077 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1078 0xffff, 0x0031, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
1079 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
1080 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
1081 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
1082 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
1083 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
1084 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
1085 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
1086 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
1087 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
1088 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
1089 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
1090 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
1091 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
1092 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1093 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1094 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1095 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1096 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1097 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1098 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1099 0xffff, 0xffff, 0x003c, 0x003e, 0x003c, 0x003e, 0xffff, 0xffff,
1100 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1101 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1102 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1103 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1104 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1105 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1106 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1107 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
1108}};
1109
1110const MockGroupLayoutData kLayoutRussian0{
1111
1112 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1113 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1114 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
1115 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
1116 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
1117 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
1118 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
1119 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
1120 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
1121 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
1122 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
1123 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
1124 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
1125 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
1126 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
1127 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
1128 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1129 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1130 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1131 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1132 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1133 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1134 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1135 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
1136 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1137 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
1138 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1139 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1140 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1141 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1142 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1143 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
1144};
1145
1146const MockGroupLayoutData kLayoutRussian2{{
1147
1148 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1149 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1150 0xffff, 0x0031, 0x0021, 0x0000, 0x0031, 0x0021, 0x0032, 0x0022,
1151 0x0033, 0x06b0, 0x0034, 0x003b, 0x0035, 0x0025, 0x0036, 0x003a,
1152 0x0037, 0x003f, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
1153 0x002d, 0x005f, 0x003d, 0x002b, 0x0071, 0x0051, 0x0000, 0x0000,
1154 0x06ca, 0x06ea, 0x06c3, 0x06e3, 0x06d5, 0x06f5, 0x06cb, 0x06eb,
1155 0x06c5, 0x06e5, 0x06ce, 0x06ee, 0x06c7, 0x06e7, 0x06db, 0x06fb,
1156 0x06dd, 0x06fd, 0x06da, 0x06fa, 0x06c8, 0x06e8, 0x06df, 0x06ff,
1157 0x0061, 0x0041, 0x0041, 0x0000, 0x06c6, 0x06e6, 0x06d9, 0x06f9,
1158 0x06d7, 0x06f7, 0x06c1, 0x06e1, 0x06d0, 0x06f0, 0x06d2, 0x06f2,
1159 0x06cf, 0x06ef, 0x06cc, 0x06ec, 0x06c4, 0x06e4, 0x06d6, 0x06f6,
1160 0x06dc, 0x06fc, 0x06a3, 0x06b3, 0x007c, 0x0000, 0x005c, 0x002f,
1161 0x06d1, 0x06f1, 0x06de, 0x06fe, 0x06d3, 0x06f3, 0x06cd, 0x06ed,
1162 0x06c9, 0x06e9, 0x06d4, 0x06f4, 0x06d8, 0x06f8, 0x06c2, 0x06e2,
1163 0x06c0, 0x06e0, 0x002e, 0x002c, 0xffff, 0xffff, 0xffff, 0xffff,
1164 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1165 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1166 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1167 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1168 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1169 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1170 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1171 0xffff, 0xffff, 0x003c, 0x003e, 0x002f, 0x007c, 0xffff, 0xffff,
1172 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1173 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1174 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0x0000,
1175 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1176 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1177 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1178 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1,
1179 0x00b1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1180}};
1181
1182const MockGroupLayoutData kLayoutFrench0 = {
1183
1184 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1185 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1186 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
1187 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
1188 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
1189 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
1190 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
1191 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
1192 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
1193 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
1194 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
1195 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
1196 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
1197 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
1198 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
1199 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
1200 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1201 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1202 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1203 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1204 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1205 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1206 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1207 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
1208 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1209 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
1210 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1211 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1212 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1213 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1214 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1215 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
1216};
1217
1218const MockGroupLayoutData kLayoutFrench3 = {
1219
1220 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1221 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
1222 0x0000, 0xffff, 0x0000, 0x0000, 0x0026, 0x0031, 0x00e9, 0x0032,
1223 0x0022, 0x0033, 0x0027, 0x0034, 0x0028, 0x0035, 0x002d, 0x0036,
1224 0x00e8, 0x0037, 0x005f, 0x0038, 0x00e7, 0x0039, 0x00e0, 0x0030,
1225 0x0029, 0x00b0, 0x003d, 0x002b, 0x0000, 0x0000, 0x0061, 0x0041,
1226 0x0061, 0x0041, 0x007a, 0x005a, 0x0065, 0x0045, 0x0072, 0x0052,
1227 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
1228 0x006f, 0x004f, 0x0070, 0x0050, 0xffff, 0xffff, 0x0024, 0x00a3,
1229 0x0041, 0x0000, 0x0000, 0x0000, 0x0071, 0x0051, 0x0073, 0x0053,
1230 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
1231 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x006d, 0x004d,
1232 0x00f9, 0x0025, 0x00b2, 0x007e, 0x0000, 0x0000, 0x002a, 0x00b5,
1233 0x0077, 0x0057, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
1234 0x0062, 0x0042, 0x006e, 0x004e, 0x002c, 0x003f, 0x003b, 0x002e,
1235 0x003a, 0x002f, 0x0021, 0x00a7, 0xffff, 0xffff, 0xffff, 0xffff,
1236 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1237 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1238 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1239 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1240 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1241 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1242 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1243 0xffff, 0x003c, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
1244 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1245 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
1246 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1247 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1248 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1249 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1250 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff,
1251 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
1252};
1253
1254const MockLayoutData kLayoutUs{&kLayoutUs0};
1255const MockLayoutData kLayoutRussian{&kLayoutRussian0, nullptr,
1256 &kLayoutRussian2};
1257const MockLayoutData kLayoutFrench{&kLayoutFrench0, nullptr, nullptr,
1258 &kLayoutFrench3};
1259
1260}
#define TEST(S, s, D, expected)
void(* FlutterKeyEventCallback)(bool, void *)
@ kFlutterKeyEventTypeDown
G_DEFINE_TYPE_WITH_CODE(FlAccessibleNode, fl_accessible_node, ATK_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT, fl_accessible_node_component_interface_init) G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION, fl_accessible_node_action_interface_init)) static gboolean flag_is_changed(FlutterSemanticsFlag old_flags
G_BEGIN_DECLS G_DECLARE_FINAL_TYPE(FlAccessibleTextField, fl_accessible_text_field, FL, ACCESSIBLE_TEXT_FIELD, FlAccessibleNode)
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(FlBinaryMessenger *self, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
G_MODULE_EXPORT GObject typedef void(* FlBinaryMessengerMessageHandler)(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
G_MODULE_EXPORT FlJsonMessageCodec * fl_json_message_codec_new()
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static FlKeyEvent * fl_key_event_new_by_mock(guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, GdkModifierType state, gboolean is_modifier)
typedefG_BEGIN_DECLS struct _FlKeyboardManager FlKeyboardManager
gboolean fl_keyboard_manager_is_state_clear(FlKeyboardManager *self)
gboolean fl_keyboard_manager_handle_event(FlKeyboardManager *self, FlKeyEvent *event)
GHashTable * fl_keyboard_manager_get_pressed_state(FlKeyboardManager *self)
static constexpr char kGetKeyboardStateMethod[]
FlKeyboardManager * fl_keyboard_manager_new(FlBinaryMessenger *messenger, FlKeyboardViewDelegate *view_delegate)
void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager *self, guint state, double event_time)
#define EXPECT_KEY_EVENT(RECORD, TYPE, PHYSICAL, LOGICAL, CHAR, SYNTHESIZED)
#define FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(obj)
#define FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(obj)
#define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR)
std::function< void()> KeyboardLayoutNotifier
G_MODULE_EXPORT GBytes * fl_message_codec_encode_message(FlMessageCodec *self, FlValue *message, GError **error)
FlMethodResponse * fl_method_codec_decode_response(FlMethodCodec *self, GBytes *message, GError **error)
GBytes * fl_method_codec_encode_method_call(FlMethodCodec *self, const gchar *name, FlValue *args, GError **error)
G_MODULE_EXPORT FlValue * fl_method_response_get_result(FlMethodResponse *self, GError **error)
FlPixelBufferTexturePrivate * priv
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
G_MODULE_EXPORT FlValue * fl_value_new_map()
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 void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
typedefG_BEGIN_DECLS struct _FlValue FlValue
FlutterKeyboardManager * manager
gpointer uint64_to_gpointer(uint64_t number)
uint64_t gpointer_to_uint64(gpointer pointer)
CallbackHandler callback_handler
static void fl_mock_binary_messenger_resize_channel(FlBinaryMessenger *messenger, const gchar *channel, int64_t new_size)
static void fl_mock_binary_messenger_set_warns_on_channel_overflow(FlBinaryMessenger *messenger, const gchar *channel, bool warns)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
#define EXPECT_TRUE(handle)