| Flutter Linux Embedder |

fl_basic_message_channel.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 #include "flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h"
6
7 #include <gmodule.h>
8
9 struct _FlBasicMessageChannel {
10 GObject parent_instance;
11
12 // Messenger to communicate on.
13 FlBinaryMessenger* messenger;
14
15 // TRUE if the channel has been closed.
16 gboolean channel_closed;
17
18 // Channel name.
19 gchar* name;
20
21 // Codec to en/decode messages.
22 FlMessageCodec* codec;
23
24 // Function called when a message is received.
25 FlBasicMessageChannelMessageHandler message_handler;
26 gpointer message_handler_data;
27 GDestroyNotify message_handler_destroy_notify;
28 };
29
30 struct _FlBasicMessageChannelResponseHandle {
31 GObject parent_instance;
32
33 FlBinaryMessengerResponseHandle* response_handle;
34 };
35
36 G_DEFINE_TYPE(FlBasicMessageChannel, fl_basic_message_channel, G_TYPE_OBJECT)
37 G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle,
38 fl_basic_message_channel_response_handle,
39 G_TYPE_OBJECT)
40
41 static void fl_basic_message_channel_response_handle_dispose(GObject* object) {
42 FlBasicMessageChannelResponseHandle* self =
43 FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(object);
44
45 g_clear_object(&self->response_handle);
46
47 G_OBJECT_CLASS(fl_basic_message_channel_response_handle_parent_class)
48 ->dispose(object);
49 }
50
51 static void fl_basic_message_channel_response_handle_class_init(
52 FlBasicMessageChannelResponseHandleClass* klass) {
53 G_OBJECT_CLASS(klass)->dispose =
54 fl_basic_message_channel_response_handle_dispose;
55 }
56
57 static void fl_basic_message_channel_response_handle_init(
58 FlBasicMessageChannelResponseHandle* self) {}
59
60 static FlBasicMessageChannelResponseHandle*
61 fl_basic_message_channel_response_handle_new(
62 FlBinaryMessengerResponseHandle* response_handle) {
63 FlBasicMessageChannelResponseHandle* self =
64 FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(g_object_new(
65 fl_basic_message_channel_response_handle_get_type(), nullptr));
66
67 self->response_handle =
68 FL_BINARY_MESSENGER_RESPONSE_HANDLE(g_object_ref(response_handle));
69
70 return self;
71 }
72
73 // Called when a binary message is received on this channel.
74 static void message_cb(FlBinaryMessenger* messenger,
75 const gchar* channel,
76 GBytes* message,
77 FlBinaryMessengerResponseHandle* response_handle,
78 gpointer user_data) {
79 FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(user_data);
80
81 if (self->message_handler == nullptr) {
82 fl_binary_messenger_send_response(messenger, response_handle, nullptr,
83 nullptr);
84 return;
85 }
86
87 g_autoptr(GError) error = nullptr;
88 g_autoptr(FlValue) message_value =
89 fl_message_codec_decode_message(self->codec, message, &error);
90 if (message_value == nullptr) {
91 g_warning("Failed to decode message: %s", error->message);
92 fl_binary_messenger_send_response(messenger, response_handle, nullptr,
93 nullptr);
94 }
95
96 g_autoptr(FlBasicMessageChannelResponseHandle) handle =
97 fl_basic_message_channel_response_handle_new(response_handle);
98 self->message_handler(self, message_value, handle,
99 self->message_handler_data);
100 }
101
102 // Called when a response is received to a sent message.
103 static void message_response_cb(GObject* object,
104 GAsyncResult* result,
105 gpointer user_data) {
106 g_autoptr(GTask) task = G_TASK(user_data);
107 g_task_return_pointer(task, g_object_ref(result), g_object_unref);
108 }
109
110 // Called when the channel handler is closed.
111 static void channel_closed_cb(gpointer user_data) {
112 g_autoptr(FlBasicMessageChannel) self = FL_BASIC_MESSAGE_CHANNEL(user_data);
113
114 self->channel_closed = TRUE;
115
116 // Disconnect handler.
117 if (self->message_handler_destroy_notify != nullptr) {
118 self->message_handler_destroy_notify(self->message_handler_data);
119 }
120 self->message_handler = nullptr;
121 self->message_handler_data = nullptr;
122 self->message_handler_destroy_notify = nullptr;
123 }
124
125 static void fl_basic_message_channel_dispose(GObject* object) {
126 FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(object);
127
128 if (self->messenger != nullptr) {
129 fl_binary_messenger_set_message_handler_on_channel(
130 self->messenger, self->name, nullptr, nullptr, nullptr);
131 }
132
133 g_clear_object(&self->messenger);
134 g_clear_pointer(&self->name, g_free);
135 g_clear_object(&self->codec);
136
137 if (self->message_handler_destroy_notify != nullptr) {
138 self->message_handler_destroy_notify(self->message_handler_data);
139 }
140 self->message_handler = nullptr;
141 self->message_handler_data = nullptr;
142 self->message_handler_destroy_notify = nullptr;
143
144 G_OBJECT_CLASS(fl_basic_message_channel_parent_class)->dispose(object);
145 }
146
147 static void fl_basic_message_channel_class_init(
148 FlBasicMessageChannelClass* klass) {
149 G_OBJECT_CLASS(klass)->dispose = fl_basic_message_channel_dispose;
150 }
151
152 static void fl_basic_message_channel_init(FlBasicMessageChannel* self) {}
153
154 G_MODULE_EXPORT FlBasicMessageChannel* fl_basic_message_channel_new(
155 FlBinaryMessenger* messenger,
156 const gchar* name,
157 FlMessageCodec* codec) {
158 g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
159 g_return_val_if_fail(name != nullptr, nullptr);
160 g_return_val_if_fail(FL_IS_MESSAGE_CODEC(codec), nullptr);
161
162 FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(
163 g_object_new(fl_basic_message_channel_get_type(), nullptr));
164
165 self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));
166 self->name = g_strdup(name);
167 self->codec = FL_MESSAGE_CODEC(g_object_ref(codec));
168
169 fl_binary_messenger_set_message_handler_on_channel(
170 self->messenger, self->name, message_cb, g_object_ref(self),
171 channel_closed_cb);
172
173 return self;
174 }
175
176 G_MODULE_EXPORT void fl_basic_message_channel_set_message_handler(
177 FlBasicMessageChannel* self,
178 FlBasicMessageChannelMessageHandler handler,
179 gpointer user_data,
180 GDestroyNotify destroy_notify) {
181 g_return_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self));
182
183 // Don't set handler if channel closed.
184 if (self->channel_closed) {
185 if (handler != nullptr) {
186 g_warning(
187 "Attempted to set message handler on a closed FlBasicMessageChannel");
188 }
189 if (destroy_notify != nullptr) {
190 destroy_notify(user_data);
191 }
192 return;
193 }
194
195 if (self->message_handler_destroy_notify != nullptr) {
196 self->message_handler_destroy_notify(self->message_handler_data);
197 }
198
199 self->message_handler = handler;
200 self->message_handler_data = user_data;
201 self->message_handler_destroy_notify = destroy_notify;
202 }
203
204 G_MODULE_EXPORT gboolean fl_basic_message_channel_respond(
205 FlBasicMessageChannel* self,
206 FlBasicMessageChannelResponseHandle* response_handle,
207 FlValue* message,
208 GError** error) {
209 g_return_val_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self), FALSE);
210 g_return_val_if_fail(response_handle != nullptr, FALSE);
211 g_return_val_if_fail(response_handle->response_handle != nullptr, FALSE);
212
213 g_autoptr(GBytes) data =
214 fl_message_codec_encode_message(self->codec, message, error);
215 if (data == nullptr) {
216 return FALSE;
217 }
218
219 gboolean result = fl_binary_messenger_send_response(
220 self->messenger, response_handle->response_handle, data, error);
221 g_clear_object(&response_handle->response_handle);
222
223 return result;
224 }
225
226 G_MODULE_EXPORT void fl_basic_message_channel_send(FlBasicMessageChannel* self,
227 FlValue* message,
228 GCancellable* cancellable,
229 GAsyncReadyCallback callback,
230 gpointer user_data) {
231 g_return_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self));
232
233 g_autoptr(GTask) task =
234 callback != nullptr ? g_task_new(self, cancellable, callback, user_data)
235 : nullptr;
236
237 g_autoptr(GError) error = nullptr;
238 g_autoptr(GBytes) data =
239 fl_message_codec_encode_message(self->codec, message, &error);
240 if (data == nullptr) {
241 if (task != nullptr) {
242 g_task_return_error(task, g_error_copy(error));
243 }
244 return;
245 }
246
247 fl_binary_messenger_send_on_channel(
248 self->messenger, self->name, data, cancellable,
249 callback != nullptr ? message_response_cb : nullptr,
250 g_steal_pointer(&task));
251 }
252
253 G_MODULE_EXPORT FlValue* fl_basic_message_channel_send_finish(
254 FlBasicMessageChannel* self,
255 GAsyncResult* result,
256 GError** error) {
257 g_return_val_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self), nullptr);
258 g_return_val_if_fail(g_task_is_valid(result, self), nullptr);
259
260 GTask* task = G_TASK(result);
261 g_autoptr(GAsyncResult) r =
262 G_ASYNC_RESULT(g_task_propagate_pointer(task, error));
263 if (r == nullptr) {
264 return nullptr;
265 }
266
267 g_autoptr(GBytes) message =
268 fl_binary_messenger_send_on_channel_finish(self->messenger, r, error);
269 if (message == nullptr) {
270 return nullptr;
271 }
272
273 return fl_message_codec_decode_message(self->codec, message, error);
274 }
fl_basic_message_channel_class_init
static void fl_basic_message_channel_class_init(FlBasicMessageChannelClass *klass)
Definition: fl_basic_message_channel.cc:147
message_cb
static void message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_basic_message_channel.cc:74
fl_basic_message_channel_send_finish
G_MODULE_EXPORT FlValue * fl_basic_message_channel_send_finish(FlBasicMessageChannel *self, GAsyncResult *result, GError **error)
Definition: fl_basic_message_channel.cc:253
fl_basic_message_channel_set_message_handler
G_MODULE_EXPORT void fl_basic_message_channel_set_message_handler(FlBasicMessageChannel *self, FlBasicMessageChannelMessageHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_basic_message_channel.cc:176
fl_basic_message_channel_new
G_MODULE_EXPORT FlBasicMessageChannel * fl_basic_message_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMessageCodec *codec)
Definition: fl_basic_message_channel.cc:154
fl_basic_message_channel_respond
G_MODULE_EXPORT gboolean fl_basic_message_channel_respond(FlBasicMessageChannel *self, FlBasicMessageChannelResponseHandle *response_handle, FlValue *message, GError **error)
Definition: fl_basic_message_channel.cc:204
message_response_cb
static void message_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_basic_message_channel.cc:103
fl_basic_message_channel_response_handle_init
static void fl_basic_message_channel_response_handle_init(FlBasicMessageChannelResponseHandle *self)
Definition: fl_basic_message_channel.cc:57
fl_basic_message_channel_init
static void fl_basic_message_channel_init(FlBasicMessageChannel *self)
Definition: fl_basic_message_channel.cc:152
fl_basic_message_channel_response_handle_new
static FlBasicMessageChannelResponseHandle * fl_basic_message_channel_response_handle_new(FlBinaryMessengerResponseHandle *response_handle)
Definition: fl_basic_message_channel.cc:61
fl_basic_message_channel_response_handle_class_init
static void fl_basic_message_channel_response_handle_class_init(FlBasicMessageChannelResponseHandleClass *klass)
Definition: fl_basic_message_channel.cc:51
fl_basic_message_channel_dispose
static void fl_basic_message_channel_dispose(GObject *object)
Definition: fl_basic_message_channel.cc:125
channel_closed_cb
static void channel_closed_cb(gpointer user_data)
Definition: fl_basic_message_channel.cc:111
fl_basic_message_channel_send
G_MODULE_EXPORT void fl_basic_message_channel_send(FlBasicMessageChannel *self, FlValue *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_basic_message_channel.cc:226
G_DEFINE_TYPE
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
Definition: fl_basic_message_channel.cc:37
fl_basic_message_channel.h
FlBasicMessageChannelMessageHandler
G_BEGIN_DECLS G_MODULE_EXPORT GObject typedef void(* FlBasicMessageChannelMessageHandler)(FlBasicMessageChannel *channel, FlValue *message, FlBasicMessageChannelResponseHandle *response_handle, gpointer user_data)
Definition: fl_basic_message_channel.h:110
fl_basic_message_channel_response_handle
G_BEGIN_DECLS G_MODULE_EXPORT fl_basic_message_channel_response_handle
Definition: fl_basic_message_channel.h:30
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:449
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:408
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:435
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:422
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
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
fl_message_codec_decode_message
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
Definition: fl_message_codec.cc:33
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
_FlBasicMessageChannel
Definition: fl_basic_message_channel.cc:9
_FlBasicMessageChannel::message_handler
FlBasicMessageChannelMessageHandler message_handler
Definition: fl_basic_message_channel.cc:25
_FlBasicMessageChannel::message_handler_data
gpointer message_handler_data
Definition: fl_basic_message_channel.cc:26
_FlBasicMessageChannel::name
gchar * name
Definition: fl_basic_message_channel.cc:19
_FlBasicMessageChannel::parent_instance
GObject parent_instance
Definition: fl_basic_message_channel.cc:10
_FlBasicMessageChannel::codec
FlMessageCodec * codec
Definition: fl_basic_message_channel.cc:22
_FlBasicMessageChannel::messenger
FlBinaryMessenger * messenger
Definition: fl_basic_message_channel.cc:13
_FlBasicMessageChannel::message_handler_destroy_notify
GDestroyNotify message_handler_destroy_notify
Definition: fl_basic_message_channel.cc:27
_FlBasicMessageChannel::channel_closed
gboolean channel_closed
Definition: fl_basic_message_channel.cc:16
_FlBasicMessageChannelResponseHandle
Definition: fl_basic_message_channel.cc:30
_FlBasicMessageChannelResponseHandle::response_handle
FlBinaryMessengerResponseHandle * response_handle
Definition: fl_basic_message_channel.cc:33
_FlBasicMessageChannelResponseHandle::parent_instance
GObject parent_instance
Definition: fl_basic_message_channel.cc:31