Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
5#include "flutter/shell/platform/linux/public/flutter_linux/fl_event_channel.h"
6
7#include <gmodule.h>
8
9#include "flutter/shell/platform/linux/fl_method_codec_private.h"
10
11static constexpr char kListenMethod[] = "listen";
12static constexpr char kCancelMethod[] = "cancel";
13static constexpr char kEventRequestError[] = "error";
14
17
18 // Messenger to communicate on.
19 FlBinaryMessenger* messenger;
20
21 // TRUE if the channel has been 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
39
40 FlBinaryMessengerResponseHandle* response_handle;
41};
42
43G_DEFINE_TYPE(FlEventChannel, fl_event_channel, G_TYPE_OBJECT)
44
45// Handle method calls from the Dart side of the channel.
46static 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);
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.
69static 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;
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 =
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.
119static 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.
130static void channel_closed_cb(gpointer user_data) {
131 g_autoptr(FlEventChannel) self = FL_EVENT_CHANNEL(user_data);
132 self->channel_closed = TRUE;
134}
135
136static 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
149
150 G_OBJECT_CLASS(fl_event_channel_parent_class)->dispose(object);
151}
152
153static void fl_event_channel_class_init(FlEventChannelClass* klass) {
154 G_OBJECT_CLASS(klass)->dispose = fl_event_channel_dispose;
155}
156
157static void fl_event_channel_init(FlEventChannel* self) {}
158
159G_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
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
196G_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
215G_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
237G_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}
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_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)
G_MODULE_EXPORT gboolean fl_event_channel_send(FlEventChannel *self, FlValue *event, GCancellable *cancellable, GError **error)
static void message_cb(FlBinaryMessenger *messenger, const gchar *channel, GBytes *message, FlBinaryMessengerResponseHandle *response_handle, gpointer user_data)
G_MODULE_EXPORT gboolean fl_event_channel_send_end_of_stream(FlEventChannel *self, GCancellable *cancellable, GError **error)
G_MODULE_EXPORT gboolean fl_event_channel_send_error(FlEventChannel *self, const gchar *code, const gchar *message, FlValue *details, GCancellable *cancellable, GError **error)
static void fl_event_channel_dispose(GObject *object)
static void fl_event_channel_class_init(FlEventChannelClass *klass)
static constexpr char kListenMethod[]
G_MODULE_EXPORT void fl_event_channel_set_stream_handlers(FlEventChannel *self, FlEventChannelHandler listen_handler, FlEventChannelHandler cancel_handler, gpointer user_data, GDestroyNotify destroy_notify)
G_MODULE_EXPORT FlEventChannel * fl_event_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMethodCodec *codec)
static void fl_event_channel_init(FlEventChannel *self)
static constexpr char kEventRequestError[]
static FlMethodErrorResponse * handle_method_call(FlEventChannel *self, const gchar *name, FlValue *args)
static void remove_handlers(FlEventChannel *self)
static void channel_closed_cb(gpointer user_data)
static constexpr char kCancelMethod[]
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent * event
gboolean fl_method_codec_decode_method_call(FlMethodCodec *self, GBytes *message, gchar **name, FlValue **args, GError **error)
GBytes * fl_method_codec_encode_success_envelope(FlMethodCodec *self, FlValue *result, GError **error)
GBytes * fl_method_codec_encode_error_envelope(FlMethodCodec *self, const gchar *code, const gchar *message, FlValue *details, GError **error)
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
G_MODULE_EXPORT const gchar * fl_method_error_response_get_message(FlMethodErrorResponse *self)
G_MODULE_EXPORT FlValue * fl_method_error_response_get_details(FlMethodErrorResponse *self)
G_MODULE_EXPORT const gchar * fl_method_error_response_get_code(FlMethodErrorResponse *self)
const uint8_t uint32_t uint32_t GError ** error
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
GDestroyNotify handler_data_destroy_notify
FlEventChannelHandler cancel_handler
FlBinaryMessenger * messenger
FlEventChannelHandler listen_handler
FlMethodCodec * codec