Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
11
12 // Messenger to communicate on.
13 FlBinaryMessenger* messenger;
14
15 // TRUE if the channel has been 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
32
33 FlBinaryMessengerResponseHandle* response_handle;
34};
35
36G_DEFINE_TYPE(FlBasicMessageChannel, fl_basic_message_channel, G_TYPE_OBJECT)
37G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle,
39 G_TYPE_OBJECT)
40
41static 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
60static 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.
74static 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 =
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.
103static 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.
111static 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
125static 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
152static void fl_basic_message_channel_init(FlBasicMessageChannel* self) {}
153
154G_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
204G_MODULE_EXPORT gboolean fl_basic_message_channel_respond(
205 FlBasicMessageChannel* self,
206 FlBasicMessageChannelResponseHandle* response_handle,
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 =
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
226G_MODULE_EXPORT void fl_basic_message_channel_send(FlBasicMessageChannel* self,
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 =
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
270}
static void fl_basic_message_channel_class_init(FlBasicMessageChannelClass *klass)
G_MODULE_EXPORT FlBasicMessageChannel * fl_basic_message_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMessageCodec *codec)
static FlBasicMessageChannelResponseHandle * fl_basic_message_channel_response_handle_new(FlBinaryMessengerResponseHandle *response_handle)
static void message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
G_MODULE_EXPORT void fl_basic_message_channel_set_message_handler(FlBasicMessageChannel *self, FlBasicMessageChannelMessageHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
G_MODULE_EXPORT gboolean fl_basic_message_channel_respond(FlBasicMessageChannel *self, FlBasicMessageChannelResponseHandle *response_handle, FlValue *message, GError **error)
static void message_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
static void fl_basic_message_channel_response_handle_init(FlBasicMessageChannelResponseHandle *self)
static void fl_basic_message_channel_init(FlBasicMessageChannel *self)
G_MODULE_EXPORT FlValue * fl_basic_message_channel_send_finish(FlBasicMessageChannel *self, GAsyncResult *result, GError **error)
static void fl_basic_message_channel_response_handle_class_init(FlBasicMessageChannelResponseHandleClass *klass)
static void fl_basic_message_channel_dispose(GObject *object)
static void channel_closed_cb(gpointer user_data)
G_MODULE_EXPORT void fl_basic_message_channel_send(FlBasicMessageChannel *self, FlValue *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
G_BEGIN_DECLS G_MODULE_EXPORT GObject typedef void(* FlBasicMessageChannelMessageHandler)(FlBasicMessageChannel *channel, FlValue *message, FlBasicMessageChannelResponseHandle *response_handle, gpointer user_data)
G_BEGIN_DECLS G_MODULE_EXPORT fl_basic_message_channel_response_handle
G_MODULE_EXPORT GBytes * fl_binary_messenger_send_on_channel_finish(FlBinaryMessenger *self, GAsyncResult *result, GError **error)
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)
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(FlBinaryMessenger *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(FlBinaryMessenger *self, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
G_MODULE_EXPORT GBytes * fl_message_codec_encode_message(FlMessageCodec *self, FlValue *message, GError **error)
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition fl_value.h:42
const char * name
Definition fuchsia.cc:50
Win32Message message
return FALSE
FlBinaryMessengerResponseHandle * response_handle
FlBasicMessageChannelMessageHandler message_handler
GDestroyNotify message_handler_destroy_notify