Flutter Engine
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 <cstring>
9 
10 #include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
11 #include "flutter/shell/platform/linux/fl_engine_private.h"
12 #include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
13 #include "flutter/shell/platform/linux/testing/mock_renderer.h"
14 
15 // Creates a mock engine that responds to platform messages.
16 static FlEngine* make_mock_engine() {
17  g_autoptr(FlDartProject) project = fl_dart_project_new();
18  g_autoptr(FlMockRenderer) renderer = fl_mock_renderer_new();
19  g_autoptr(FlEngine) engine = fl_engine_new(project, FL_RENDERER(renderer));
20  g_autoptr(GError) engine_error = nullptr;
21  EXPECT_TRUE(fl_engine_start(engine, &engine_error));
22  EXPECT_EQ(engine_error, nullptr);
23 
24  return static_cast<FlEngine*>(g_object_ref(engine));
25 }
26 
27 // Checks sending nullptr for a message works.
28 TEST(FlBinaryMessengerTest, SendNullptrMessage) {
29  g_autoptr(FlEngine) engine = make_mock_engine();
30  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
31  fl_binary_messenger_send_on_channel(messenger, "test/echo", nullptr, nullptr,
32  nullptr, nullptr);
33 }
34 
35 // Checks sending a zero length message works.
36 TEST(FlBinaryMessengerTest, SendEmptyMessage) {
37  g_autoptr(FlEngine) engine = make_mock_engine();
38  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
39  g_autoptr(GBytes) message = g_bytes_new(nullptr, 0);
40  fl_binary_messenger_send_on_channel(messenger, "test/echo", message, nullptr,
41  nullptr, nullptr);
42 }
43 
44 // Called when the message response is received in the SendMessage test.
45 static void echo_response_cb(GObject* object,
46  GAsyncResult* result,
47  gpointer user_data) {
48  g_autoptr(GError) error = nullptr;
49  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
50  FL_BINARY_MESSENGER(object), result, &error);
51  EXPECT_NE(message, nullptr);
52  EXPECT_EQ(error, nullptr);
53 
54  g_autofree gchar* text =
55  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
56  g_bytes_get_size(message));
57  EXPECT_STREQ(text, "Hello World!");
58 
59  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
60 }
61 
62 // Checks sending a message works.
63 TEST(FlBinaryMessengerTest, SendMessage) {
64  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
65 
66  g_autoptr(FlEngine) engine = make_mock_engine();
67  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
68  const char* text = "Hello World!";
69  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
70  fl_binary_messenger_send_on_channel(messenger, "test/echo", message, nullptr,
71  echo_response_cb, loop);
72 
73  // Blocks here until echo_response_cb is called.
74  g_main_loop_run(loop);
75 }
76 
77 // Called when the message response is received in the NullptrResponse test.
78 static void nullptr_response_cb(GObject* object,
79  GAsyncResult* result,
80  gpointer user_data) {
81  g_autoptr(GError) error = nullptr;
82  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
83  FL_BINARY_MESSENGER(object), result, &error);
84  EXPECT_NE(message, nullptr);
85  EXPECT_EQ(error, nullptr);
86 
87  EXPECT_EQ(g_bytes_get_size(message), static_cast<gsize>(0));
88 
89  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
90 }
91 
92 // Checks the engine returning a nullptr message work.
93 TEST(FlBinaryMessengerTest, NullptrResponse) {
94  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
95 
96  g_autoptr(FlEngine) engine = make_mock_engine();
97  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
98  const char* text = "Hello World!";
99  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
100  fl_binary_messenger_send_on_channel(messenger, "test/nullptr-response",
101  message, nullptr, nullptr_response_cb,
102  loop);
103 
104  // Blocks here until nullptr_response_cb is called.
105  g_main_loop_run(loop);
106 }
107 
108 // Called when the message response is received in the SendFailure test.
109 static void failure_response_cb(GObject* object,
110  GAsyncResult* result,
111  gpointer user_data) {
112  g_autoptr(GError) error = nullptr;
113  g_autoptr(GBytes) message = fl_binary_messenger_send_on_channel_finish(
114  FL_BINARY_MESSENGER(object), result, &error);
115  EXPECT_EQ(message, nullptr);
116  EXPECT_NE(error, nullptr);
117 
118  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
119 }
120 
121 // Checks the engine reporting a send failure is handled.
122 TEST(FlBinaryMessengerTest, SendFailure) {
123  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
124 
125  g_autoptr(FlEngine) engine = make_mock_engine();
126  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
127  fl_binary_messenger_send_on_channel(messenger, "test/failure", nullptr,
128  nullptr, failure_response_cb, loop);
129 
130  // Blocks here until failure_response_cb is called.
131  g_main_loop_run(loop);
132 }
133 
134 // Called when a message is received from the engine in the ReceiveMessage test.
135 static void message_cb(FlBinaryMessenger* messenger,
136  const gchar* channel,
137  GBytes* message,
138  FlBinaryMessengerResponseHandle* response_handle,
139  gpointer user_data) {
140  EXPECT_NE(message, nullptr);
141  g_autofree gchar* text =
142  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
143  g_bytes_get_size(message));
144  EXPECT_STREQ(text, "Marco!");
145 
146  const char* response_text = "Polo!";
147  g_autoptr(GBytes) response =
148  g_bytes_new(response_text, strlen(response_text));
149  g_autoptr(GError) error = nullptr;
150  EXPECT_TRUE(fl_binary_messenger_send_response(messenger, response_handle,
151  response, &error));
152  EXPECT_EQ(error, nullptr);
153 }
154 
155 // Called when a the test engine notifies us what response we sent in the
156 // ReceiveMessage test.
157 static void response_cb(FlBinaryMessenger* messenger,
158  const gchar* channel,
159  GBytes* message,
160  FlBinaryMessengerResponseHandle* response_handle,
161  gpointer user_data) {
162  EXPECT_NE(message, nullptr);
163  g_autofree gchar* text =
164  g_strndup(static_cast<const gchar*>(g_bytes_get_data(message, nullptr)),
165  g_bytes_get_size(message));
166  EXPECT_STREQ(text, "Polo!");
167 
168  fl_binary_messenger_send_response(messenger, response_handle, nullptr,
169  nullptr);
170 
171  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
172 }
173 
174 // Checks the shell able to receive and respond to messages from the engine.
175 TEST(FlBinaryMessengerTest, ReceiveMessage) {
176  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
177 
178  g_autoptr(FlEngine) engine = make_mock_engine();
179  FlBinaryMessenger* messenger = fl_binary_messenger_new(engine);
180 
181  // Listen for messages from the engine.
183  messenger, "test/messages", message_cb, nullptr, nullptr);
184 
185  // Listen for response from the engine.
187  messenger, "test/responses", response_cb, loop, nullptr);
188 
189  // Triggger the engine to send a message.
190  const char* text = "Marco!";
191  g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
192  fl_binary_messenger_send_on_channel(messenger, "test/send-message", message,
193  nullptr, nullptr, nullptr);
194 
195  // Blocks here until response_cb is called.
196  g_main_loop_run(loop);
197 }
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)
FlMockRenderer * fl_mock_renderer_new()
FlMethodResponse GError ** error
static void response_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
G_MODULE_EXPORT GBytes * fl_binary_messenger_send_on_channel_finish(FlBinaryMessenger *self, GAsyncResult *result, GError **error)
static void nullptr_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
static void echo_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(FlBinaryMessenger *self, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
G_BEGIN_DECLS FlValue gpointer user_data
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:352
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(FlBinaryMessenger *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
static void message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
FlEngine * fl_engine_new(FlDartProject *project, FlRenderer *renderer)
Definition: fl_engine.cc:337
static FlEngine * make_mock_engine()
TEST(FlBinaryMessengerTest, SendNullptrMessage)
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
static void failure_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
FlBinaryMessenger * fl_binary_messenger_new(FlEngine *engine)