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 
6 
7 #include <gmodule.h>
8 
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.
28 };
29 
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,
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 
52  FlBasicMessageChannelResponseHandleClass* klass) {
53  G_OBJECT_CLASS(klass)->dispose =
54  fl_basic_message_channel_response_handle_dispose;
55 }
56 
58  FlBasicMessageChannelResponseHandle* self) {}
59 
60 static FlBasicMessageChannelResponseHandle*
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 =
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  GTask* task = G_TASK(user_data);
107  g_task_return_pointer(task, 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) {
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 
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 
170  self->messenger, self->name, message_cb, g_object_ref(self),
172 
173  return self;
174 }
175 
177  FlBasicMessageChannel* self,
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 
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, error);
243  }
244  return;
245  }
246 
248  self->messenger, self->name, data, cancellable,
249  callback != nullptr ? message_response_cb : nullptr,
250  g_steal_pointer(&task));
251 }
252 
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  g_autoptr(GTask) task = G_TASK(result);
261  GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr));
262 
263  g_autoptr(GBytes) message =
265  if (message == nullptr) {
266  return nullptr;
267  }
268 
269  return fl_message_codec_decode_message(self->codec, message, error);
270 }
channel_closed_cb
static void channel_closed_cb(gpointer user_data)
Definition: fl_basic_message_channel.cc:111
_FlBasicMessageChannelResponseHandle::parent_instance
GObject parent_instance
Definition: fl_basic_message_channel.cc:31
_FlBasicMessageChannel
Definition: fl_basic_message_channel.cc:9
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
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
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_basic_message_channel.h
_FlBasicMessageChannel::message_handler
FlBasicMessageChannelMessageHandler message_handler
Definition: fl_basic_message_channel.cc:25
_FlBasicMessageChannelResponseHandle
Definition: fl_basic_message_channel.cc:30
_FlBasicMessageChannel::messenger
FlBinaryMessenger * messenger
Definition: fl_basic_message_channel.cc:13
_FlBasicMessageChannel::message_handler_data
gpointer message_handler_data
Definition: fl_basic_message_channel.cc:26
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
message_response_cb
static void message_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_basic_message_channel.cc:103
_FlBasicMessageChannel::message_handler_destroy_notify
GDestroyNotify message_handler_destroy_notify
Definition: fl_basic_message_channel.cc:27
fl_basic_message_channel_init
static void fl_basic_message_channel_init(FlBasicMessageChannel *self)
Definition: fl_basic_message_channel.cc:152
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_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
_FlBasicMessageChannel::name
gchar * name
Definition: fl_basic_message_channel.cc:19
_FlBasicMessageChannel::codec
FlMessageCodec * codec
Definition: fl_basic_message_channel.cc:22
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_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:424
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
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
_FlBasicMessageChannel::parent_instance
GObject parent_instance
Definition: fl_basic_message_channel.cc:10
fl_basic_message_channel_class_init
static void fl_basic_message_channel_class_init(FlBasicMessageChannelClass *klass)
Definition: fl_basic_message_channel.cc:147
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:465
_FlBasicMessageChannelResponseHandle::response_handle
FlBinaryMessengerResponseHandle * response_handle
Definition: fl_basic_message_channel.cc:33
_FlBasicMessageChannel::channel_closed
gboolean channel_closed
Definition: fl_basic_message_channel.cc:16
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
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
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_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_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
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:438
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_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_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
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:451
fl_basic_message_channel_dispose
static void fl_basic_message_channel_dispose(GObject *object)
Definition: fl_basic_message_channel.cc:125