Flutter Linux Embedder
fl_event_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 
11 static constexpr char kListenMethod[] = "listen";
12 static constexpr char kCancelMethod[] = "cancel";
13 static constexpr char kEventRequestError[] = "error";
14 
16  GObject parent_instance;
17 
18  // Messenger to communicate on.
19  FlBinaryMessenger* messenger;
20 
21  // TRUE if the channel has been closed.
22  gboolean channel_closed;
23 
24  // Channel name.
25  gchar* name;
26 
27  // Codec to en/decode messages.
28  FlMethodCodec* codec;
29 
30  // Function called when the stream is listened to / cancelled.
31  FlEventChannelHandler listen_handler;
32  FlEventChannelHandler cancel_handler;
33  gpointer handler_data;
35 };
36 
38  GObject parent_instance;
39 
40  FlBinaryMessengerResponseHandle* response_handle;
41 };
42 
43 G_DEFINE_TYPE(FlEventChannel, fl_event_channel, G_TYPE_OBJECT)
44 
45 // Handle method calls from the Dart side of the channel.
46 static FlMethodErrorResponse* handle_method_call(FlEventChannel* self,
47  const gchar* name,
48  FlValue* args) {
49  FlEventChannelHandler handler;
50  if (g_strcmp0(name, kListenMethod) == 0) {
51  handler = self->listen_handler;
52  } else if (g_strcmp0(name, kCancelMethod) == 0) {
53  handler = self->cancel_handler;
54  } else {
55  g_autofree gchar* message =
56  g_strdup_printf("Unknown event channel request '%s'", name);
57  return fl_method_error_response_new(kEventRequestError, message, nullptr);
58  }
59 
60  // If not handled, just accept requests.
61  if (handler == nullptr) {
62  return nullptr;
63  }
64 
65  return handler(self, args, self->handler_data);
66 }
67 
68 // Called when a binary message is received on this channel.
69 static void message_cb(FlBinaryMessenger* messenger,
70  const gchar* channel,
71  GBytes* message,
72  FlBinaryMessengerResponseHandle* response_handle,
73  gpointer user_data) {
74  FlEventChannel* self = FL_EVENT_CHANNEL(user_data);
75 
76  g_autofree gchar* name = nullptr;
77  g_autoptr(GError) error = nullptr;
78  g_autoptr(FlValue) args = nullptr;
79  if (!fl_method_codec_decode_method_call(self->codec, message, &name, &args,
80  &error)) {
81  g_warning("Failed to decode message on event channel %s: %s", self->name,
82  error->message);
83  fl_binary_messenger_send_response(messenger, response_handle, nullptr,
84  nullptr);
85  return;
86  }
87 
88  g_autoptr(FlMethodErrorResponse) response =
89  handle_method_call(self, name, args);
90 
91  g_autoptr(GBytes) data = nullptr;
92  if (response == nullptr) {
93  g_autoptr(GError) codec_error = nullptr;
94  data = fl_method_codec_encode_success_envelope(self->codec, nullptr,
95  &codec_error);
96  if (data == nullptr) {
97  g_warning("Failed to encode event channel %s success response: %s",
98  self->name, codec_error->message);
99  }
100  } else {
101  g_autoptr(GError) codec_error = nullptr;
103  self->codec, fl_method_error_response_get_code(response),
105  fl_method_error_response_get_details(response), &codec_error);
106  if (data == nullptr) {
107  g_warning("Failed to encode event channel %s error response: %s",
108  self->name, codec_error->message);
109  }
110  }
111 
112  if (!fl_binary_messenger_send_response(messenger, response_handle, data,
113  &error)) {
114  g_warning("Failed to send event channel response: %s", error->message);
115  }
116 }
117 
118 // Removes handlers and their associated data.
119 static void remove_handlers(FlEventChannel* self) {
120  if (self->handler_data_destroy_notify != nullptr) {
121  self->handler_data_destroy_notify(self->handler_data);
122  }
123  self->listen_handler = nullptr;
124  self->cancel_handler = nullptr;
125  self->handler_data = nullptr;
126  self->handler_data_destroy_notify = nullptr;
127 }
128 
129 // Called when the channel handler is closed.
130 static void channel_closed_cb(gpointer user_data) {
131  g_autoptr(FlEventChannel) self = FL_EVENT_CHANNEL(user_data);
132  self->channel_closed = TRUE;
133  remove_handlers(self);
134 }
135 
136 static void fl_event_channel_dispose(GObject* object) {
137  FlEventChannel* self = FL_EVENT_CHANNEL(object);
138 
139  if (!self->channel_closed) {
141  self->messenger, self->name, nullptr, nullptr, nullptr);
142  }
143 
144  g_clear_object(&self->messenger);
145  g_clear_pointer(&self->name, g_free);
146  g_clear_object(&self->codec);
147 
148  remove_handlers(self);
149 
150  G_OBJECT_CLASS(fl_event_channel_parent_class)->dispose(object);
151 }
152 
153 static void fl_event_channel_class_init(FlEventChannelClass* klass) {
154  G_OBJECT_CLASS(klass)->dispose = fl_event_channel_dispose;
155 }
156 
157 static void fl_event_channel_init(FlEventChannel* self) {}
158 
159 G_MODULE_EXPORT FlEventChannel* fl_event_channel_new(
160  FlBinaryMessenger* messenger,
161  const gchar* name,
162  FlMethodCodec* codec) {
163  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
164  g_return_val_if_fail(name != nullptr, nullptr);
165  g_return_val_if_fail(FL_IS_METHOD_CODEC(codec), nullptr);
166 
167  FlEventChannel* self =
168  FL_EVENT_CHANNEL(g_object_new(fl_event_channel_get_type(), nullptr));
169 
170  self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));
171  self->name = g_strdup(name);
172  self->codec = FL_METHOD_CODEC(g_object_ref(codec));
173 
175  self->messenger, self->name, message_cb, g_object_ref(self),
177 
178  return self;
179 }
180 
182  FlEventChannel* self,
183  FlEventChannelHandler listen_handler,
184  FlEventChannelHandler cancel_handler,
185  gpointer user_data,
186  GDestroyNotify destroy_notify) {
187  g_return_if_fail(FL_IS_EVENT_CHANNEL(self));
188 
189  remove_handlers(self);
190  self->listen_handler = listen_handler;
191  self->cancel_handler = cancel_handler;
192  self->handler_data = user_data;
193  self->handler_data_destroy_notify = destroy_notify;
194 }
195 
196 G_MODULE_EXPORT gboolean fl_event_channel_send(FlEventChannel* self,
197  FlValue* event,
198  GCancellable* cancellable,
199  GError** error) {
200  g_return_val_if_fail(FL_IS_EVENT_CHANNEL(self), FALSE);
201  g_return_val_if_fail(event != nullptr, FALSE);
202 
203  g_autoptr(GBytes) data =
205  if (data == nullptr) {
206  return FALSE;
207  }
208 
209  fl_binary_messenger_send_on_channel(self->messenger, self->name, data,
210  cancellable, nullptr, nullptr);
211 
212  return TRUE;
213 }
214 
215 G_MODULE_EXPORT gboolean fl_event_channel_send_error(FlEventChannel* self,
216  const gchar* code,
217  const gchar* message,
218  FlValue* details,
219  GCancellable* cancellable,
220  GError** error) {
221  g_return_val_if_fail(FL_IS_EVENT_CHANNEL(self), FALSE);
222  g_return_val_if_fail(code != nullptr, FALSE);
223  g_return_val_if_fail(message != nullptr, FALSE);
224 
225  g_autoptr(GBytes) data = fl_method_codec_encode_error_envelope(
226  self->codec, code, message, details, error);
227  if (data == nullptr) {
228  return FALSE;
229  }
230 
231  fl_binary_messenger_send_on_channel(self->messenger, self->name, data,
232  cancellable, nullptr, nullptr);
233 
234  return TRUE;
235 }
236 
237 G_MODULE_EXPORT gboolean fl_event_channel_send_end_of_stream(
238  FlEventChannel* self,
239  GCancellable* cancellable,
240  GError** error) {
241  g_return_val_if_fail(FL_IS_EVENT_CHANNEL(self), FALSE);
242  fl_binary_messenger_send_on_channel(self->messenger, self->name, nullptr,
243  cancellable, nullptr, nullptr);
244  return TRUE;
245 }
_FlEventChannelResponseHandle
Definition: fl_event_channel.cc:37
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
kEventRequestError
static constexpr char kEventRequestError[]
Definition: fl_event_channel.cc:13
fl_method_error_response_new
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
Definition: fl_method_response.cc:144
_FlEventChannel::name
gchar * name
Definition: fl_event_channel.cc:25
_FlEventChannelResponseHandle::response_handle
FlBinaryMessengerResponseHandle * response_handle
Definition: fl_event_channel.cc:40
_FlEventChannelResponseHandle::parent_instance
GObject parent_instance
Definition: fl_event_channel.cc:38
_FlEventChannel::channel_closed
gboolean channel_closed
Definition: fl_event_channel.cc:22
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
remove_handlers
static void remove_handlers(FlEventChannel *self)
Definition: fl_event_channel.cc:119
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_event_channel_send
G_MODULE_EXPORT gboolean fl_event_channel_send(FlEventChannel *self, FlValue *event, GCancellable *cancellable, GError **error)
Definition: fl_event_channel.cc:196
fl_method_error_response_get_message
const G_MODULE_EXPORT gchar * fl_method_error_response_get_message(FlMethodErrorResponse *self)
Definition: fl_method_response.cc:166
_FlEventChannel
Definition: fl_event_channel.cc:15
channel_closed_cb
static void channel_closed_cb(gpointer user_data)
Definition: fl_event_channel.cc:130
_FlEventChannel::messenger
FlBinaryMessenger * messenger
Definition: fl_event_channel.cc:19
_FlEventChannel::parent_instance
GObject parent_instance
Definition: fl_event_channel.cc:16
fl_method_error_response_get_details
G_MODULE_EXPORT FlValue * fl_method_error_response_get_details(FlMethodErrorResponse *self)
Definition: fl_method_response.cc:172
fl_event_channel_send_error
G_MODULE_EXPORT gboolean fl_event_channel_send_error(FlEventChannel *self, const gchar *code, const gchar *message, FlValue *details, GCancellable *cancellable, GError **error)
Definition: fl_event_channel.cc:215
fl_event_channel_dispose
static void fl_event_channel_dispose(GObject *object)
Definition: fl_event_channel.cc:136
fl_method_codec_decode_method_call
gboolean fl_method_codec_decode_method_call(FlMethodCodec *self, GBytes *message, gchar **name, FlValue **args, GError **error)
Definition: fl_method_codec.cc:27
fl_event_channel_new
G_MODULE_EXPORT FlEventChannel * fl_event_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMethodCodec *codec)
Definition: fl_event_channel.cc:159
_FlEventChannel::codec
FlMethodCodec * codec
Definition: fl_event_channel.cc:28
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
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
_FlEventChannel::handler_data
gpointer handler_data
Definition: fl_event_channel.cc:33
_FlEventChannel::cancel_handler
FlEventChannelHandler cancel_handler
Definition: fl_event_channel.cc:32
fl_event_channel.h
fl_method_codec_encode_success_envelope
GBytes * fl_method_codec_encode_success_envelope(FlMethodCodec *self, FlValue *result, GError **error)
Definition: fl_method_codec.cc:41
fl_event_channel_send_end_of_stream
G_MODULE_EXPORT gboolean fl_event_channel_send_end_of_stream(FlEventChannel *self, GCancellable *cancellable, GError **error)
Definition: fl_event_channel.cc:237
fl_event_channel_init
static void fl_event_channel_init(FlEventChannel *self)
Definition: fl_event_channel.cc:157
_FlEventChannel::listen_handler
FlEventChannelHandler listen_handler
Definition: fl_event_channel.cc:31
fl_event_channel_set_stream_handlers
G_MODULE_EXPORT void fl_event_channel_set_stream_handlers(FlEventChannel *self, FlEventChannelHandler listen_handler, FlEventChannelHandler cancel_handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_event_channel.cc:181
fl_method_error_response_get_code
const G_MODULE_EXPORT gchar * fl_method_error_response_get_code(FlMethodErrorResponse *self)
Definition: fl_method_response.cc:160
message_cb
static void message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
Definition: fl_event_channel.cc:69
args
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: fl_event_channel.h:89
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
_FlEventChannel::handler_data_destroy_notify
GDestroyNotify handler_data_destroy_notify
Definition: fl_event_channel.cc:34
fl_method_codec_encode_error_envelope
GBytes * fl_method_codec_encode_error_envelope(FlMethodCodec *self, const gchar *code, const gchar *message, FlValue *details, GError **error)
Definition: fl_method_codec.cc:50
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
fl_method_codec_private.h
kCancelMethod
static constexpr char kCancelMethod[]
Definition: fl_event_channel.cc:12
fl_event_channel_class_init
static void fl_event_channel_class_init(FlEventChannelClass *klass)
Definition: fl_event_channel.cc:153
handle_method_call
static FlMethodErrorResponse * handle_method_call(FlEventChannel *self, const gchar *name, FlValue *args)
Definition: fl_event_channel.cc:46
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
kListenMethod
static constexpr char kListenMethod[]
Definition: fl_event_channel.cc:11