10 #include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
11 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
14 #include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
15 #include "flutter/shell/platform/linux/testing/mock_keymap.h"
17 #include "gtest/gtest.h"
19 #define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR) \
20 EXPECT_EQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
22 kFlutterKeyEventTypeDown); \
23 EXPECT_EQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
26 EXPECT_STREQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
29 EXPECT_EQ(static_cast<CallRecord*>(g_ptr_array_index(call_records, 0)) \
30 ->event_synthesized, \
32 g_ptr_array_set_size(call_records, 0)
45 FlutterKeyEventCallback callback,
46 void* callback_user_data) {
70 using ::flutter::testing::keycodes::kLogicalAltLeft;
71 using ::flutter::testing::keycodes::kLogicalBracketLeft;
72 using ::flutter::testing::keycodes::kLogicalComma;
73 using ::flutter::testing::keycodes::kLogicalControlLeft;
74 using ::flutter::testing::keycodes::kLogicalDigit1;
75 using ::flutter::testing::keycodes::kLogicalKeyA;
76 using ::flutter::testing::keycodes::kLogicalKeyB;
77 using ::flutter::testing::keycodes::kLogicalKeyM;
78 using ::flutter::testing::keycodes::kLogicalKeyQ;
79 using ::flutter::testing::keycodes::kLogicalMetaLeft;
80 using ::flutter::testing::keycodes::kLogicalMinus;
81 using ::flutter::testing::keycodes::kLogicalParenthesisRight;
82 using ::flutter::testing::keycodes::kLogicalSemicolon;
83 using ::flutter::testing::keycodes::kLogicalShiftLeft;
84 using ::flutter::testing::keycodes::kLogicalUnderscore;
86 using ::flutter::testing::keycodes::kPhysicalAltLeft;
87 using ::flutter::testing::keycodes::kPhysicalControlLeft;
88 using ::flutter::testing::keycodes::kPhysicalKeyA;
89 using ::flutter::testing::keycodes::kPhysicalKeyB;
90 using ::flutter::testing::keycodes::kPhysicalMetaLeft;
91 using ::flutter::testing::keycodes::kPhysicalShiftLeft;
94 constexpr guint16 kKeyCodeKeyM = 0x3au;
95 constexpr guint16 kKeyCodeDigit1 = 0x0au;
96 constexpr guint16 kKeyCodeMinus = 0x14u;
97 constexpr guint16 kKeyCodeSemicolon = 0x2fu;
98 constexpr guint16 kKeyCodeKeyLeftBracket = 0x22u;
105 typedef std::array<uint32_t, 256> MockGroupLayoutData;
106 typedef std::vector<const MockGroupLayoutData*> MockLayoutData;
108 extern const MockLayoutData kLayoutRussian;
109 extern const MockLayoutData kLayoutFrench;
111 TEST(FlKeyboardManagerTest, EngineNoResponseChannelHandled) {
112 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
114 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
116 fl_mock_binary_messenger_set_json_message_channel(
117 messenger,
"flutter/keyevent",
118 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
127 g_autoptr(FlEngine) engine =
135 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
136 FlutterKeyEventCallback callback,
140 gboolean first_event_completed = FALSE;
142 manager, event1,
nullptr,
143 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
144 gboolean* first_event_completed =
static_cast<gboolean*
>(
user_data);
145 *first_event_completed =
TRUE;
147 &first_event_completed);
151 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
152 FlutterKeyEventCallback callback,
void*
user_data) {
157 0, FALSE,
kKeyCodeKeyA, GDK_KEY_a,
static_cast<GdkModifierType
>(0), 0);
158 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
160 manager, event2,
nullptr,
161 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
162 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
164 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
165 EXPECT_EQ(redispatched_event,
nullptr);
166 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
169 g_main_loop_run(loop);
171 EXPECT_FALSE(first_event_completed);
176 TEST(FlKeyboardManagerTest, EngineHandledChannelNotHandledSync) {
177 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
179 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
181 g_autoptr(FlEngine) engine =
188 fl_mock_binary_messenger_set_json_message_channel(
189 messenger,
"flutter/keyevent",
190 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
199 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
200 FlutterKeyEventCallback callback,
void*
user_data) {
207 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
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));
218 g_main_loop_run(loop);
221 TEST(FlKeyboardManagerTest, EngineNotHandledChannelHandledSync) {
222 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
224 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
226 g_autoptr(FlEngine) engine =
233 fl_mock_binary_messenger_set_json_message_channel(
234 messenger,
"flutter/keyevent",
235 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
244 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
245 FlutterKeyEventCallback callback,
void*
user_data) {
252 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
254 manager, event,
nullptr,
255 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
256 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
258 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
259 EXPECT_EQ(redispatched_event,
nullptr);
260 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
263 g_main_loop_run(loop);
266 TEST(FlKeyboardManagerTest, EngineHandledChannelHandledSync) {
267 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
269 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
271 g_autoptr(FlEngine) engine =
278 fl_mock_binary_messenger_set_json_message_channel(
279 messenger,
"flutter/keyevent",
280 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
289 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
290 FlutterKeyEventCallback callback,
void*
user_data) {
297 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
299 manager, event,
nullptr,
300 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
301 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
303 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
304 EXPECT_EQ(redispatched_event,
nullptr);
305 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
308 g_main_loop_run(loop);
311 TEST(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledSync) {
312 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
314 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
316 g_autoptr(FlEngine) engine =
323 fl_mock_binary_messenger_set_json_message_channel(
324 messenger,
"flutter/keyevent",
325 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
334 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
335 FlutterKeyEventCallback callback,
void*
user_data) {
342 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
344 manager, event,
nullptr,
345 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
346 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
348 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
349 EXPECT_NE(redispatched_event,
nullptr);
350 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
353 g_main_loop_run(loop);
356 static void channel_respond(FlMockBinaryMessenger* messenger,
361 fl_mock_binary_messenger_json_message_channel_respond(messenger, task,
value);
364 TEST(FlKeyboardManagerTest, EngineHandledChannelNotHandledAsync) {
365 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
367 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
369 g_autoptr(FlEngine) engine =
376 g_autoptr(GPtrArray) channel_calls =
377 g_ptr_array_new_with_free_func(g_object_unref);
378 fl_mock_binary_messenger_set_json_message_channel(
379 messenger,
"flutter/keyevent",
380 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
382 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
383 g_ptr_array_add(channel_calls, g_object_ref(task));
385 return static_cast<FlValue*
>(
nullptr);
388 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
391 SendKeyEvent, ([&embedder_call_records](
392 auto engine,
const FlutterKeyEvent* event,
393 FlutterKeyEventCallback callback,
void*
user_data) {
394 g_ptr_array_add(embedder_call_records,
401 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
403 manager, event,
nullptr,
404 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
405 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
407 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
408 EXPECT_EQ(redispatched_event,
nullptr);
409 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
413 EXPECT_EQ(embedder_call_records->len, 1u);
414 EXPECT_EQ(channel_calls->len, 1u);
417 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
419 channel_respond(messenger,
420 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
422 g_main_loop_run(loop);
425 TEST(FlKeyboardManagerTest, EngineNotHandledChannelHandledAsync) {
426 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
428 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
430 g_autoptr(FlEngine) engine =
437 g_autoptr(GPtrArray) channel_calls =
438 g_ptr_array_new_with_free_func(g_object_unref);
439 fl_mock_binary_messenger_set_json_message_channel(
440 messenger,
"flutter/keyevent",
441 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
443 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
444 g_ptr_array_add(channel_calls, g_object_ref(task));
446 return static_cast<FlValue*
>(
nullptr);
449 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
452 SendKeyEvent, ([&embedder_call_records](
453 auto engine,
const FlutterKeyEvent* event,
454 FlutterKeyEventCallback callback,
void*
user_data) {
455 g_ptr_array_add(embedder_call_records,
462 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
464 manager, event,
nullptr,
465 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
466 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
468 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
469 EXPECT_EQ(redispatched_event,
nullptr);
470 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
474 EXPECT_EQ(embedder_call_records->len, 1u);
475 EXPECT_EQ(channel_calls->len, 1u);
478 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
480 channel_respond(messenger,
481 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
483 g_main_loop_run(loop);
486 TEST(FlKeyboardManagerTest, EngineHandledChannelHandledAsync) {
487 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
489 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
491 g_autoptr(FlEngine) engine =
498 g_autoptr(GPtrArray) channel_calls =
499 g_ptr_array_new_with_free_func(g_object_unref);
500 fl_mock_binary_messenger_set_json_message_channel(
501 messenger,
"flutter/keyevent",
502 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
504 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
505 g_ptr_array_add(channel_calls, g_object_ref(task));
507 return static_cast<FlValue*
>(
nullptr);
510 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
513 SendKeyEvent, ([&embedder_call_records](
514 auto engine,
const FlutterKeyEvent* event,
515 FlutterKeyEventCallback callback,
void*
user_data) {
516 g_ptr_array_add(embedder_call_records,
523 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
525 manager, event,
nullptr,
526 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
527 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
529 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
530 EXPECT_EQ(redispatched_event,
nullptr);
531 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
535 EXPECT_EQ(embedder_call_records->len, 1u);
536 EXPECT_EQ(channel_calls->len, 1u);
539 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
541 channel_respond(messenger,
542 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
544 g_main_loop_run(loop);
547 TEST(FlKeyboardManagerTest, EngineNotHandledChannelNotHandledAsync) {
548 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
550 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
552 g_autoptr(FlEngine) engine =
559 g_autoptr(GPtrArray) channel_calls =
560 g_ptr_array_new_with_free_func(g_object_unref);
561 fl_mock_binary_messenger_set_json_message_channel(
562 messenger,
"flutter/keyevent",
563 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
565 GPtrArray* channel_calls =
static_cast<GPtrArray*
>(
user_data);
566 g_ptr_array_add(channel_calls, g_object_ref(task));
568 return static_cast<FlValue*
>(
nullptr);
571 g_autoptr(GPtrArray) embedder_call_records = g_ptr_array_new_with_free_func(
574 SendKeyEvent, ([&embedder_call_records](
575 auto engine,
const FlutterKeyEvent* event,
576 FlutterKeyEventCallback callback,
void*
user_data) {
577 g_ptr_array_add(embedder_call_records,
584 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
586 manager, event,
nullptr,
587 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
588 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
590 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
591 EXPECT_NE(redispatched_event,
nullptr);
592 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
596 EXPECT_EQ(embedder_call_records->len, 1u);
597 EXPECT_EQ(channel_calls->len, 1u);
600 static_cast<CallRecord*
>(g_ptr_array_index(embedder_call_records, 0)),
602 channel_respond(messenger,
603 static_cast<GTask*
>(g_ptr_array_index(channel_calls, 0)),
605 g_main_loop_run(loop);
608 TEST(FlKeyboardManagerTest, CorrectLogicalKeyForLayouts) {
609 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
617 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
621 ([&call_records](
auto engine,
const FlutterKeyEvent* event,
622 FlutterKeyEventCallback callback,
void*
user_data) {
623 g_ptr_array_add(call_records,
628 auto sendTap = [&](guint8 keycode, guint keyval, guint8 group) {
630 0,
TRUE, keycode, keyval,
static_cast<GdkModifierType
>(0), group);
634 0, FALSE, keycode, keyval,
static_cast<GdkModifierType
>(0), group);
647 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
650 sendTap(kKeyCodeDigit1, GDK_KEY_exclam, 0);
653 sendTap(kKeyCodeMinus, GDK_KEY_minus, 0);
656 sendTap(kKeyCodeMinus, GDK_KEY_underscore, 0);
664 [](
const GdkKeymapKey* key, gpointer
user_data) {
665 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
666 guint8 group =
static_cast<guint8
>(key->group);
667 EXPECT_LT(group, layout_data->size());
668 const MockGroupLayoutData* group_layout = (*layout_data)[group];
669 EXPECT_NE(group_layout,
nullptr);
670 EXPECT_TRUE(key->level == 0 || key->level == 1);
671 bool shift = key->level == 1;
672 return (*group_layout)[key->keycode * 2 + shift];
674 reinterpret_cast<gpointer
>(
const_cast<MockLayoutData*
>(&kLayoutFrench)));
682 sendTap(kKeyCodeSemicolon, GDK_KEY_m, 3);
685 sendTap(kKeyCodeKeyM, GDK_KEY_comma, 3);
688 sendTap(kKeyCodeDigit1, GDK_KEY_ampersand, 3);
691 sendTap(kKeyCodeDigit1, GDK_KEY_1, 3);
694 sendTap(kKeyCodeMinus, GDK_KEY_parenright, 3);
697 sendTap(kKeyCodeMinus, GDK_KEY_degree, 3);
706 sendTap(kKeyCodeDigit1, GDK_KEY_1, 0);
712 [](
const GdkKeymapKey* key, gpointer
user_data) {
713 MockLayoutData* layout_data =
static_cast<MockLayoutData*
>(
user_data);
714 guint8 group =
static_cast<guint8
>(key->group);
715 EXPECT_LT(group, layout_data->size());
716 const MockGroupLayoutData* group_layout = (*layout_data)[group];
717 EXPECT_NE(group_layout,
nullptr);
718 EXPECT_TRUE(key->level == 0 || key->level == 1);
719 bool shift = key->level == 1;
720 return (*group_layout)[key->keycode * 2 + shift];
722 reinterpret_cast<gpointer
>(
const_cast<MockLayoutData*
>(&kLayoutRussian)));
727 sendTap(kKeyCodeDigit1, GDK_KEY_1, 2);
730 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_Cyrillic_ha, 2);
737 sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_bracketleft, 0);
741 TEST(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
742 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
750 g_autoptr(GPtrArray) call_records = g_ptr_array_new_with_free_func(
754 ([&call_records](
auto engine,
const FlutterKeyEvent* event,
755 FlutterKeyEventCallback callback,
void*
user_data) {
756 g_ptr_array_add(call_records,
761 auto verifyModifierIsSynthesized = [&](GdkModifierType mask,
762 uint64_t physical, uint64_t logical) {
766 EXPECT_EQ(call_records->len, 1u);
768 static_cast<CallRecord*
>(g_ptr_array_index(call_records, 0));
769 EXPECT_EQ(record->
event_type, kFlutterKeyEventTypeDown);
777 EXPECT_EQ(call_records->len, 2u);
778 record =
static_cast<CallRecord*
>(g_ptr_array_index(call_records, 1));
779 EXPECT_EQ(record->
event_type, kFlutterKeyEventTypeUp);
784 g_ptr_array_set_size(call_records, 0);
790 EXPECT_EQ(call_records->len, 0u);
791 g_ptr_array_set_size(call_records, 0);
794 verifyModifierIsSynthesized(GDK_CONTROL_MASK, kPhysicalControlLeft,
795 kLogicalControlLeft);
796 verifyModifierIsSynthesized(GDK_META_MASK, kPhysicalMetaLeft,
798 verifyModifierIsSynthesized(GDK_MOD1_MASK, kPhysicalAltLeft, kLogicalAltLeft);
799 verifyModifierIsSynthesized(GDK_SHIFT_MASK, kPhysicalShiftLeft,
803 TEST(FlKeyboardManagerTest, GetPressedState) {
804 ::testing::NiceMock<flutter::testing::MockKeymap> mock_keymap;
806 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
807 g_autoptr(FlEngine) engine =
814 fl_mock_binary_messenger_set_json_message_channel(
815 messenger,
"flutter/keyevent",
816 [](FlMockBinaryMessenger* messenger, GTask* task,
FlValue* message,
824 SendKeyEvent, ([](
auto engine,
const FlutterKeyEvent* event,
825 FlutterKeyEventCallback callback,
void*
user_data) {
831 g_autoptr(GMainLoop) loop = g_main_loop_new(
nullptr, 0);
833 manager, event,
nullptr,
834 [](GObject*
object, GAsyncResult* result, gpointer
user_data) {
835 g_autoptr(FlKeyEvent) redispatched_event =
nullptr;
837 FL_KEYBOARD_MANAGER(
object), result, &redispatched_event,
nullptr));
838 EXPECT_NE(redispatched_event,
nullptr);
839 g_main_loop_quit(
static_cast<GMainLoop*
>(
user_data));
842 g_main_loop_run(loop);
845 EXPECT_EQ(g_hash_table_size(pressed_state), 1u);
847 gpointer physical_key =
854 const MockGroupLayoutData kLayoutRussian0{
856 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
857 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
858 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
859 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
860 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
861 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
862 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
863 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
864 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
865 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
866 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
867 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
868 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
869 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
870 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
871 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
872 0xffff, 0xffff, 0x0020, 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, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
879 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
880 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
881 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 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 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
886 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
887 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
890 const MockGroupLayoutData kLayoutRussian2{{
892 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
893 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
894 0xffff, 0x0031, 0x0021, 0x0000, 0x0031, 0x0021, 0x0032, 0x0022,
895 0x0033, 0x06b0, 0x0034, 0x003b, 0x0035, 0x0025, 0x0036, 0x003a,
896 0x0037, 0x003f, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
897 0x002d, 0x005f, 0x003d, 0x002b, 0x0071, 0x0051, 0x0000, 0x0000,
898 0x06ca, 0x06ea, 0x06c3, 0x06e3, 0x06d5, 0x06f5, 0x06cb, 0x06eb,
899 0x06c5, 0x06e5, 0x06ce, 0x06ee, 0x06c7, 0x06e7, 0x06db, 0x06fb,
900 0x06dd, 0x06fd, 0x06da, 0x06fa, 0x06c8, 0x06e8, 0x06df, 0x06ff,
901 0x0061, 0x0041, 0x0041, 0x0000, 0x06c6, 0x06e6, 0x06d9, 0x06f9,
902 0x06d7, 0x06f7, 0x06c1, 0x06e1, 0x06d0, 0x06f0, 0x06d2, 0x06f2,
903 0x06cf, 0x06ef, 0x06cc, 0x06ec, 0x06c4, 0x06e4, 0x06d6, 0x06f6,
904 0x06dc, 0x06fc, 0x06a3, 0x06b3, 0x007c, 0x0000, 0x005c, 0x002f,
905 0x06d1, 0x06f1, 0x06de, 0x06fe, 0x06d3, 0x06f3, 0x06cd, 0x06ed,
906 0x06c9, 0x06e9, 0x06d4, 0x06f4, 0x06d8, 0x06f8, 0x06c2, 0x06e2,
907 0x06c0, 0x06e0, 0x002e, 0x002c, 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, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
915 0xffff, 0xffff, 0x003c, 0x003e, 0x002f, 0x007c, 0xffff, 0xffff,
916 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
917 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
918 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0x0000,
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, 0xffff,
922 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1,
923 0x00b1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
926 const MockGroupLayoutData kLayoutFrench0 = {
928 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
929 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
930 0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040,
931 0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e,
932 0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029,
933 0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff,
934 0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052,
935 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
936 0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d,
937 0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053,
938 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
939 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a,
940 0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c,
941 0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
942 0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c,
943 0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff,
944 0xffff, 0xffff, 0x0020, 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, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
951 0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
952 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
953 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 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 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
958 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
959 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff,
962 const MockGroupLayoutData kLayoutFrench3 = {
964 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
965 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
966 0x0000, 0xffff, 0x0000, 0x0000, 0x0026, 0x0031, 0x00e9, 0x0032,
967 0x0022, 0x0033, 0x0027, 0x0034, 0x0028, 0x0035, 0x002d, 0x0036,
968 0x00e8, 0x0037, 0x005f, 0x0038, 0x00e7, 0x0039, 0x00e0, 0x0030,
969 0x0029, 0x00b0, 0x003d, 0x002b, 0x0000, 0x0000, 0x0061, 0x0041,
970 0x0061, 0x0041, 0x007a, 0x005a, 0x0065, 0x0045, 0x0072, 0x0052,
971 0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049,
972 0x006f, 0x004f, 0x0070, 0x0050, 0xffff, 0xffff, 0x0024, 0x00a3,
973 0x0041, 0x0000, 0x0000, 0x0000, 0x0071, 0x0051, 0x0073, 0x0053,
974 0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048,
975 0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x006d, 0x004d,
976 0x00f9, 0x0025, 0x00b2, 0x007e, 0x0000, 0x0000, 0x002a, 0x00b5,
977 0x0077, 0x0057, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056,
978 0x0062, 0x0042, 0x006e, 0x004e, 0x002c, 0x003f, 0x003b, 0x002e,
979 0x003a, 0x002f, 0x0021, 0x00a7, 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, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
987 0xffff, 0x003c, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff,
988 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
989 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff,
990 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
991 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
992 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
993 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
994 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff,
995 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
998 const MockLayoutData kLayoutRussian{&kLayoutRussian0,
nullptr,
1000 const MockLayoutData kLayoutFrench{&kLayoutFrench0,
nullptr,
nullptr,