Flutter Linux Embedder
fl_binary_messenger_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 
5 // Included first as it collides with the X11 headers.
6 #include "gtest/gtest.h"
7 
8 #include <pthread.h>
9 #include <cstring>
10 
11 #include "flutter/shell/platform/embedder/embedder.h"
12 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
18 #include "flutter/shell/platform/linux/testing/fl_test.h"
19 #include "flutter/shell/platform/linux/testing/mock_binary_messenger_response_handle.h"
20 #include "flutter/shell/platform/linux/testing/mock_renderer.h"
21 
22 G_DECLARE_FINAL_TYPE(FlFakeBinaryMessenger,
23  fl_fake_binary_messenger,
24  FL,
25  FAKE_BINARY_MESSENGER,
26  GObject)
27 
28 struct _FlFakeBinaryMessenger {
29  GObject parent_instance;
30 
31  GMainLoop* loop;
32  GAsyncReadyCallback send_callback;
33  gpointer send_callback_user_data;
34  FlBinaryMessengerMessageHandler message_handler;
35  gpointer message_handler_user_data;
36 };
37 
39  FlBinaryMessengerInterface* iface);
40 
42  FlFakeBinaryMessenger,
43  fl_fake_binary_messenger,
44  G_TYPE_OBJECT,
45  G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
47 
48 static void fl_fake_binary_messenger_class_init(
49  FlFakeBinaryMessengerClass* klass) {}
50 
51 static gboolean send_message_cb(gpointer user_data) {
52  FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(user_data);
53 
54  const char* text = "Marco!";
55  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
56  self->message_handler(FL_BINARY_MESSENGER(self), "CHANNEL", message,
57  FL_BINARY_MESSENGER_RESPONSE_HANDLE(
58  fl_mock_binary_messenger_response_handle_new()),
59  self->message_handler_user_data);
60 
61  return FALSE;
62 }
63 
65  FlBinaryMessenger* messenger,
66  const gchar* channel,
68  gpointer user_data,
69  GDestroyNotify destroy_notify) {
70  FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(messenger);
71 
72  EXPECT_STREQ(channel, "CHANNEL");
73 
74  // Send message.
75  self->message_handler = handler;
76  self->message_handler_user_data = user_data;
77  g_idle_add(send_message_cb, messenger);
78 }
79 
80 static gboolean send_response(FlBinaryMessenger* messenger,
81  FlBinaryMessengerResponseHandle* response_handle,
82  GBytes* response,
83  GError** error) {
84  FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(messenger);
85 
86  EXPECT_TRUE(FL_IS_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle));
87 
88  g_autofree gchar* text =
89  g_strndup(static_cast<const gchar*>(g_bytes_get_data(response, nullptr)),
90  g_bytes_get_size(response));
91  EXPECT_STREQ(text, "Polo!");
92 
93  g_main_loop_quit(self->loop);
94 
95  return TRUE;
96 }
97 
98 static gboolean send_ready_cb(gpointer user_data) {
99  FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(user_data);
100 
101  self->send_callback(G_OBJECT(self), NULL, self->send_callback_user_data);
102 
103  return FALSE;
104 }
105 
106 static void send_on_channel(FlBinaryMessenger* messenger,
107  const gchar* channel,
108  GBytes* message,
109  GCancellable* cancellable,
110  GAsyncReadyCallback callback,
111  gpointer user_data) {
112  FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(messenger);
113 
114  EXPECT_STREQ(channel, "CHANNEL");
115  g_autofree gchar* text =
116  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
117  g_bytes_get_size(message));
118  EXPECT_STREQ(text, "Marco!");
119 
120  // Send response.
121  self->send_callback = callback;
122  self->send_callback_user_data = user_data;
123  g_idle_add(send_ready_cb, messenger);
124 }
125 
126 static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
127  GAsyncResult* result,
128  GError** error) {
129  const char* text = "Polo!";
130  return g_bytes_new(text, strlen(text));
131 }
132 
133 static void resize_channel(FlBinaryMessenger* messenger,
134  const gchar* channel,
135  int64_t new_size) {
136  // Fake implementation. Do nothing.
137 }
138 
139 static void set_warns_on_channel_overflow(FlBinaryMessenger* messenger,
140  const gchar* channel,
141  bool warns) {
142  // Fake implementation. Do nothing.
143 }
144 
146  FlBinaryMessengerInterface* iface) {
147  iface->set_message_handler_on_channel = set_message_handler_on_channel;
148  iface->send_response = send_response;
149  iface->send_on_channel = send_on_channel;
150  iface->send_on_channel_finish = send_on_channel_finish;
151  iface->resize_channel = resize_channel;
152  iface->set_warns_on_channel_overflow = set_warns_on_channel_overflow;
153 }
154 
155 static void fl_fake_binary_messenger_init(FlFakeBinaryMessenger* self) {}
156 
157 static FlBinaryMessenger* fl_fake_binary_messenger_new(GMainLoop* loop) {
158  FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(
159  g_object_new(fl_fake_binary_messenger_get_type(), NULL));
160  self->loop = loop;
161  return FL_BINARY_MESSENGER(self);
162 }
163 
164 // Called when the message response is received in the FakeMessengerSend test.
165 static void fake_response_cb(GObject* object,
166  GAsyncResult* result,
167  gpointer user_data) {
168  g_autoptr(GError) error = nullptr;
169  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
170  FL_BINARY_MESSENGER(object), result, &error);
171  EXPECT_NE(message, nullptr);
172  EXPECT_EQ(error, nullptr);
173 
174  g_autofree gchar* text =
175  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
176  g_bytes_get_size(message));
177  EXPECT_STREQ(text, "Polo!");
178 
179  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
180 }
181 
182 // Checks can make a fake messenger and send a message.
183 TEST(FlBinaryMessengerTest, FakeMessengerSend) {
184  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
185 
186  g_autoptr(FlBinaryMessenger) messenger = fl_fake_binary_messenger_new(loop);
187  EXPECT_TRUE(FL_IS_FAKE_BINARY_MESSENGER(messenger));
188 
189  const char* text = "Marco!";
190  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
191  fl_binary_messenger_send_on_channel(messenger, "CHANNEL", message, nullptr,
192  fake_response_cb, loop);
193 
194  // Blocks here until fake_response_cb is called.
195  g_main_loop_run(loop);
196 }
197 
198 // Called when a message is received in the FakeMessengerReceive test.
199 static void fake_message_cb(FlBinaryMessenger* messenger,
200  const gchar* channel,
201  GBytes* message,
202  FlBinaryMessengerResponseHandle* response_handle,
203  gpointer user_data) {
204  EXPECT_STREQ(channel, "CHANNEL");
205 
206  EXPECT_NE(message, nullptr);
207  g_autofree gchar* text =
208  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
209  g_bytes_get_size(message));
210  EXPECT_STREQ(text, "Marco!");
211 
212  const char* response_text = "Polo!";
213  g_autoptr(GBytes) response =
214  g_bytes_new(response_text, strlen(response_text));
215  g_autoptr(GError) error = nullptr;
216  EXPECT_TRUE(fl_binary_messenger_send_response(messenger, response_handle,
217  response, &error));
218  EXPECT_EQ(error, nullptr);
219 }
220 
221 // Checks can make a fake messenger and receive a message.
222 TEST(FlBinaryMessengerTest, FakeMessengerReceive) {
223  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
224 
225  g_autoptr(FlBinaryMessenger) messenger = fl_fake_binary_messenger_new(loop);
226  EXPECT_TRUE(FL_IS_FAKE_BINARY_MESSENGER(messenger));
227 
229  messenger, "CHANNEL", fake_message_cb, nullptr, nullptr);
230 
231  // Blocks here until response is received in fake messenger.
232  g_main_loop_run(loop);
233 }
234 
235 // Checks sending nullptr for a message works.
236 TEST(FlBinaryMessengerTest, SendNullptrMessage) {
237  g_autoptr(FlEngine) engine = make_mock_engine();
238  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
239  fl_binary_messenger_send_on_channel(messenger, "test/echo", nullptr, nullptr,
240  nullptr, nullptr);
241 }
242 
243 // Checks sending a zero length message works.
244 TEST(FlBinaryMessengerTest, SendEmptyMessage) {
245  g_autoptr(FlEngine) engine = make_mock_engine();
246  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
247  g_autoptr(GBytes) message = g_bytes_new(nullptr, 0);
248  fl_binary_messenger_send_on_channel(messenger, "test/echo", message, nullptr,
249  nullptr, nullptr);
250 }
251 
252 // Called when the message response is received in the SendMessage test.
253 static void echo_response_cb(GObject* object,
254  GAsyncResult* result,
255  gpointer user_data) {
256  g_autoptr(GError) error = nullptr;
257  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
258  FL_BINARY_MESSENGER(object), result, &error);
259  EXPECT_NE(message, nullptr);
260  EXPECT_EQ(error, nullptr);
261 
262  g_autofree gchar* text =
263  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
264  g_bytes_get_size(message));
265  EXPECT_STREQ(text, "Hello World!");
266 
267  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
268 }
269 
270 // Checks sending a message works.
271 TEST(FlBinaryMessengerTest, SendMessage) {
272  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
273 
274  g_autoptr(FlEngine) engine = make_mock_engine();
275  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
276  const char* text = "Hello World!";
277  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
278  fl_binary_messenger_send_on_channel(messenger, "test/echo", message, nullptr,
279  echo_response_cb, loop);
280 
281  // Blocks here until echo_response_cb is called.
282  g_main_loop_run(loop);
283 }
284 
285 // Called when the message response is received in the NullptrResponse test.
286 static void nullptr_response_cb(GObject* object,
287  GAsyncResult* result,
288  gpointer user_data) {
289  g_autoptr(GError) error = nullptr;
290  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
291  FL_BINARY_MESSENGER(object), result, &error);
292  EXPECT_NE(message, nullptr);
293  EXPECT_EQ(error, nullptr);
294 
295  EXPECT_EQ(g_bytes_get_size(message), static_cast<gsize>(0));
296 
297  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
298 }
299 
300 // Checks the engine returning a nullptr message work.
301 TEST(FlBinaryMessengerTest, NullptrResponse) {
302  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
303 
304  g_autoptr(FlEngine) engine = make_mock_engine();
305  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
306  const char* text = "Hello World!";
307  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
308  fl_binary_messenger_send_on_channel(messenger, "test/nullptr-response",
309  message, nullptr, nullptr_response_cb,
310  loop);
311 
312  // Blocks here until nullptr_response_cb is called.
313  g_main_loop_run(loop);
314 }
315 
316 // Called when the message response is received in the SendFailure test.
317 static void failure_response_cb(GObject* object,
318  GAsyncResult* result,
319  gpointer user_data) {
320  g_autoptr(GError) error = nullptr;
321  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
322  FL_BINARY_MESSENGER(object), result, &error);
323  EXPECT_EQ(message, nullptr);
324  EXPECT_NE(error, nullptr);
325 
326  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
327 }
328 
329 // Checks the engine reporting a send failure is handled.
330 TEST(FlBinaryMessengerTest, SendFailure) {
331  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
332 
333  g_autoptr(FlEngine) engine = make_mock_engine();
334  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
335  fl_binary_messenger_send_on_channel(messenger, "test/failure", nullptr,
336  nullptr, failure_response_cb, loop);
337 
338  // Blocks here until failure_response_cb is called.
339  g_main_loop_run(loop);
340 }
341 
342 // Called when a message is received from the engine in the ReceiveMessage test.
343 static void message_cb(FlBinaryMessenger* messenger,
344  const gchar* channel,
345  GBytes* message,
346  FlBinaryMessengerResponseHandle* response_handle,
347  gpointer user_data) {
348  EXPECT_NE(message, nullptr);
349  g_autofree gchar* text =
350  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
351  g_bytes_get_size(message));
352  EXPECT_STREQ(text, "Marco!");
353 
354  const char* response_text = "Polo!";
355  g_autoptr(GBytes) response =
356  g_bytes_new(response_text, strlen(response_text));
357  g_autoptr(GError) error = nullptr;
358  EXPECT_TRUE(fl_binary_messenger_send_response(messenger, response_handle,
359  response, &error));
360  EXPECT_EQ(error, nullptr);
361 }
362 
363 // Called when a the test engine notifies us what response we sent in the
364 // ReceiveMessage test.
365 static void response_cb(FlBinaryMessenger* messenger,
366  const gchar* channel,
367  GBytes* message,
368  FlBinaryMessengerResponseHandle* response_handle,
369  gpointer user_data) {
370  EXPECT_NE(message, nullptr);
371  g_autofree gchar* text =
372  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
373  g_bytes_get_size(message));
374  EXPECT_STREQ(text, "Polo!");
375 
376  fl_binary_messenger_send_response(messenger, response_handle, nullptr,
377  nullptr);
378 
379  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
380 }
381 
382 // Checks the shell able to receive and respond to messages from the engine.
383 TEST(FlBinaryMessengerTest, ReceiveMessage) {
384  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
385 
386  g_autoptr(FlEngine) engine = make_mock_engine();
387  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
388 
389  // Listen for messages from the engine.
391  messenger, "test/messages", message_cb, nullptr, nullptr);
392 
393  // Listen for response from the engine.
395  messenger, "test/responses", response_cb, loop, nullptr);
396 
397  // Trigger the engine to send a message.
398  const char* text = "Marco!";
399  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
400  fl_binary_messenger_send_on_channel(messenger, "test/send-message", message,
401  nullptr, nullptr, nullptr);
402 
403  // Blocks here until response_cb is called.
404  g_main_loop_run(loop);
405 }
406 
407 // MOCK_ENGINE_PROC is leaky by design.
408 // NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
409 
410 // Checks if the 'resize' command is sent and is well-formed.
411 TEST(FlBinaryMessengerTest, ResizeChannel) {
412  g_autoptr(FlEngine) engine = make_mock_engine();
413  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
414 
415  bool called = false;
416 
417  FlutterEngineSendPlatformMessageFnPtr old_handler =
418  embedder_api->SendPlatformMessage;
419  embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
420  SendPlatformMessage,
421  ([&called, old_handler](auto engine,
422  const FlutterPlatformMessage* message) {
423  // Expect to receive a message on the "control" channel.
424  if (strcmp(message->channel, "dev.flutter/channel-buffers") != 0) {
425  return old_handler(engine, message);
426  }
427 
428  called = true;
429 
430  // The expected content was created from the following Dart code:
431  // MethodCall call = MethodCall('resize', ['flutter/test',3]);
432  // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
433  const int expected_message_size = 29;
434  EXPECT_EQ(message->message_size,
435  static_cast<size_t>(expected_message_size));
436  int expected[expected_message_size] = {
437  7, 6, 114, 101, 115, 105, 122, 101, 12, 2,
438  7, 12, 102, 108, 117, 116, 116, 101, 114, 47,
439  116, 101, 115, 116, 3, 3, 0, 0, 0};
440  for (size_t i = 0; i < expected_message_size; i++) {
441  EXPECT_EQ(message->message[i], expected[i]);
442  }
443 
444  return kSuccess;
445  }));
446 
447  g_autoptr(GError) error = nullptr;
448  EXPECT_TRUE(fl_engine_start(engine, &error));
449  EXPECT_EQ(error, nullptr);
450 
451  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
452  fl_binary_messenger_resize_channel(messenger, "flutter/test", 3);
453 
454  EXPECT_TRUE(called);
455 }
456 
457 // Checks if the 'overflow' command is sent and is well-formed.
458 TEST(FlBinaryMessengerTest, WarnsOnOverflowChannel) {
459  g_autoptr(FlEngine) engine = make_mock_engine();
460  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
461 
462  bool called = false;
463 
464  FlutterEngineSendPlatformMessageFnPtr old_handler =
465  embedder_api->SendPlatformMessage;
466  embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
467  SendPlatformMessage,
468  ([&called, old_handler](auto engine,
469  const FlutterPlatformMessage* message) {
470  // Expect to receive a message on the "control" channel.
471  if (strcmp(message->channel, "dev.flutter/channel-buffers") != 0) {
472  return old_handler(engine, message);
473  }
474 
475  called = true;
476 
477  // The expected content was created from the following Dart code:
478  // MethodCall call = MethodCall('overflow',['flutter/test', true]);
479  // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
480  const int expected_message_size = 27;
481  EXPECT_EQ(message->message_size,
482  static_cast<size_t>(expected_message_size));
483  int expected[expected_message_size] = {
484  7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12,
485  102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1};
486  for (size_t i = 0; i < expected_message_size; i++) {
487  EXPECT_EQ(message->message[i], expected[i]);
488  }
489 
490  return kSuccess;
491  }));
492 
493  g_autoptr(GError) error = nullptr;
494  EXPECT_TRUE(fl_engine_start(engine, &error));
495  EXPECT_EQ(error, nullptr);
496 
497  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
498  fl_binary_messenger_set_warns_on_channel_overflow(messenger, "flutter/test",
499  false);
500 
501  EXPECT_TRUE(called);
502 }
503 
504 static gboolean quit_main_loop_cb(gpointer user_data) {
505  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
506  return FALSE;
507 }
508 
509 // Checks if error returned when invoking a command on the control channel
510 // are handled.
511 TEST(FlBinaryMessengerTest, ControlChannelErrorResponse) {
512  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
513  g_autoptr(FlEngine) engine = make_mock_engine();
514  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
515 
516  g_autoptr(GError) error = nullptr;
517  EXPECT_TRUE(fl_engine_start(engine, &error));
518  EXPECT_EQ(error, nullptr);
519 
520  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
521 
522  bool called = false;
523 
524  FlutterEngineSendPlatformMessageFnPtr old_handler =
525  embedder_api->SendPlatformMessage;
526  embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
527  SendPlatformMessage,
528  ([&called, old_handler, loop](auto engine,
529  const FlutterPlatformMessage* message) {
530  // Expect to receive a message on the "control" channel.
531  if (strcmp(message->channel, "dev.flutter/channel-buffers") != 0) {
532  return old_handler(engine, message);
533  }
534 
535  called = true;
536 
537  // Register a callback to quit the main loop when binary messenger work
538  // ends.
539  g_idle_add(quit_main_loop_cb, loop);
540 
541  // Simulates an internal error.
542  return kInvalidArguments;
543  }));
544 
545  fl_binary_messenger_set_warns_on_channel_overflow(messenger, "flutter/test",
546  false);
547 
548  EXPECT_TRUE(called);
549 
550  // Blocks here until quit_main_loop_cb is called.
551  g_main_loop_run(loop);
552 }
553 
554 // NOLINTEND(clang-analyzer-core.StackAddressEscape)
555 
557  FlBinaryMessenger* messenger;
558  FlBinaryMessengerResponseHandle* response_handle;
559  GMainLoop* loop;
560 };
561 
565  GMainLoop* loop = info->loop;
566 
567  g_object_unref(info->messenger);
568  g_object_unref(info->response_handle);
569  free(info);
570 
571  g_main_loop_quit(static_cast<GMainLoop*>(loop));
572 
573  return G_SOURCE_REMOVE;
574 }
575 
579 
581  nullptr, nullptr);
582 
584 
585  return nullptr;
586 }
587 
589  FlBinaryMessenger* messenger,
590  const gchar* channel,
591  GBytes* message,
592  FlBinaryMessengerResponseHandle* response_handle,
593  gpointer user_data) {
594  EXPECT_NE(message, nullptr);
595  pthread_t thread;
597  static_cast<RespondsOnBackgroundThreadInfo*>(
598  malloc(sizeof(RespondsOnBackgroundThreadInfo)));
599  info->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));
600  info->response_handle =
601  FL_BINARY_MESSENGER_RESPONSE_HANDLE(g_object_ref(response_handle));
602  info->loop = static_cast<GMainLoop*>(user_data);
603  EXPECT_EQ(0,
604  pthread_create(&thread, nullptr, &response_from_thread_main, info));
605 }
606 
607 TEST(FlBinaryMessengerTest, RespondOnBackgroundThread) {
608  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
609 
610  g_autoptr(FlEngine) engine = make_mock_engine();
611  g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
612 
613  // Listen for messages from the engine.
615  messenger, "test/messages", message_cb, nullptr, nullptr);
616 
617  // Listen for response from the engine.
619  messenger, "test/responses", response_from_thread_cb, loop, nullptr);
620 
621  // Trigger the engine to send a message.
622  const char* text = "Marco!";
623  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
624  fl_binary_messenger_send_on_channel(messenger, "test/send-message", message,
625  nullptr, nullptr, nullptr);
626 
627  // Blocks here until response_cb is called.
628  g_main_loop_run(loop);
629 }
630 
631 static void kill_handler_notify_cb(gpointer was_called) {
632  *static_cast<gboolean*>(was_called) = TRUE;
633 }
634 
635 TEST(FlBinaryMessengerTest, DeletingEngineClearsHandlers) {
636  FlEngine* engine = make_mock_engine();
637  FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(engine);
638  gboolean was_killed = FALSE;
639 
640  // Listen for messages from the engine.
641  fl_binary_messenger_set_message_handler_on_channel(messenger, "test/messages",
642  message_cb, &was_killed,
644 
645  g_clear_object(&engine);
646 
647  ASSERT_TRUE(was_killed);
648 }
G_DECLARE_FINAL_TYPE
G_DECLARE_FINAL_TYPE(FlFakeBinaryMessenger, fl_fake_binary_messenger, FL, FAKE_BINARY_MESSENGER, GObject) struct _FlFakeBinaryMessenger
Definition: fl_binary_messenger_test.cc:22
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(FlFakeBinaryMessenger, fl_fake_binary_messenger, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(), fl_fake_binary_messenger_iface_init)) static void fl_fake_binary_messenger_class_init(FlFakeBinaryMessengerClass *klass)
Definition: fl_binary_messenger_test.cc:41
response_from_thread_cb
static void response_from_thread_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_binary_messenger_test.cc:588
fl_engine_get_embedder_api
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:637
send_ready_cb
static gboolean send_ready_cb(gpointer user_data)
Definition: fl_binary_messenger_test.cc:98
kill_handler_notify_cb
static void kill_handler_notify_cb(gpointer was_called)
Definition: fl_binary_messenger_test.cc:631
RespondsOnBackgroundThreadInfo::messenger
FlBinaryMessenger * messenger
Definition: fl_binary_messenger_test.cc:557
echo_response_cb
static void echo_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_binary_messenger_test.cc:253
fl_fake_binary_messenger_new
static FlBinaryMessenger * fl_fake_binary_messenger_new(GMainLoop *loop)
Definition: fl_binary_messenger_test.cc:157
fl_method_channel.h
i
int i
Definition: fl_socket_accessible.cc:18
cleanup_responds_on_background_thread_info
static gboolean cleanup_responds_on_background_thread_info(gpointer user_data)
Definition: fl_binary_messenger_test.cc:562
response_cb
static void response_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_binary_messenger_test.cc:365
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_engine_get_binary_messenger
G_MODULE_EXPORT FlBinaryMessenger * fl_engine_get_binary_messenger(FlEngine *self)
Definition: fl_engine.cc:995
set_warns_on_channel_overflow
static void set_warns_on_channel_overflow(FlBinaryMessenger *messenger, const gchar *channel, bool warns)
Definition: fl_binary_messenger_test.cc:139
fl_binary_messenger_new
FlBinaryMessenger * fl_binary_messenger_new(FlEngine *engine)
Definition: fl_binary_messenger.cc:399
quit_main_loop_cb
static gboolean quit_main_loop_cb(gpointer user_data)
Definition: fl_binary_messenger_test.cc:504
make_mock_engine
static FlEngine * make_mock_engine()
Definition: fl_event_channel_test.cc:24
response_from_thread_main
static void * response_from_thread_main(void *user_data)
Definition: fl_binary_messenger_test.cc:576
nullptr_response_cb
static void nullptr_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_binary_messenger_test.cc:286
send_response
static gboolean send_response(FlBinaryMessenger *messenger, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
Definition: fl_binary_messenger_test.cc:80
RespondsOnBackgroundThreadInfo
Definition: fl_binary_messenger_test.cc:556
fl_binary_messenger_set_warns_on_channel_overflow
G_MODULE_EXPORT void fl_binary_messenger_set_warns_on_channel_overflow(FlBinaryMessenger *self, const gchar *channel, bool warns)
Definition: fl_binary_messenger.cc:476
fl_binary_messenger.h
send_on_channel
static void send_on_channel(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_binary_messenger_test.cc:106
fake_response_cb
static void fake_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_binary_messenger_test.cc:165
flutter::internal::ResizeChannel
void ResizeChannel(BinaryMessenger *messenger, std::string name, int new_size)
Definition: core_implementations.cc:181
fl_engine_private.h
fl_binary_messenger_set_message_handler_on_channel
G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(FlBinaryMessenger *self, const gchar *channel, FlBinaryMessengerMessageHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_binary_messenger.cc:416
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
RespondsOnBackgroundThreadInfo::response_handle
FlBinaryMessengerResponseHandle * response_handle
Definition: fl_binary_messenger_test.cc:558
fl_binary_messenger_send_on_channel_finish
G_MODULE_EXPORT GBytes * fl_binary_messenger_send_on_channel_finish(FlBinaryMessenger *self, GAsyncResult *result, GError **error)
Definition: fl_binary_messenger.cc:457
FL
FL
Definition: fl_binary_messenger.cc:27
failure_response_cb
static void failure_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_binary_messenger_test.cc:317
fl_standard_method_codec.h
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
fl_binary_messenger_private.h
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_fake_binary_messenger_iface_init
static void fl_fake_binary_messenger_iface_init(FlBinaryMessengerInterface *iface)
Definition: fl_binary_messenger_test.cc:145
message_cb
static void message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_binary_messenger_test.cc:343
RespondsOnBackgroundThreadInfo::loop
GMainLoop * loop
Definition: fl_binary_messenger_test.cc:559
set_message_handler_on_channel
static void set_message_handler_on_channel(FlBinaryMessenger *messenger, const gchar *channel, FlBinaryMessengerMessageHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_binary_messenger_test.cc:64
fl_engine_start
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:509
fake_message_cb
static void fake_message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_binary_messenger_test.cc:199
resize_channel
static void resize_channel(FlBinaryMessenger *messenger, const gchar *channel, int64_t new_size)
Definition: fl_binary_messenger_test.cc:133
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
fl_binary_messenger_resize_channel
G_MODULE_EXPORT void fl_binary_messenger_resize_channel(FlBinaryMessenger *self, const gchar *channel, int64_t new_size)
Definition: fl_binary_messenger.cc:467
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
TEST
TEST(FlBinaryMessengerTest, FakeMessengerSend)
Definition: fl_binary_messenger_test.cc:183
fl_fake_binary_messenger_init
static void fl_fake_binary_messenger_init(FlFakeBinaryMessenger *self)
Definition: fl_binary_messenger_test.cc:155
send_message_cb
static gboolean send_message_cb(gpointer user_data)
Definition: fl_binary_messenger_test.cc:51
fl_binary_messenger_send_on_channel
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(FlBinaryMessenger *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_binary_messenger.cc:443
send_on_channel_finish
static GBytes * send_on_channel_finish(FlBinaryMessenger *messenger, GAsyncResult *result, GError **error)
Definition: fl_binary_messenger_test.cc:126