Flutter Linux Embedder
fl_keyboard_manager_test.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <cstring>
8 #include <vector>
9 
10 #include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
17 #include "flutter/shell/platform/linux/testing/fl_test.h"
18 #include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
19 #include "flutter/shell/platform/linux/testing/mock_text_input_plugin.h"
20 #include "flutter/testing/testing.h"
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 
25 // Define compound `expect` in macros. If they were defined in functions, the
26 // stacktrace wouldn't print where the function is called in the unit tests.
27 
28 #define EXPECT_KEY_EVENT(RECORD, TYPE, PHYSICAL, LOGICAL, CHAR, SYNTHESIZED) \
29  EXPECT_EQ((RECORD).type, CallRecord::kKeyCallEmbedder); \
30  EXPECT_EQ((RECORD).event->type, (TYPE)); \
31  EXPECT_EQ((RECORD).event->physical, (PHYSICAL)); \
32  EXPECT_EQ((RECORD).event->logical, (LOGICAL)); \
33  EXPECT_STREQ((RECORD).event->character, (CHAR)); \
34  EXPECT_EQ((RECORD).event->synthesized, (SYNTHESIZED));
35 
36 #define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR) \
37  EXPECT_EQ(call_records[0].type, CallRecord::kKeyCallEmbedder); \
38  EXPECT_EQ(call_records[0].event->type, kFlutterKeyEventTypeDown); \
39  EXPECT_EQ(call_records[0].event->logical, (OUT_LOGICAL)); \
40  EXPECT_STREQ(call_records[0].event->character, (OUT_CHAR)); \
41  EXPECT_EQ(call_records[0].event->synthesized, false); \
42  call_records.clear()
43 
44 namespace {
45 using ::flutter::testing::keycodes::kLogicalAltLeft;
46 using ::flutter::testing::keycodes::kLogicalBracketLeft;
47 using ::flutter::testing::keycodes::kLogicalComma;
48 using ::flutter::testing::keycodes::kLogicalControlLeft;
49 using ::flutter::testing::keycodes::kLogicalDigit1;
50 using ::flutter::testing::keycodes::kLogicalKeyA;
51 using ::flutter::testing::keycodes::kLogicalKeyB;
52 using ::flutter::testing::keycodes::kLogicalKeyM;
53 using ::flutter::testing::keycodes::kLogicalKeyQ;
54 using ::flutter::testing::keycodes::kLogicalMetaLeft;
55 using ::flutter::testing::keycodes::kLogicalMinus;
56 using ::flutter::testing::keycodes::kLogicalParenthesisRight;
57 using ::flutter::testing::keycodes::kLogicalSemicolon;
58 using ::flutter::testing::keycodes::kLogicalShiftLeft;
59 using ::flutter::testing::keycodes::kLogicalUnderscore;
60 
61 using ::flutter::testing::keycodes::kPhysicalAltLeft;
62 using ::flutter::testing::keycodes::kPhysicalControlLeft;
63 using ::flutter::testing::keycodes::kPhysicalKeyA;
64 using ::flutter::testing::keycodes::kPhysicalKeyB;
65 using ::flutter::testing::keycodes::kPhysicalMetaLeft;
66 using ::flutter::testing::keycodes::kPhysicalShiftLeft;
67 
68 // Hardware key codes.
69 typedef std::function<void(bool handled)> AsyncKeyCallback;
70 typedef std::function<void(AsyncKeyCallback callback)> ChannelCallHandler;
71 typedef std::function<void(const FlutterKeyEvent* event,
72  AsyncKeyCallback callback)>
73  EmbedderCallHandler;
74 typedef std::function<void(std::unique_ptr<FlKeyEvent>)> RedispatchHandler;
75 
76 // A type that can record all kinds of effects that the keyboard manager
77 // triggers.
78 //
79 // An instance of `CallRecord` might not have all the fields filled.
80 typedef struct {
81  enum {
82  kKeyCallEmbedder,
83  kKeyCallChannel,
84  } type;
85 
86  AsyncKeyCallback callback;
87  std::unique_ptr<FlutterKeyEvent> event;
88  std::unique_ptr<char[]> event_character;
89 } CallRecord;
90 
91 // Clone a C-string.
92 //
93 // Must be deleted by delete[].
94 char* cloneString(const char* source) {
95  if (source == nullptr) {
96  return nullptr;
97  }
98  size_t charLen = strlen(source);
99  char* target = new char[charLen + 1];
100  strncpy(target, source, charLen + 1);
101  return target;
102 }
103 
104 constexpr guint16 kKeyCodeKeyA = 0x26u;
105 constexpr guint16 kKeyCodeKeyB = 0x38u;
106 constexpr guint16 kKeyCodeKeyM = 0x3au;
107 constexpr guint16 kKeyCodeDigit1 = 0x0au;
108 constexpr guint16 kKeyCodeMinus = 0x14u;
109 constexpr guint16 kKeyCodeSemicolon = 0x2fu;
110 constexpr guint16 kKeyCodeKeyLeftBracket = 0x22u;
111 
112 static constexpr char kKeyEventChannelName[] = "flutter/keyevent";
113 static constexpr char kKeyboardChannelName[] = "flutter/keyboard";
114 static constexpr char kGetKeyboardStateMethod[] = "getKeyboardState";
115 static constexpr uint64_t kMockPhysicalKey = 42;
116 static constexpr uint64_t kMockLogicalKey = 42;
117 
118 // All key clues for a keyboard layout.
119 //
120 // The index is (keyCode * 2 + hasShift), where each value is the character for
121 // this key (GTK only supports UTF-16.) Since the maximum keycode of interest
122 // is 128, it has a total of 256 entries..
123 typedef std::array<uint32_t, 256> MockGroupLayoutData;
124 typedef std::vector<const MockGroupLayoutData*> MockLayoutData;
125 
126 extern const MockLayoutData kLayoutUs;
127 extern const MockLayoutData kLayoutRussian;
128 extern const MockLayoutData kLayoutFrench;
129 
130 G_BEGIN_DECLS
131 
132 G_DECLARE_FINAL_TYPE(FlMockViewDelegate,
133  fl_mock_view_delegate,
134  FL,
135  MOCK_VIEW_DELEGATE,
136  GObject);
137 
138 G_DECLARE_FINAL_TYPE(FlMockKeyBinaryMessenger,
139  fl_mock_key_binary_messenger,
140  FL,
141  MOCK_KEY_BINARY_MESSENGER,
142  GObject)
143 
144 G_END_DECLS
145 
146 MATCHER_P(MethodSuccessResponse, result, "") {
147  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
148  g_autoptr(FlMethodResponse) response =
149  fl_method_codec_decode_response(FL_METHOD_CODEC(codec), arg, nullptr);
150  fl_method_response_get_result(response, nullptr);
151  if (fl_value_equal(fl_method_response_get_result(response, nullptr),
152  result)) {
153  return true;
154  }
155  *result_listener << ::testing::PrintToString(response);
156  return false;
157 }
158 
159 /***** FlMockKeyBinaryMessenger *****/
160 /* Mock a binary messenger that only processes messages from the embedding on
161  * the key event channel, and does so according to the callback set by
162  * fl_mock_key_binary_messenger_set_callback_handler */
163 
164 struct _FlMockKeyBinaryMessenger {
165  GObject parent_instance;
166 };
167 
168 struct FlMockKeyBinaryMessengerPrivate {
169  ChannelCallHandler callback_handler;
170 };
171 
172 static void fl_mock_key_binary_messenger_iface_init(
173  FlBinaryMessengerInterface* iface);
174 
176  FlMockKeyBinaryMessenger,
177  fl_mock_key_binary_messenger,
178  G_TYPE_OBJECT,
179  G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
180  fl_mock_key_binary_messenger_iface_init);
181  G_ADD_PRIVATE(FlMockKeyBinaryMessenger))
182 
184  static_cast<FlMockKeyBinaryMessengerPrivate*>( \
185  fl_mock_key_binary_messenger_get_instance_private( \
186  FL_MOCK_KEY_BINARY_MESSENGER(obj)))
187 
188 static void fl_mock_key_binary_messenger_init(FlMockKeyBinaryMessenger* self) {
189  FlMockKeyBinaryMessengerPrivate* priv =
191  new (priv) FlMockKeyBinaryMessengerPrivate();
192 }
193 
194 static void fl_mock_key_binary_messenger_finalize(GObject* object) {
196  ->~FlMockKeyBinaryMessengerPrivate();
197 }
198 
199 static void fl_mock_key_binary_messenger_class_init(
200  FlMockKeyBinaryMessengerClass* klass) {
201  G_OBJECT_CLASS(klass)->finalize = fl_mock_key_binary_messenger_finalize;
202 }
203 
204 static void fl_mock_key_binary_messenger_send_on_channel(
205  FlBinaryMessenger* messenger,
206  const gchar* channel,
207  GBytes* message,
208  GCancellable* cancellable,
209  GAsyncReadyCallback callback,
210  gpointer user_data) {
211  FlMockKeyBinaryMessenger* self = FL_MOCK_KEY_BINARY_MESSENGER(messenger);
212 
213  if (callback != nullptr) {
214  EXPECT_STREQ(channel, kKeyEventChannelName);
215  FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(self)->callback_handler(
216  [self, cancellable, callback, user_data](bool handled) {
217  g_autoptr(GTask) task =
218  g_task_new(self, cancellable, callback, user_data);
219  g_autoptr(FlValue) result = fl_value_new_map();
220  fl_value_set_string_take(result, "handled",
221  fl_value_new_bool(handled));
222  g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
223  g_autoptr(GError) error = nullptr;
224  GBytes* data = fl_message_codec_encode_message(
225  FL_MESSAGE_CODEC(codec), result, &error);
226 
227  g_task_return_pointer(
228  task, data, reinterpret_cast<GDestroyNotify>(g_bytes_unref));
229  });
230  }
231 }
232 
233 static GBytes* fl_mock_key_binary_messenger_send_on_channel_finish(
234  FlBinaryMessenger* messenger,
235  GAsyncResult* result,
236  GError** error) {
237  return static_cast<GBytes*>(g_task_propagate_pointer(G_TASK(result), error));
238 }
239 
240 static void fl_mock_binary_messenger_resize_channel(
241  FlBinaryMessenger* messenger,
242  const gchar* channel,
243  int64_t new_size) {
244  // Mock implementation. Do nothing.
245 }
246 
247 static void fl_mock_binary_messenger_set_warns_on_channel_overflow(
248  FlBinaryMessenger* messenger,
249  const gchar* channel,
250  bool warns) {
251  // Mock implementation. Do nothing.
252 }
253 
254 static void fl_mock_key_binary_messenger_iface_init(
255  FlBinaryMessengerInterface* iface) {
256  iface->set_message_handler_on_channel =
257  [](FlBinaryMessenger* messenger, const gchar* channel,
258  FlBinaryMessengerMessageHandler handler, gpointer user_data,
259  GDestroyNotify destroy_notify) {
260  EXPECT_STREQ(channel, kKeyEventChannelName);
261  // No need to mock. The key event channel expects no incoming messages
262  // from the framework.
263  };
264  iface->send_response = [](FlBinaryMessenger* messenger,
265  FlBinaryMessengerResponseHandle* response_handle,
266  GBytes* response, GError** error) -> gboolean {
267  // The key event channel expects no incoming messages from the framework,
268  // hence no responses either.
269  g_return_val_if_reached(TRUE);
270  return TRUE;
271  };
272  iface->send_on_channel = fl_mock_key_binary_messenger_send_on_channel;
273  iface->send_on_channel_finish =
274  fl_mock_key_binary_messenger_send_on_channel_finish;
275  iface->resize_channel = fl_mock_binary_messenger_resize_channel;
276  iface->set_warns_on_channel_overflow =
277  fl_mock_binary_messenger_set_warns_on_channel_overflow;
278 }
279 
280 static FlMockKeyBinaryMessenger* fl_mock_key_binary_messenger_new() {
281  FlMockKeyBinaryMessenger* self = FL_MOCK_KEY_BINARY_MESSENGER(
282  g_object_new(fl_mock_key_binary_messenger_get_type(), NULL));
283 
284  // Added to stop compiler complaining about an unused function.
285  FL_IS_MOCK_KEY_BINARY_MESSENGER(self);
286 
287  return self;
288 }
289 
290 static void fl_mock_key_binary_messenger_set_callback_handler(
291  FlMockKeyBinaryMessenger* self,
292  ChannelCallHandler handler) {
293  FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(self)->callback_handler =
294  std::move(handler);
295 }
296 
297 /***** FlMockViewDelegate *****/
298 
299 struct _FlMockViewDelegate {
300  GObject parent_instance;
301 };
302 
303 struct FlMockViewDelegatePrivate {
304  FlMockKeyBinaryMessenger* messenger;
305  EmbedderCallHandler embedder_handler;
306  bool text_filter_result;
307  RedispatchHandler redispatch_handler;
308  KeyboardLayoutNotifier layout_notifier;
309  const MockLayoutData* layout_data;
310 };
311 
312 static void fl_mock_view_keyboard_delegate_iface_init(
313  FlKeyboardViewDelegateInterface* iface);
314 
316  FlMockViewDelegate,
317  fl_mock_view_delegate,
318  G_TYPE_OBJECT,
319  G_IMPLEMENT_INTERFACE(fl_keyboard_view_delegate_get_type(),
320  fl_mock_view_keyboard_delegate_iface_init);
321  G_ADD_PRIVATE(FlMockViewDelegate))
322 
324  static_cast<FlMockViewDelegatePrivate*>( \
325  fl_mock_view_delegate_get_instance_private(FL_MOCK_VIEW_DELEGATE(obj)))
326 
327 static void fl_mock_view_delegate_init(FlMockViewDelegate* self) {
328  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
329  new (priv) FlMockViewDelegatePrivate();
330 }
331 
332 static void fl_mock_view_delegate_finalize(GObject* object) {
333  FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(object)->~FlMockViewDelegatePrivate();
334 }
335 
336 static void fl_mock_view_delegate_dispose(GObject* object) {
337  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(object);
338 
339  g_clear_object(&priv->messenger);
340 
341  G_OBJECT_CLASS(fl_mock_view_delegate_parent_class)->dispose(object);
342 }
343 
344 static void fl_mock_view_delegate_class_init(FlMockViewDelegateClass* klass) {
345  G_OBJECT_CLASS(klass)->dispose = fl_mock_view_delegate_dispose;
346  G_OBJECT_CLASS(klass)->finalize = fl_mock_view_delegate_finalize;
347 }
348 
349 static void fl_mock_view_keyboard_send_key_event(
350  FlKeyboardViewDelegate* view_delegate,
351  const FlutterKeyEvent* event,
352  FlutterKeyEventCallback callback,
353  void* user_data) {
354  FlMockViewDelegatePrivate* priv =
355  FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
356  priv->embedder_handler(event, [callback, user_data](bool handled) {
357  if (callback != nullptr) {
358  callback(handled, user_data);
359  }
360  });
361 }
362 
363 static gboolean fl_mock_view_keyboard_text_filter_key_press(
364  FlKeyboardViewDelegate* view_delegate,
365  FlKeyEvent* event) {
366  FlMockViewDelegatePrivate* priv =
367  FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
368  return priv->text_filter_result;
369 }
370 
371 static FlBinaryMessenger* fl_mock_view_keyboard_get_messenger(
372  FlKeyboardViewDelegate* view_delegate) {
373  FlMockViewDelegatePrivate* priv =
374  FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
375  return FL_BINARY_MESSENGER(priv->messenger);
376 }
377 
378 static void fl_mock_view_keyboard_redispatch_event(
379  FlKeyboardViewDelegate* view_delegate,
380  std::unique_ptr<FlKeyEvent> event) {
381  FlMockViewDelegatePrivate* priv =
382  FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
383  if (priv->redispatch_handler) {
384  priv->redispatch_handler(std::move(event));
385  }
386 }
387 
388 static void fl_mock_view_keyboard_subscribe_to_layout_change(
389  FlKeyboardViewDelegate* delegate,
390  KeyboardLayoutNotifier notifier) {
391  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(delegate);
392  priv->layout_notifier = std::move(notifier);
393 }
394 
395 static guint fl_mock_view_keyboard_lookup_key(FlKeyboardViewDelegate* delegate,
396  const GdkKeymapKey* key) {
397  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(delegate);
398  guint8 group = static_cast<guint8>(key->group);
399  EXPECT_LT(group, priv->layout_data->size());
400  const MockGroupLayoutData* group_layout = (*priv->layout_data)[group];
401  EXPECT_TRUE(group_layout != nullptr);
402  EXPECT_TRUE(key->level == 0 || key->level == 1);
403  bool shift = key->level == 1;
404  return (*group_layout)[key->keycode * 2 + shift];
405 }
406 
407 static GHashTable* fl_mock_view_keyboard_get_keyboard_state(
408  FlKeyboardViewDelegate* view_delegate) {
409  GHashTable* result = g_hash_table_new(g_direct_hash, g_direct_equal);
410  g_hash_table_insert(result, reinterpret_cast<gpointer>(kMockPhysicalKey),
411  reinterpret_cast<gpointer>(kMockLogicalKey));
412 
413  return result;
414 }
415 
416 static void fl_mock_view_keyboard_delegate_iface_init(
417  FlKeyboardViewDelegateInterface* iface) {
418  iface->send_key_event = fl_mock_view_keyboard_send_key_event;
419  iface->text_filter_key_press = fl_mock_view_keyboard_text_filter_key_press;
420  iface->get_messenger = fl_mock_view_keyboard_get_messenger;
421  iface->redispatch_event = fl_mock_view_keyboard_redispatch_event;
422  iface->subscribe_to_layout_change =
423  fl_mock_view_keyboard_subscribe_to_layout_change;
424  iface->lookup_key = fl_mock_view_keyboard_lookup_key;
425  iface->get_keyboard_state = fl_mock_view_keyboard_get_keyboard_state;
426 }
427 
428 static FlMockViewDelegate* fl_mock_view_delegate_new() {
429  FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(
430  g_object_new(fl_mock_view_delegate_get_type(), nullptr));
431 
432  // Added to stop compiler complaining about an unused function.
433  FL_IS_MOCK_VIEW_DELEGATE(self);
434 
435  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
436  priv->messenger = fl_mock_key_binary_messenger_new();
437 
438  return self;
439 }
440 
441 static void fl_mock_view_set_embedder_handler(FlMockViewDelegate* self,
442  EmbedderCallHandler handler) {
443  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
444  priv->embedder_handler = std::move(handler);
445 }
446 
447 static void fl_mock_view_set_text_filter_result(FlMockViewDelegate* self,
448  bool result) {
449  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
450  priv->text_filter_result = result;
451 }
452 
453 static void fl_mock_view_set_redispatch_handler(FlMockViewDelegate* self,
454  RedispatchHandler handler) {
455  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
456  priv->redispatch_handler = std::move(handler);
457 }
458 
459 static void fl_mock_view_set_layout(FlMockViewDelegate* self,
460  const MockLayoutData* layout) {
461  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
462  priv->layout_data = layout;
463  if (priv->layout_notifier != nullptr) {
464  priv->layout_notifier();
465  }
466 }
467 
468 /***** End FlMockViewDelegate *****/
469 
470 // Create a new #FlKeyEvent with the given information.
471 static FlKeyEvent* fl_key_event_new_by_mock(bool is_press,
472  guint keyval,
473  guint16 keycode,
474  GdkModifierType state,
475  gboolean is_modifier,
476  guint8 group = 0) {
477  FlKeyEvent* event = g_new0(FlKeyEvent, 1);
478  event->is_press = is_press;
479  event->time = 0;
480  event->state = state;
481  event->keyval = keyval;
482  event->group = group;
483  event->keycode = keycode;
484  return event;
485 }
486 
487 class KeyboardTester {
488  public:
489  KeyboardTester() {
490  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
491 
492  view_ = fl_mock_view_delegate_new();
493  respondToEmbedderCallsWith(false);
494  respondToChannelCallsWith(false);
495  respondToTextInputWith(false);
496  setLayout(kLayoutUs);
497 
498  manager_ =
499  fl_keyboard_manager_new(messenger, FL_KEYBOARD_VIEW_DELEGATE(view_));
500  }
501 
502  ~KeyboardTester() {
503  g_clear_object(&view_);
504  g_clear_object(&manager_);
505  }
506 
507  FlKeyboardManager* manager() { return manager_; }
508 
509  // Block until all GdkMainLoop messages are processed, which is basically
510  // used only for channel messages.
511  void flushChannelMessages() {
512  GMainLoop* loop = g_main_loop_new(nullptr, 0);
513  g_idle_add(_flushChannelMessagesCb, loop);
514  g_main_loop_run(loop);
515  }
516 
517  // Dispatch each of the given events, expect their results to be false
518  // (unhandled), and clear the event array.
519  //
520  // Returns the number of events redispatched. If any result is unexpected
521  // (handled), return a minus number `-x` instead, where `x` is the index of
522  // the first unexpected redispatch.
523  int redispatchEventsAndClear(
524  std::vector<std::unique_ptr<FlKeyEvent>>& events) {
525  size_t event_count = events.size();
526  int first_error = -1;
527  during_redispatch_ = true;
528  for (size_t event_id = 0; event_id < event_count; event_id += 1) {
529  bool handled = fl_keyboard_manager_handle_event(
530  manager_, events[event_id].release());
531  EXPECT_FALSE(handled);
532  if (handled) {
533  first_error = first_error == -1 ? event_id : first_error;
534  }
535  }
536  during_redispatch_ = false;
537  events.clear();
538  return first_error < 0 ? event_count : -first_error;
539  }
540 
541  void respondToEmbedderCallsWith(bool response) {
542  fl_mock_view_set_embedder_handler(
543  view_, [response, this](const FlutterKeyEvent* event,
544  const AsyncKeyCallback& callback) {
545  EXPECT_FALSE(during_redispatch_);
546  callback(response);
547  });
548  }
549 
550  void recordEmbedderCallsTo(std::vector<CallRecord>& storage) {
551  fl_mock_view_set_embedder_handler(
552  view_, [&storage, this](const FlutterKeyEvent* event,
553  AsyncKeyCallback callback) {
554  EXPECT_FALSE(during_redispatch_);
555  auto new_event = std::make_unique<FlutterKeyEvent>(*event);
556  char* new_event_character = cloneString(event->character);
557  new_event->character = new_event_character;
558  storage.push_back(CallRecord{
559  .type = CallRecord::kKeyCallEmbedder,
560  .callback = std::move(callback),
561  .event = std::move(new_event),
562  .event_character = std::unique_ptr<char[]>(new_event_character),
563  });
564  });
565  }
566 
567  void respondToEmbedderCallsWithAndRecordsTo(
568  bool response,
569  std::vector<CallRecord>& storage) {
570  fl_mock_view_set_embedder_handler(
571  view_, [&storage, response, this](const FlutterKeyEvent* event,
572  const AsyncKeyCallback& callback) {
573  EXPECT_FALSE(during_redispatch_);
574  auto new_event = std::make_unique<FlutterKeyEvent>(*event);
575  char* new_event_character = cloneString(event->character);
576  new_event->character = new_event_character;
577  storage.push_back(CallRecord{
578  .type = CallRecord::kKeyCallEmbedder,
579  .event = std::move(new_event),
580  .event_character = std::unique_ptr<char[]>(new_event_character),
581  });
582  callback(response);
583  });
584  }
585 
586  void respondToChannelCallsWith(bool response) {
587  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_);
588 
589  fl_mock_key_binary_messenger_set_callback_handler(
590  priv->messenger, [response, this](const AsyncKeyCallback& callback) {
591  EXPECT_FALSE(during_redispatch_);
592  callback(response);
593  });
594  }
595 
596  void recordChannelCallsTo(std::vector<CallRecord>& storage) {
597  FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_);
598 
599  fl_mock_key_binary_messenger_set_callback_handler(
600  priv->messenger, [&storage, this](AsyncKeyCallback callback) {
601  EXPECT_FALSE(during_redispatch_);
602  storage.push_back(CallRecord{
603  .type = CallRecord::kKeyCallChannel,
604  .callback = std::move(callback),
605  });
606  });
607  }
608 
609  void respondToTextInputWith(bool response) {
610  fl_mock_view_set_text_filter_result(view_, response);
611  }
612 
613  void recordRedispatchedEventsTo(
614  std::vector<std::unique_ptr<FlKeyEvent>>& storage) {
615  fl_mock_view_set_redispatch_handler(
616  view_, [&storage](std::unique_ptr<FlKeyEvent> key) {
617  storage.push_back(std::move(key));
618  });
619  }
620 
621  void setLayout(const MockLayoutData& layout) {
622  fl_mock_view_set_layout(view_, &layout);
623  }
624 
625  private:
626  FlMockViewDelegate* view_;
627  FlKeyboardManager* manager_;
628  bool during_redispatch_ = false;
629 
630  static gboolean _flushChannelMessagesCb(gpointer data) {
631  g_autoptr(GMainLoop) loop = reinterpret_cast<GMainLoop*>(data);
632  g_main_loop_quit(loop);
633  return FALSE;
634  }
635 };
636 
637 // Make sure that the keyboard can be disposed without crashes when there are
638 // unresolved pending events.
639 TEST(FlKeyboardManagerTest, DisposeWithUnresolvedPends) {
640  KeyboardTester tester;
641  std::vector<CallRecord> call_records;
642 
643  // Record calls so that they aren't responded.
644  tester.recordEmbedderCallsTo(call_records);
646  tester.manager(),
647  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
648  static_cast<GdkModifierType>(0), false));
649 
650  tester.respondToEmbedderCallsWith(true);
652  tester.manager(),
653  fl_key_event_new_by_mock(false, GDK_KEY_a, kKeyCodeKeyA,
654  static_cast<GdkModifierType>(0), false));
655 
656  tester.flushChannelMessages();
657 
658  // Passes if the cleanup does not crash.
659 }
660 
661 TEST(FlKeyboardManagerTest, SingleDelegateWithAsyncResponds) {
662  KeyboardTester tester;
663  std::vector<CallRecord> call_records;
664  std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
665 
666  gboolean manager_handled = false;
667 
668  /// Test 1: One event that is handled by the framework
669  tester.recordEmbedderCallsTo(call_records);
670  tester.recordRedispatchedEventsTo(redispatched);
671 
672  // Dispatch a key event
673  manager_handled = fl_keyboard_manager_handle_event(
674  tester.manager(),
675  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
676  static_cast<GdkModifierType>(0), false));
677  tester.flushChannelMessages();
678  EXPECT_EQ(manager_handled, true);
679  EXPECT_EQ(redispatched.size(), 0u);
680  EXPECT_EQ(call_records.size(), 1u);
681  EXPECT_KEY_EVENT(call_records[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
682  kLogicalKeyA, "a", false);
683 
684  call_records[0].callback(true);
685  tester.flushChannelMessages();
686  EXPECT_EQ(redispatched.size(), 0u);
687  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
688  call_records.clear();
689 
690  /// Test 2: Two events that are unhandled by the framework
691  manager_handled = fl_keyboard_manager_handle_event(
692  tester.manager(),
693  fl_key_event_new_by_mock(false, GDK_KEY_a, kKeyCodeKeyA,
694  static_cast<GdkModifierType>(0), false));
695  tester.flushChannelMessages();
696  EXPECT_EQ(manager_handled, true);
697  EXPECT_EQ(redispatched.size(), 0u);
698  EXPECT_EQ(call_records.size(), 1u);
699  EXPECT_KEY_EVENT(call_records[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
700  kLogicalKeyA, nullptr, false);
701 
702  // Dispatch another key event
703  manager_handled = fl_keyboard_manager_handle_event(
704  tester.manager(),
705  fl_key_event_new_by_mock(true, GDK_KEY_b, kKeyCodeKeyB,
706  static_cast<GdkModifierType>(0), false));
707  tester.flushChannelMessages();
708  EXPECT_EQ(manager_handled, true);
709  EXPECT_EQ(redispatched.size(), 0u);
710  EXPECT_EQ(call_records.size(), 2u);
711  EXPECT_KEY_EVENT(call_records[1], kFlutterKeyEventTypeDown, kPhysicalKeyB,
712  kLogicalKeyB, "b", false);
713 
714  // Resolve the second event first to test out-of-order response
715  call_records[1].callback(false);
716  EXPECT_EQ(redispatched.size(), 1u);
717  EXPECT_EQ(redispatched[0]->keyval, 0x62u);
718  call_records[0].callback(false);
719  tester.flushChannelMessages();
720  EXPECT_EQ(redispatched.size(), 2u);
721  EXPECT_EQ(redispatched[1]->keyval, 0x61u);
722 
723  EXPECT_FALSE(fl_keyboard_manager_is_state_clear(tester.manager()));
724  call_records.clear();
725 
726  // Resolve redispatches
727  EXPECT_EQ(tester.redispatchEventsAndClear(redispatched), 2);
728  tester.flushChannelMessages();
729  EXPECT_EQ(call_records.size(), 0u);
730  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
731 
732  /// Test 3: Dispatch the same event again to ensure that prevention from
733  /// redispatching only works once.
734  manager_handled = fl_keyboard_manager_handle_event(
735  tester.manager(),
736  fl_key_event_new_by_mock(false, GDK_KEY_a, kKeyCodeKeyA,
737  static_cast<GdkModifierType>(0), false));
738  tester.flushChannelMessages();
739  EXPECT_EQ(manager_handled, true);
740  EXPECT_EQ(redispatched.size(), 0u);
741  EXPECT_EQ(call_records.size(), 1u);
742 
743  call_records[0].callback(true);
744  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
745 }
746 
747 TEST(FlKeyboardManagerTest, SingleDelegateWithSyncResponds) {
748  KeyboardTester tester;
749  gboolean manager_handled = false;
750  std::vector<CallRecord> call_records;
751  std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
752 
753  /// Test 1: One event that is handled by the framework
754  tester.respondToEmbedderCallsWithAndRecordsTo(true, call_records);
755  tester.recordRedispatchedEventsTo(redispatched);
756 
757  // Dispatch a key event
758  manager_handled = fl_keyboard_manager_handle_event(
759  tester.manager(),
760  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
761  static_cast<GdkModifierType>(0), false));
762  tester.flushChannelMessages();
763  EXPECT_EQ(manager_handled, true);
764  EXPECT_EQ(call_records.size(), 1u);
765  EXPECT_KEY_EVENT(call_records[0], kFlutterKeyEventTypeDown, kPhysicalKeyA,
766  kLogicalKeyA, "a", false);
767  EXPECT_EQ(redispatched.size(), 0u);
768  call_records.clear();
769 
770  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
771  redispatched.clear();
772 
773  /// Test 2: An event unhandled by the framework
774  tester.respondToEmbedderCallsWithAndRecordsTo(false, call_records);
775  manager_handled = fl_keyboard_manager_handle_event(
776  tester.manager(),
777  fl_key_event_new_by_mock(false, GDK_KEY_a, kKeyCodeKeyA,
778  static_cast<GdkModifierType>(0), false));
779  tester.flushChannelMessages();
780  EXPECT_EQ(manager_handled, true);
781  EXPECT_EQ(call_records.size(), 1u);
782  EXPECT_KEY_EVENT(call_records[0], kFlutterKeyEventTypeUp, kPhysicalKeyA,
783  kLogicalKeyA, nullptr, false);
784  EXPECT_EQ(redispatched.size(), 1u);
785  call_records.clear();
786 
787  EXPECT_FALSE(fl_keyboard_manager_is_state_clear(tester.manager()));
788 
789  EXPECT_EQ(tester.redispatchEventsAndClear(redispatched), 1);
790  EXPECT_EQ(call_records.size(), 0u);
791 
792  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
793 }
794 
795 TEST(FlKeyboardManagerTest, WithTwoAsyncDelegates) {
796  KeyboardTester tester;
797  std::vector<CallRecord> call_records;
798  std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
799 
800  gboolean manager_handled = false;
801 
802  tester.recordEmbedderCallsTo(call_records);
803  tester.recordChannelCallsTo(call_records);
804  tester.recordRedispatchedEventsTo(redispatched);
805 
806  /// Test 1: One delegate responds true, the other false
807 
808  manager_handled = fl_keyboard_manager_handle_event(
809  tester.manager(),
810  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
811  static_cast<GdkModifierType>(0), false));
812 
813  EXPECT_EQ(manager_handled, true);
814  EXPECT_EQ(redispatched.size(), 0u);
815  EXPECT_EQ(call_records.size(), 2u);
816 
817  EXPECT_EQ(call_records[0].type, CallRecord::kKeyCallEmbedder);
818  EXPECT_EQ(call_records[1].type, CallRecord::kKeyCallChannel);
819 
820  call_records[0].callback(true);
821  call_records[1].callback(false);
822  tester.flushChannelMessages();
823  EXPECT_EQ(redispatched.size(), 0u);
824 
825  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
826  call_records.clear();
827 
828  /// Test 2: All delegates respond false
829  manager_handled = fl_keyboard_manager_handle_event(
830  tester.manager(),
831  fl_key_event_new_by_mock(false, GDK_KEY_a, kKeyCodeKeyA,
832  static_cast<GdkModifierType>(0), false));
833 
834  EXPECT_EQ(manager_handled, true);
835  EXPECT_EQ(redispatched.size(), 0u);
836  EXPECT_EQ(call_records.size(), 2u);
837 
838  EXPECT_EQ(call_records[0].type, CallRecord::kKeyCallEmbedder);
839  EXPECT_EQ(call_records[1].type, CallRecord::kKeyCallChannel);
840 
841  call_records[0].callback(false);
842  call_records[1].callback(false);
843 
844  call_records.clear();
845 
846  // Resolve redispatch
847  tester.flushChannelMessages();
848  EXPECT_EQ(redispatched.size(), 1u);
849  EXPECT_EQ(tester.redispatchEventsAndClear(redispatched), 1);
850  EXPECT_EQ(call_records.size(), 0u);
851 
852  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
853 }
854 
855 TEST(FlKeyboardManagerTest, TextInputPluginReturnsFalse) {
856  KeyboardTester tester;
857  std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
858  gboolean manager_handled = false;
859  tester.recordRedispatchedEventsTo(redispatched);
860  tester.respondToTextInputWith(false);
861 
862  // Dispatch a key event.
863  manager_handled = fl_keyboard_manager_handle_event(
864  tester.manager(),
865  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
866  static_cast<GdkModifierType>(0), false));
867  tester.flushChannelMessages();
868  EXPECT_EQ(manager_handled, true);
869  // The event was redispatched because no one handles it.
870  EXPECT_EQ(redispatched.size(), 1u);
871 
872  // Resolve redispatched event.
873  EXPECT_EQ(tester.redispatchEventsAndClear(redispatched), 1);
874 
875  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
876 }
877 
878 TEST(FlKeyboardManagerTest, TextInputPluginReturnsTrue) {
879  KeyboardTester tester;
880  std::vector<std::unique_ptr<FlKeyEvent>> redispatched;
881  gboolean manager_handled = false;
882  tester.recordRedispatchedEventsTo(redispatched);
883  tester.respondToTextInputWith(true);
884 
885  // Dispatch a key event.
886  manager_handled = fl_keyboard_manager_handle_event(
887  tester.manager(),
888  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
889  static_cast<GdkModifierType>(0), false));
890  tester.flushChannelMessages();
891  EXPECT_EQ(manager_handled, true);
892  // The event was not redispatched because text input plugin handles it.
893  EXPECT_EQ(redispatched.size(), 0u);
894 
895  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(tester.manager()));
896 }
897 
898 TEST(FlKeyboardManagerTest, CorrectLogicalKeyForLayouts) {
899  KeyboardTester tester;
900 
901  std::vector<CallRecord> call_records;
902  tester.recordEmbedderCallsTo(call_records);
903 
904  auto sendTap = [&](guint8 keycode, guint keyval, guint8 group) {
906  tester.manager(), fl_key_event_new_by_mock(
907  true, keyval, keycode,
908  static_cast<GdkModifierType>(0), false, group));
910  tester.manager(), fl_key_event_new_by_mock(
911  false, keyval, keycode,
912  static_cast<GdkModifierType>(0), false, group));
913  };
914 
915  /* US keyboard layout */
916 
917  sendTap(kKeyCodeKeyA, GDK_KEY_a, 0); // KeyA
918  VERIFY_DOWN(kLogicalKeyA, "a");
919 
920  sendTap(kKeyCodeKeyA, GDK_KEY_A, 0); // Shift-KeyA
921  VERIFY_DOWN(kLogicalKeyA, "A");
922 
923  sendTap(kKeyCodeDigit1, GDK_KEY_1, 0); // Digit1
924  VERIFY_DOWN(kLogicalDigit1, "1");
925 
926  sendTap(kKeyCodeDigit1, GDK_KEY_exclam, 0); // Shift-Digit1
927  VERIFY_DOWN(kLogicalDigit1, "!");
928 
929  sendTap(kKeyCodeMinus, GDK_KEY_minus, 0); // Minus
930  VERIFY_DOWN(kLogicalMinus, "-");
931 
932  sendTap(kKeyCodeMinus, GDK_KEY_underscore, 0); // Shift-Minus
933  VERIFY_DOWN(kLogicalUnderscore, "_");
934 
935  /* French keyboard layout, group 3, which is when the input method is showing
936  * "Fr" */
937 
938  tester.setLayout(kLayoutFrench);
939 
940  sendTap(kKeyCodeKeyA, GDK_KEY_q, 3); // KeyA
941  VERIFY_DOWN(kLogicalKeyQ, "q");
942 
943  sendTap(kKeyCodeKeyA, GDK_KEY_Q, 3); // Shift-KeyA
944  VERIFY_DOWN(kLogicalKeyQ, "Q");
945 
946  sendTap(kKeyCodeSemicolon, GDK_KEY_m, 3); // ; but prints M
947  VERIFY_DOWN(kLogicalKeyM, "m");
948 
949  sendTap(kKeyCodeKeyM, GDK_KEY_comma, 3); // M but prints ,
950  VERIFY_DOWN(kLogicalComma, ",");
951 
952  sendTap(kKeyCodeDigit1, GDK_KEY_ampersand, 3); // Digit1
953  VERIFY_DOWN(kLogicalDigit1, "&");
954 
955  sendTap(kKeyCodeDigit1, GDK_KEY_1, 3); // Shift-Digit1
956  VERIFY_DOWN(kLogicalDigit1, "1");
957 
958  sendTap(kKeyCodeMinus, GDK_KEY_parenright, 3); // Minus
959  VERIFY_DOWN(kLogicalParenthesisRight, ")");
960 
961  sendTap(kKeyCodeMinus, GDK_KEY_degree, 3); // Shift-Minus
962  VERIFY_DOWN(static_cast<uint32_t>(L'°'), "°");
963 
964  /* French keyboard layout, group 0, which is pressing the "extra key for
965  * triggering input method" key once after switching to French IME. */
966 
967  sendTap(kKeyCodeKeyA, GDK_KEY_a, 0); // KeyA
968  VERIFY_DOWN(kLogicalKeyA, "a");
969 
970  sendTap(kKeyCodeDigit1, GDK_KEY_1, 0); // Digit1
971  VERIFY_DOWN(kLogicalDigit1, "1");
972 
973  /* Russian keyboard layout, group 2 */
974  tester.setLayout(kLayoutRussian);
975 
976  sendTap(kKeyCodeKeyA, GDK_KEY_Cyrillic_ef, 2); // KeyA
977  VERIFY_DOWN(kLogicalKeyA, "Ñ„");
978 
979  sendTap(kKeyCodeDigit1, GDK_KEY_1, 2); // Shift-Digit1
980  VERIFY_DOWN(kLogicalDigit1, "1");
981 
982  sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_Cyrillic_ha, 2);
983  VERIFY_DOWN(kLogicalBracketLeft, "Ñ…");
984 
985  /* Russian keyboard layout, group 0 */
986  sendTap(kKeyCodeKeyA, GDK_KEY_a, 0); // KeyA
987  VERIFY_DOWN(kLogicalKeyA, "a");
988 
989  sendTap(kKeyCodeKeyLeftBracket, GDK_KEY_bracketleft, 0);
990  VERIFY_DOWN(kLogicalBracketLeft, "[");
991 }
992 
993 TEST(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
994  KeyboardTester tester;
995  std::vector<CallRecord> call_records;
996  tester.recordEmbedderCallsTo(call_records);
997 
998  auto verifyModifierIsSynthesized = [&](GdkModifierType mask,
999  uint64_t physical, uint64_t logical) {
1000  // Modifier is pressed.
1001  guint state = mask;
1002  fl_keyboard_manager_sync_modifier_if_needed(tester.manager(), state, 1000);
1003  EXPECT_EQ(call_records.size(), 1u);
1004  EXPECT_KEY_EVENT(call_records[0], kFlutterKeyEventTypeDown, physical,
1005  logical, NULL, true);
1006  // Modifier is released.
1007  state = state ^ mask;
1008  fl_keyboard_manager_sync_modifier_if_needed(tester.manager(), state, 1001);
1009  EXPECT_EQ(call_records.size(), 2u);
1010  EXPECT_KEY_EVENT(call_records[1], kFlutterKeyEventTypeUp, physical, logical,
1011  NULL, true);
1012  call_records.clear();
1013  };
1014 
1015  // No modifiers pressed.
1016  guint state = 0;
1017  fl_keyboard_manager_sync_modifier_if_needed(tester.manager(), state, 1000);
1018  EXPECT_EQ(call_records.size(), 0u);
1019  call_records.clear();
1020 
1021  // Press and release each modifier once.
1022  verifyModifierIsSynthesized(GDK_CONTROL_MASK, kPhysicalControlLeft,
1023  kLogicalControlLeft);
1024  verifyModifierIsSynthesized(GDK_META_MASK, kPhysicalMetaLeft,
1025  kLogicalMetaLeft);
1026  verifyModifierIsSynthesized(GDK_MOD1_MASK, kPhysicalAltLeft, kLogicalAltLeft);
1027  verifyModifierIsSynthesized(GDK_SHIFT_MASK, kPhysicalShiftLeft,
1028  kLogicalShiftLeft);
1029 }
1030 
1031 TEST(FlKeyboardManagerTest, GetPressedState) {
1032  KeyboardTester tester;
1033  tester.respondToTextInputWith(true);
1034 
1035  // Dispatch a key event.
1037  tester.manager(),
1038  fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA,
1039  static_cast<GdkModifierType>(0), false));
1040 
1041  GHashTable* pressedState =
1042  fl_keyboard_manager_get_pressed_state(tester.manager());
1043  EXPECT_EQ(g_hash_table_size(pressedState), 1u);
1044 
1045  gpointer physical_key =
1046  g_hash_table_lookup(pressedState, uint64_to_gpointer(kPhysicalKeyA));
1047  EXPECT_EQ(gpointer_to_uint64(physical_key), kLogicalKeyA);
1048 }
1049 
1050 TEST(FlKeyboardPluginTest, KeyboardChannelGetPressedState) {
1051  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
1052 
1053  g_autoptr(FlKeyboardManager) manager = fl_keyboard_manager_new(
1054  messenger, FL_KEYBOARD_VIEW_DELEGATE(fl_mock_view_delegate_new()));
1055  EXPECT_NE(manager, nullptr);
1056 
1057  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
1058  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
1059  FL_METHOD_CODEC(codec), kGetKeyboardStateMethod, nullptr, nullptr);
1060 
1061  g_autoptr(FlValue) response = fl_value_new_map();
1062  fl_value_set_take(response, fl_value_new_int(kMockPhysicalKey),
1063  fl_value_new_int(kMockLogicalKey));
1064  EXPECT_CALL(messenger,
1066  ::testing::Eq<FlBinaryMessenger*>(messenger), ::testing::_,
1067  MethodSuccessResponse(response), ::testing::_))
1068  .WillOnce(::testing::Return(true));
1069 
1070  messenger.ReceiveMessage(kKeyboardChannelName, message);
1071 }
1072 
1073 // The following layout data is generated using DEBUG_PRINT_LAYOUT.
1074 
1075 const MockGroupLayoutData kLayoutUs0{{
1076  // +0x0 Shift +0x1 Shift +0x2 Shift +0x3 Shift
1077  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x00
1078  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x04
1079  0xffff, 0x0031, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040, // 0x08
1080  0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e, // 0x0c
1081  0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029, // 0x10
1082  0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff, // 0x14
1083  0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052, // 0x18
1084  0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049, // 0x1c
1085  0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d, // 0x20
1086  0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053, // 0x24
1087  0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048, // 0x28
1088  0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a, // 0x2c
1089  0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c, // 0x30
1090  0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056, // 0x34
1091  0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c, // 0x38
1092  0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff, // 0x3c
1093  0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x40
1094  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x44
1095  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x48
1096  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x4c
1097  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x50
1098  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x54
1099  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x58
1100  0xffff, 0xffff, 0x003c, 0x003e, 0x003c, 0x003e, 0xffff, 0xffff, // 0x5c
1101  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x60
1102  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x64
1103  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x68
1104  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x6c
1105  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x70
1106  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x74
1107  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x78
1108  0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff, // 0x7c
1109 }};
1110 
1111 const MockGroupLayoutData kLayoutRussian0{
1112  // +0x0 Shift +0x1 Shift +0x2 Shift +0x3 Shift
1113  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x00
1114  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x04
1115  0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040, // 0x08
1116  0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e, // 0x0c
1117  0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029, // 0x10
1118  0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff, // 0x14
1119  0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052, // 0x18
1120  0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049, // 0x1c
1121  0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d, // 0x20
1122  0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053, // 0x24
1123  0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048, // 0x28
1124  0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a, // 0x2c
1125  0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c, // 0x30
1126  0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056, // 0x34
1127  0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c, // 0x38
1128  0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff, // 0x3c
1129  0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x40
1130  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x44
1131  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x48
1132  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x4c
1133  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x50
1134  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x54
1135  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x58
1136  0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff, // 0x5c
1137  0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x60
1138  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, // 0x64
1139  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x68
1140  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x6c
1141  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x70
1142  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x74
1143  0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x78
1144  0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff, // 0x7c
1145 };
1146 
1147 const MockGroupLayoutData kLayoutRussian2{{
1148  // +0x0 Shift +0x1 Shift +0x2 Shift +0x3 Shift
1149  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x00
1150  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x04
1151  0xffff, 0x0031, 0x0021, 0x0000, 0x0031, 0x0021, 0x0032, 0x0022, // 0x08
1152  0x0033, 0x06b0, 0x0034, 0x003b, 0x0035, 0x0025, 0x0036, 0x003a, // 0x0c
1153  0x0037, 0x003f, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029, // 0x10
1154  0x002d, 0x005f, 0x003d, 0x002b, 0x0071, 0x0051, 0x0000, 0x0000, // 0x14
1155  0x06ca, 0x06ea, 0x06c3, 0x06e3, 0x06d5, 0x06f5, 0x06cb, 0x06eb, // 0x18
1156  0x06c5, 0x06e5, 0x06ce, 0x06ee, 0x06c7, 0x06e7, 0x06db, 0x06fb, // 0x1c
1157  0x06dd, 0x06fd, 0x06da, 0x06fa, 0x06c8, 0x06e8, 0x06df, 0x06ff, // 0x20
1158  0x0061, 0x0041, 0x0041, 0x0000, 0x06c6, 0x06e6, 0x06d9, 0x06f9, // 0x24
1159  0x06d7, 0x06f7, 0x06c1, 0x06e1, 0x06d0, 0x06f0, 0x06d2, 0x06f2, // 0x28
1160  0x06cf, 0x06ef, 0x06cc, 0x06ec, 0x06c4, 0x06e4, 0x06d6, 0x06f6, // 0x2c
1161  0x06dc, 0x06fc, 0x06a3, 0x06b3, 0x007c, 0x0000, 0x005c, 0x002f, // 0x30
1162  0x06d1, 0x06f1, 0x06de, 0x06fe, 0x06d3, 0x06f3, 0x06cd, 0x06ed, // 0x34
1163  0x06c9, 0x06e9, 0x06d4, 0x06f4, 0x06d8, 0x06f8, 0x06c2, 0x06e2, // 0x38
1164  0x06c0, 0x06e0, 0x002e, 0x002c, 0xffff, 0xffff, 0xffff, 0xffff, // 0x3c
1165  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x40
1166  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x44
1167  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x48
1168  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x4c
1169  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x50
1170  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x54
1171  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x58
1172  0xffff, 0xffff, 0x003c, 0x003e, 0x002f, 0x007c, 0xffff, 0xffff, // 0x5c
1173  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x60
1174  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x64
1175  0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0x0000, // 0x68
1176  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x6c
1177  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x70
1178  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x74
1179  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, // 0x78
1180  0x00b1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x7c
1181 }};
1182 
1183 const MockGroupLayoutData kLayoutFrench0 = {
1184  // +0x0 Shift +0x1 Shift +0x2 Shift +0x3 Shift
1185  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x00
1186  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x04
1187  0x0000, 0xffff, 0xffff, 0x0031, 0x0031, 0x0021, 0x0032, 0x0040, // 0x08
1188  0x0033, 0x0023, 0x0034, 0x0024, 0x0035, 0x0025, 0x0036, 0x005e, // 0x0c
1189  0x0037, 0x0026, 0x0038, 0x002a, 0x0039, 0x0028, 0x0030, 0x0029, // 0x10
1190  0x002d, 0x005f, 0x003d, 0x002b, 0xffff, 0xffff, 0xffff, 0xffff, // 0x14
1191  0x0071, 0x0051, 0x0077, 0x0057, 0x0065, 0x0045, 0x0072, 0x0052, // 0x18
1192  0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049, // 0x1c
1193  0x006f, 0x004f, 0x0070, 0x0050, 0x005b, 0x007b, 0x005d, 0x007d, // 0x20
1194  0xffff, 0xffff, 0xffff, 0x0061, 0x0061, 0x0041, 0x0073, 0x0053, // 0x24
1195  0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048, // 0x28
1196  0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x003b, 0x003a, // 0x2c
1197  0x0027, 0x0022, 0x0060, 0x007e, 0xffff, 0x005c, 0x005c, 0x007c, // 0x30
1198  0x007a, 0x005a, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056, // 0x34
1199  0x0062, 0x0042, 0x006e, 0x004e, 0x006d, 0x004d, 0x002c, 0x003c, // 0x38
1200  0x002e, 0x003e, 0x002f, 0x003f, 0xffff, 0xffff, 0xffff, 0xffff, // 0x3c
1201  0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x40
1202  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x44
1203  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x48
1204  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x4c
1205  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x50
1206  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x54
1207  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x58
1208  0xffff, 0xffff, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff, // 0x5c
1209  0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x60
1210  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, // 0x64
1211  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x68
1212  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x6c
1213  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x70
1214  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x74
1215  0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x78
1216  0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, 0xffff, 0xffff, // 0x7c
1217 };
1218 
1219 const MockGroupLayoutData kLayoutFrench3 = {
1220  // +0x0 Shift +0x1 Shift +0x2 Shift +0x3 Shift
1221  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x00
1222  0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, // 0x04
1223  0x0000, 0xffff, 0x0000, 0x0000, 0x0026, 0x0031, 0x00e9, 0x0032, // 0x08
1224  0x0022, 0x0033, 0x0027, 0x0034, 0x0028, 0x0035, 0x002d, 0x0036, // 0x0c
1225  0x00e8, 0x0037, 0x005f, 0x0038, 0x00e7, 0x0039, 0x00e0, 0x0030, // 0x10
1226  0x0029, 0x00b0, 0x003d, 0x002b, 0x0000, 0x0000, 0x0061, 0x0041, // 0x14
1227  0x0061, 0x0041, 0x007a, 0x005a, 0x0065, 0x0045, 0x0072, 0x0052, // 0x18
1228  0x0074, 0x0054, 0x0079, 0x0059, 0x0075, 0x0055, 0x0069, 0x0049, // 0x1c
1229  0x006f, 0x004f, 0x0070, 0x0050, 0xffff, 0xffff, 0x0024, 0x00a3, // 0x20
1230  0x0041, 0x0000, 0x0000, 0x0000, 0x0071, 0x0051, 0x0073, 0x0053, // 0x24
1231  0x0064, 0x0044, 0x0066, 0x0046, 0x0067, 0x0047, 0x0068, 0x0048, // 0x28
1232  0x006a, 0x004a, 0x006b, 0x004b, 0x006c, 0x004c, 0x006d, 0x004d, // 0x2c
1233  0x00f9, 0x0025, 0x00b2, 0x007e, 0x0000, 0x0000, 0x002a, 0x00b5, // 0x30
1234  0x0077, 0x0057, 0x0078, 0x0058, 0x0063, 0x0043, 0x0076, 0x0056, // 0x34
1235  0x0062, 0x0042, 0x006e, 0x004e, 0x002c, 0x003f, 0x003b, 0x002e, // 0x38
1236  0x003a, 0x002f, 0x0021, 0x00a7, 0xffff, 0xffff, 0xffff, 0xffff, // 0x3c
1237  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x40
1238  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x44
1239  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x48
1240  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x4c
1241  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x50
1242  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x54
1243  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x58
1244  0xffff, 0x003c, 0x0000, 0xffff, 0x003c, 0x003e, 0xffff, 0xffff, // 0x5c
1245  0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x60
1246  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, // 0x64
1247  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x68
1248  0xffff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x6c
1249  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x70
1250  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x74
1251  0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x00b1, 0x00b1, 0xffff, // 0x78
1252  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, // 0x7c
1253 };
1254 
1255 const MockLayoutData kLayoutUs{&kLayoutUs0};
1256 const MockLayoutData kLayoutRussian{&kLayoutRussian0, nullptr,
1257  &kLayoutRussian2};
1258 const MockLayoutData kLayoutFrench{&kLayoutFrench0, nullptr, nullptr,
1259  &kLayoutFrench3};
1260 
1261 } // namespace
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
fl_method_codec_encode_method_call
GBytes * fl_method_codec_encode_method_call(FlMethodCodec *self, const gchar *name, FlValue *args, GError **error)
Definition: fl_method_codec.cc:16
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1115
fl_value_set_string_take
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:650
fl_standard_method_codec_new
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
Definition: fl_standard_method_codec.cc:291
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE
#define FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(obj)
fl_keyboard_manager.h
priv
FlPixelBufferTexturePrivate * priv
Definition: fl_pixel_buffer_texture.cc:30
kGetKeyboardStateMethod
static constexpr char kGetKeyboardStateMethod[]
Definition: fl_keyboard_manager.cc:23
fl_value_new_bool
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
fl_json_message_codec_new
G_MODULE_EXPORT FlJsonMessageCodec * fl_json_message_codec_new()
Definition: fl_json_message_codec.cc:306
fl_json_message_codec.h
uint64_to_gpointer
gpointer uint64_to_gpointer(uint64_t number)
Definition: key_mapping.h:17
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_value_set_take
G_MODULE_EXPORT void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:618
fl_key_event_new_by_mock
static FlKeyEvent * fl_key_event_new_by_mock(guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, GdkModifierType state, gboolean is_modifier)
Definition: fl_key_channel_responder_test.cc:44
MATCHER_P
MATCHER_P(SuccessResponse, result, "")
Definition: fl_platform_plugin_test.cc:19
fl_method_response_get_result
G_MODULE_EXPORT FlValue * fl_method_response_get_result(FlMethodResponse *self, GError **error)
Definition: fl_method_response.cc:82
fl_value_new_int
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
fl_keyboard_manager_is_state_clear
gboolean fl_keyboard_manager_is_state_clear(FlKeyboardManager *self)
Definition: fl_keyboard_manager.cc:669
_FlKeyEvent
Definition: fl_key_event.h:22
state
AtkStateType state
Definition: fl_accessible_node.cc:10
fl_keyboard_manager_handle_event
gboolean fl_keyboard_manager_handle_event(FlKeyboardManager *self, FlKeyEvent *event)
Definition: fl_keyboard_manager.cc:638
FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE
#define FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(obj)
KeyboardLayoutNotifier
std::function< void()> KeyboardLayoutNotifier
Definition: fl_keyboard_view_delegate.h:17
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
key_mapping.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
FlBinaryMessengerMessageHandler
G_MODULE_EXPORT GObject typedef void(* FlBinaryMessengerMessageHandler)(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_binary_messenger.h:67
G_DECLARE_FINAL_TYPE
G_BEGIN_DECLS G_DECLARE_FINAL_TYPE(FlAccessibleTextField, fl_accessible_text_field, FL, ACCESSIBLE_TEXT_FIELD, FlAccessibleNode)
fl_method_codec_decode_response
FlMethodResponse * fl_method_codec_decode_response(FlMethodCodec *self, GBytes *message, GError **error)
Definition: fl_method_codec.cc:62
fl_method_codec.h
FL
FL
Definition: fl_binary_messenger.cc:27
fl_value_equal
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471
fl_standard_method_codec.h
fl_keyboard_manager_new
FlKeyboardManager * fl_keyboard_manager_new(FlBinaryMessenger *messenger, FlKeyboardViewDelegate *view_delegate)
Definition: fl_keyboard_manager.cc:585
EXPECT_KEY_EVENT
#define EXPECT_KEY_EVENT(RECORD, TYPE, PHYSICAL, LOGICAL, CHAR, SYNTHESIZED)
Definition: fl_keyboard_manager_test.cc:28
fl_keyboard_manager_sync_modifier_if_needed
void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager *self, guint state, double event_time)
Definition: fl_keyboard_manager.cc:675
fl_binary_messenger_private.h
fl_keyboard_manager_get_pressed_state
GHashTable * fl_keyboard_manager_get_pressed_state(FlKeyboardManager *self)
Definition: fl_keyboard_manager.cc:688
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
TEST
TEST(FlAccessibleNodeTest, BuildTree)
Definition: fl_accessible_node_test.cc:12
target
uint32_t * target
Definition: fl_texture_registrar_test.cc:40
fl_message_codec_encode_message
G_MODULE_EXPORT GBytes * fl_message_codec_encode_message(FlMessageCodec *self, FlValue *message, GError **error)
Definition: fl_message_codec.cc:17
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
fl_binary_messenger_send_response
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(FlBinaryMessenger *self, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
Definition: fl_binary_messenger.cc:430
fl_method_codec_private.h
VERIFY_DOWN
#define VERIFY_DOWN(OUT_LOGICAL, OUT_CHAR)
Definition: fl_keyboard_manager_test.cc:36
gpointer_to_uint64
uint64_t gpointer_to_uint64(gpointer pointer)
Definition: key_mapping.h:13
G_DEFINE_TYPE_WITH_CODE
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
FlKeyboardManager
typedefG_BEGIN_DECLS struct _FlKeyboardManager FlKeyboardManager
Definition: fl_key_responder.h:17