Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ca4751f

Browse files
committed
Add FlChannel, FlBasicMessageChannel
1 parent 72a48bd commit ca4751f

File tree

5 files changed

+321
-0
lines changed

5 files changed

+321
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,7 @@ FILE: ../../../flutter/shell/platform/glfw/platform_handler.h
11851185
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
11861186
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
11871187
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
1188+
FILE: ../../../flutter/shell/platform/linux/fl_basic_message_channel.cc
11881189
FILE: ../../../flutter/shell/platform/linux/fl_binary_codec.cc
11891190
FILE: ../../../flutter/shell/platform/linux/fl_binary_codec_test.cc
11901191
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
@@ -1204,6 +1205,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_string_codec_test.cc
12041205
FILE: ../../../flutter/shell/platform/linux/fl_value.cc
12051206
FILE: ../../../flutter/shell/platform/linux/fl_value_test.cc
12061207
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
1208+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h
12071209
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_codec.h
12081210
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h
12091211
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h

shell/platform/linux/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ if (build_glfw_shell) {
4444
}
4545

4646
_public_headers = [
47+
"public/flutter_linux/fl_basic_message_channel.h",
4748
"public/flutter_linux/fl_binary_codec.h",
4849
"public/flutter_linux/fl_binary_messenger.h",
4950
"public/flutter_linux/fl_dart_project.h",
@@ -63,6 +64,7 @@ source_set("flutter_linux") {
6364
public = _public_headers
6465

6566
sources = [
67+
"fl_basic_message_channel.cc",
6668
"fl_binary_codec.cc",
6769
"fl_binary_messenger.cc",
6870
"fl_dart_project.cc",
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
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+
typedef struct {
10+
// Messenger to communicate on
11+
FlBinaryMessenger* messenger;
12+
13+
// Channel name
14+
gchar* name;
15+
16+
// Codec to en/decode messages
17+
FlMessageCodec* codec;
18+
19+
// Function called when a message is received
20+
FlBasicMessageChannelMessageHandler message_handler;
21+
gpointer message_handler_data;
22+
} FlBasicMessageChannelPrivate;
23+
24+
// Added here to stop the compiler from optimising this function away
25+
G_MODULE_EXPORT GType fl_basic_message_channel_get_type();
26+
27+
enum { PROP_MESSENGER = 1, PROP_NAME, PROP_CODEC, PROP_LAST };
28+
29+
G_DEFINE_TYPE_WITH_PRIVATE(FlBasicMessageChannel,
30+
fl_basic_message_channel,
31+
G_TYPE_OBJECT)
32+
33+
// Called when a binary message is received on this channel
34+
static void message_cb(FlBinaryMessenger* messenger,
35+
const gchar* channel,
36+
GBytes* message,
37+
FlBinaryMessengerResponseHandle* response_handle,
38+
gpointer user_data) {
39+
FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(user_data);
40+
FlBasicMessageChannelPrivate* priv =
41+
static_cast<FlBasicMessageChannelPrivate*>(
42+
fl_basic_message_channel_get_instance_private(self));
43+
44+
if (priv->message_handler == nullptr) {
45+
fl_binary_messenger_send_response(messenger, response_handle, nullptr,
46+
nullptr);
47+
return;
48+
}
49+
50+
g_autoptr(GError) error = nullptr;
51+
g_autoptr(FlValue) message_value =
52+
fl_message_codec_decode_message(priv->codec, message, &error);
53+
if (message_value == nullptr)
54+
g_warning("Failed to decode message: %s", error->message);
55+
else
56+
priv->message_handler(self, message_value, priv->message_handler_data);
57+
58+
fl_binary_messenger_send_response(messenger, response_handle, nullptr,
59+
nullptr);
60+
}
61+
62+
// Called when a response is received to a sent message
63+
static void message_response_cb(GObject* object,
64+
GAsyncResult* result,
65+
gpointer user_data) {
66+
g_autoptr(GError) error = nullptr;
67+
g_autoptr(GBytes) response = fl_binary_messenger_send_on_channel_finish(
68+
FL_BINARY_MESSENGER(object), result, &error);
69+
if (response == nullptr)
70+
g_warning("Failed to send on basic message channel: %s", error->message);
71+
}
72+
73+
static void fl_basic_message_channel_set_property(GObject* object,
74+
guint prop_id,
75+
const GValue* value,
76+
GParamSpec* pspec) {
77+
FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(object);
78+
FlBasicMessageChannelPrivate* priv =
79+
static_cast<FlBasicMessageChannelPrivate*>(
80+
fl_basic_message_channel_get_instance_private(self));
81+
82+
switch (prop_id) {
83+
case PROP_MESSENGER:
84+
g_set_object(&priv->messenger,
85+
FL_BINARY_MESSENGER(g_value_get_object(value)));
86+
break;
87+
case PROP_NAME:
88+
g_free(priv->name);
89+
priv->name = g_value_dup_string(value);
90+
break;
91+
case PROP_CODEC:
92+
g_set_object(&priv->codec, FL_MESSAGE_CODEC(g_value_get_object(value)));
93+
break;
94+
default:
95+
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
96+
break;
97+
}
98+
}
99+
100+
static void fl_basic_message_channel_get_property(GObject* object,
101+
guint prop_id,
102+
GValue* value,
103+
GParamSpec* pspec) {
104+
FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(object);
105+
FlBasicMessageChannelPrivate* priv =
106+
static_cast<FlBasicMessageChannelPrivate*>(
107+
fl_basic_message_channel_get_instance_private(self));
108+
109+
switch (prop_id) {
110+
case PROP_MESSENGER:
111+
g_value_set_object(value, priv->messenger);
112+
break;
113+
case PROP_NAME:
114+
g_value_set_string(value, priv->name);
115+
break;
116+
case PROP_CODEC:
117+
g_value_set_object(value, priv->codec);
118+
break;
119+
default:
120+
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
121+
break;
122+
}
123+
}
124+
125+
static void fl_basic_message_channel_constructed(GObject* object) {
126+
FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(object);
127+
FlBasicMessageChannelPrivate* priv =
128+
static_cast<FlBasicMessageChannelPrivate*>(
129+
fl_basic_message_channel_get_instance_private(self));
130+
131+
fl_binary_messenger_set_message_handler_on_channel(
132+
priv->messenger, priv->name, message_cb, self);
133+
134+
G_OBJECT_CLASS(fl_basic_message_channel_parent_class)->constructed(object);
135+
}
136+
137+
static void fl_basic_message_channel_dispose(GObject* object) {
138+
FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(object);
139+
FlBasicMessageChannelPrivate* priv =
140+
static_cast<FlBasicMessageChannelPrivate*>(
141+
fl_basic_message_channel_get_instance_private(self));
142+
143+
if (priv->messenger != nullptr)
144+
fl_binary_messenger_set_message_handler_on_channel(
145+
priv->messenger, priv->name, nullptr, nullptr);
146+
147+
g_clear_object(&priv->messenger);
148+
g_clear_pointer(&priv->name, g_free);
149+
g_clear_object(&priv->codec);
150+
151+
G_OBJECT_CLASS(fl_basic_message_channel_parent_class)->dispose(object);
152+
}
153+
154+
static void fl_basic_message_channel_class_init(
155+
FlBasicMessageChannelClass* klass) {
156+
G_OBJECT_CLASS(klass)->set_property = fl_basic_message_channel_set_property;
157+
G_OBJECT_CLASS(klass)->get_property = fl_basic_message_channel_get_property;
158+
G_OBJECT_CLASS(klass)->constructed = fl_basic_message_channel_constructed;
159+
G_OBJECT_CLASS(klass)->dispose = fl_basic_message_channel_dispose;
160+
161+
g_object_class_install_property(
162+
G_OBJECT_CLASS(klass), PROP_CODEC,
163+
g_param_spec_object(
164+
"codec", "codec", "Message codec", fl_message_codec_get_type(),
165+
static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
166+
G_PARAM_STATIC_STRINGS)));
167+
}
168+
169+
static void fl_basic_message_channel_init(FlBasicMessageChannel* self) {}
170+
171+
G_MODULE_EXPORT FlBasicMessageChannel* fl_basic_message_channel_new(
172+
FlBinaryMessenger* messenger,
173+
const gchar* name,
174+
FlMessageCodec* codec) {
175+
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
176+
g_return_val_if_fail(name != nullptr, nullptr);
177+
g_return_val_if_fail(FL_IS_MESSAGE_CODEC(codec), nullptr);
178+
179+
return FL_BASIC_MESSAGE_CHANNEL(
180+
g_object_new(fl_basic_message_channel_get_type(), "messenger", messenger,
181+
"name", name, "codec", codec, nullptr));
182+
}
183+
184+
G_MODULE_EXPORT void fl_basic_message_channel_set_message_handler(
185+
FlBasicMessageChannel* self,
186+
FlBasicMessageChannelMessageHandler handler,
187+
gpointer user_data) {
188+
g_return_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self));
189+
FlBasicMessageChannelPrivate* priv =
190+
static_cast<FlBasicMessageChannelPrivate*>(
191+
fl_basic_message_channel_get_instance_private(self));
192+
193+
priv->message_handler = handler;
194+
priv->message_handler_data = user_data;
195+
}
196+
197+
G_MODULE_EXPORT gboolean
198+
fl_basic_message_channel_send(FlBasicMessageChannel* self,
199+
FlValue* message,
200+
GError** error) {
201+
FlBasicMessageChannelPrivate* priv =
202+
static_cast<FlBasicMessageChannelPrivate*>(
203+
fl_basic_message_channel_get_instance_private(self));
204+
205+
g_return_val_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self), FALSE);
206+
g_return_val_if_fail(message != nullptr, FALSE);
207+
208+
g_autoptr(GBytes) data =
209+
fl_message_codec_encode_message(priv->codec, message, error);
210+
if (data == nullptr)
211+
return FALSE;
212+
213+
fl_binary_messenger_send_on_channel(priv->messenger, priv->name, data,
214+
nullptr, message_response_cb, nullptr);
215+
216+
return TRUE;
217+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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+
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_BASIC_MESSAGE_CHANNEL_H_
6+
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_BASIC_MESSAGE_CHANNEL_H_
7+
8+
#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
9+
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
10+
#endif
11+
12+
#include <gio/gio.h>
13+
#include <glib-object.h>
14+
15+
#include "fl_binary_messenger.h"
16+
#include "fl_message_codec.h"
17+
18+
G_BEGIN_DECLS
19+
20+
G_DECLARE_DERIVABLE_TYPE(FlBasicMessageChannel,
21+
fl_basic_message_channel,
22+
FL,
23+
BASIC_MESSAGE_CHANNEL,
24+
GObject)
25+
26+
/**
27+
* FlBasicMessageChannel:
28+
*
29+
* #FlBasicMessageChannel is an object that allows sending and receiving
30+
* messages to/from Dart code over platform channels.
31+
*
32+
* #FlBasicMessageChannel matches the BasicMessageChannel class in the Flutter
33+
* services library.
34+
*/
35+
36+
struct _FlBasicMessageChannelClass {
37+
GObjectClass parent_class;
38+
};
39+
40+
/**
41+
* FlBasicMessageChannelMessageHandler:
42+
* @channel: a #FlBasicMessageChannel
43+
* @message: message received
44+
* @user_data: (closure): data provided when registering this handler
45+
*
46+
* Function called when a message is received.
47+
*/
48+
typedef void (*FlBasicMessageChannelMessageHandler)(
49+
FlBasicMessageChannel* channel,
50+
FlValue* message,
51+
gpointer user_data);
52+
53+
/**
54+
* fl_basic_message_channel_new:
55+
* @messenger: a #FlBinaryMessenger
56+
* @name: a channel name
57+
* @codec: the message codec
58+
*
59+
* Create a new basic message channel. @codec must match the codec used on the
60+
* Dart end of the channel.
61+
*
62+
* Returns: a new #FlBasicMessageChannel.
63+
*/
64+
FlBasicMessageChannel* fl_basic_message_channel_new(
65+
FlBinaryMessenger* messenger,
66+
const gchar* name,
67+
FlMessageCodec* codec);
68+
69+
/**
70+
* fl_basic_message_channel_set_message_handler:
71+
* @channel: a #FlBasicMessageChannel
72+
* @handler: (allow-none): function to call when a message is received on this
73+
* channel or %NULL to disable the handler.
74+
* @user_data: (closure): user data to pass to @handler
75+
*
76+
* Set the function called when a message is received.
77+
*/
78+
void fl_basic_message_channel_set_message_handler(
79+
FlBasicMessageChannel* channel,
80+
FlBasicMessageChannelMessageHandler handler,
81+
gpointer user_data);
82+
83+
/**
84+
* fl_basic_message_channel_send:
85+
* @channel: a #FlBasicMessageChannel
86+
* @message: message to send, must match what the #FlMessageCodec supports
87+
* @error: (allow-none): #GError location to store the error occurring, or %NULL
88+
*
89+
* Send a message.
90+
*
91+
* Returns: %TRUE on success
92+
*/
93+
gboolean fl_basic_message_channel_send(FlBasicMessageChannel* channel,
94+
FlValue* message,
95+
GError** error);
96+
97+
G_END_DECLS
98+
99+
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_BASIC_MESSAGE_CHANNEL_H_

shell/platform/linux/public/flutter_linux/flutter_linux.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#define __FLUTTER_LINUX_INSIDE__
99

10+
#include <flutter_linux/fl_basic_message_channel.h>
1011
#include <flutter_linux/fl_binary_codec.h>
1112
#include <flutter_linux/fl_binary_messenger.h>
1213
#include <flutter_linux/fl_dart_project.h>

0 commit comments

Comments
 (0)