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

Commit b17dcb6

Browse files
committed
Add FlMethodChannel, FlMethodCodec and FlStandardMethodCodec
1 parent 053601c commit b17dcb6

File tree

12 files changed

+1820
-0
lines changed

12 files changed

+1820
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,13 +1195,19 @@ FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
11951195
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
11961196
FILE: ../../../flutter/shell/platform/linux/fl_message_codec.cc
11971197
FILE: ../../../flutter/shell/platform/linux/fl_message_codec_test.cc
1198+
FILE: ../../../flutter/shell/platform/linux/fl_method_channel.cc
1199+
FILE: ../../../flutter/shell/platform/linux/fl_method_codec.cc
1200+
FILE: ../../../flutter/shell/platform/linux/fl_method_codec_private.h
1201+
FILE: ../../../flutter/shell/platform/linux/fl_method_codec_test.cc
11981202
FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc
11991203
FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
12001204
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
12011205
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
12021206
FILE: ../../../flutter/shell/platform/linux/fl_standard_codec.cc
12031207
FILE: ../../../flutter/shell/platform/linux/fl_standard_codec_private.h
12041208
FILE: ../../../flutter/shell/platform/linux/fl_standard_codec_test.cc
1209+
FILE: ../../../flutter/shell/platform/linux/fl_standard_method_codec.cc
1210+
FILE: ../../../flutter/shell/platform/linux/fl_standard_method_codec_test.cc
12051211
FILE: ../../../flutter/shell/platform/linux/fl_string_codec.cc
12061212
FILE: ../../../flutter/shell/platform/linux/fl_string_codec_test.cc
12071213
FILE: ../../../flutter/shell/platform/linux/fl_value.cc
@@ -1213,7 +1219,10 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messe
12131219
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
12141220
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
12151221
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h
1222+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h
1223+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h
12161224
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_codec.h
1225+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h
12171226
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h
12181227
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_value.h
12191228
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h

shell/platform/linux/BUILD.gn

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ _public_headers = [
5050
"public/flutter_linux/fl_dart_project.h",
5151
"public/flutter_linux/fl_engine.h",
5252
"public/flutter_linux/fl_message_codec.h",
53+
"public/flutter_linux/fl_method_channel.h",
54+
"public/flutter_linux/fl_method_codec.h",
5355
"public/flutter_linux/fl_standard_codec.h",
56+
"public/flutter_linux/fl_standard_method_codec.h",
5457
"public/flutter_linux/fl_string_codec.h",
5558
"public/flutter_linux/fl_value.h",
5659
"public/flutter_linux/fl_view.h",
@@ -71,9 +74,12 @@ source_set("flutter_linux") {
7174
"fl_dart_project.cc",
7275
"fl_engine.cc",
7376
"fl_message_codec.cc",
77+
"fl_method_channel.cc",
78+
"fl_method_codec.cc",
7479
"fl_renderer.cc",
7580
"fl_renderer_x11.cc",
7681
"fl_standard_codec.cc",
82+
"fl_standard_method_codec.cc",
7783
"fl_string_codec.cc",
7884
"fl_value.cc",
7985
"fl_view.cc",
@@ -104,7 +110,9 @@ executable("flutter_linux_unittests") {
104110
"fl_binary_codec_test.cc",
105111
"fl_dart_project_test.cc",
106112
"fl_message_codec_test.cc",
113+
"fl_method_codec_test.cc",
107114
"fl_standard_codec_test.cc",
115+
"fl_standard_method_codec_test.cc",
108116
"fl_string_codec_test.cc",
109117
"fl_value_test.cc",
110118
"testing/fl_test.cc",
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
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_method_channel.h"
6+
7+
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
8+
9+
#include <gmodule.h>
10+
11+
struct _FlMethodChannel {
12+
GObject parent_instance;
13+
14+
FlBinaryMessenger* messenger;
15+
FlMethodCodec* codec;
16+
gchar* name;
17+
18+
FlMethodChannelCallback callback;
19+
gpointer callback_data;
20+
};
21+
22+
// Added here to stop the compiler from optimising this function away
23+
G_MODULE_EXPORT GType fl_method_channel_get_type();
24+
25+
G_DEFINE_TYPE(FlMethodChannel, fl_method_channel, G_TYPE_OBJECT)
26+
27+
struct _FlMethodChannelResponseHandle {
28+
FlBinaryMessengerResponseHandle* response_handle;
29+
};
30+
31+
static FlMethodChannelResponseHandle* response_handle_new(
32+
FlBinaryMessengerResponseHandle* response_handle) {
33+
FlMethodChannelResponseHandle* handle =
34+
static_cast<FlMethodChannelResponseHandle*>(
35+
g_malloc0(sizeof(FlMethodChannelResponseHandle)));
36+
handle->response_handle = response_handle;
37+
38+
return handle;
39+
}
40+
41+
static void response_handle_free(FlMethodChannelResponseHandle* handle) {
42+
g_free(handle);
43+
}
44+
45+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlMethodChannelResponseHandle,
46+
response_handle_free);
47+
48+
static void message_cb(FlBinaryMessenger* messenger,
49+
const gchar* channel,
50+
GBytes* message,
51+
FlBinaryMessengerResponseHandle* response_handle,
52+
gpointer user_data) {
53+
FlMethodChannel* self = FL_METHOD_CHANNEL(user_data);
54+
55+
if (self->callback == nullptr) {
56+
fl_binary_messenger_send_response(messenger, response_handle, nullptr,
57+
nullptr);
58+
return;
59+
}
60+
61+
g_autofree gchar* method = nullptr;
62+
g_autoptr(FlValue) args = nullptr;
63+
g_autoptr(GError) error = nullptr;
64+
if (!fl_method_codec_decode_method_call(self->codec, message, &method, &args,
65+
&error)) {
66+
g_warning("Failed to decode method call: %s", error->message);
67+
fl_binary_messenger_send_response(messenger, response_handle, nullptr,
68+
nullptr);
69+
return;
70+
}
71+
72+
self->callback(self, method, args, response_handle_new(response_handle),
73+
self->callback_data);
74+
}
75+
76+
static void send_on_channel_ready_cb(GObject* object,
77+
GAsyncResult* result,
78+
gpointer user_data) {
79+
GTask* task = static_cast<GTask*>(user_data);
80+
g_task_return_pointer(task, result, g_object_unref);
81+
}
82+
83+
static void fl_method_channel_dispose(GObject* object) {
84+
FlMethodChannel* self = FL_METHOD_CHANNEL(object);
85+
86+
g_clear_pointer(&self->name, g_free);
87+
88+
G_OBJECT_CLASS(fl_method_channel_parent_class)->dispose(object);
89+
}
90+
91+
static void fl_method_channel_class_init(FlMethodChannelClass* klass) {
92+
G_OBJECT_CLASS(klass)->dispose = fl_method_channel_dispose;
93+
}
94+
95+
static void fl_method_channel_init(FlMethodChannel* self) {}
96+
97+
G_MODULE_EXPORT FlMethodChannel* fl_method_channel_new(
98+
FlBinaryMessenger* messenger,
99+
const gchar* name,
100+
FlMethodCodec* codec) {
101+
g_return_val_if_fail(name != nullptr, nullptr);
102+
g_return_val_if_fail(FL_IS_METHOD_CODEC(codec), nullptr);
103+
104+
FlMethodChannel* self = static_cast<FlMethodChannel*>(
105+
g_object_new(fl_method_channel_get_type(), nullptr));
106+
self->messenger = static_cast<FlBinaryMessenger*>(g_object_ref(messenger));
107+
self->name = g_strdup(name);
108+
self->codec = static_cast<FlMethodCodec*>(g_object_ref(codec));
109+
110+
fl_binary_messenger_set_message_handler_on_channel(messenger, name,
111+
message_cb, self);
112+
113+
return self;
114+
}
115+
116+
G_MODULE_EXPORT void fl_method_channel_set_callback(
117+
FlMethodChannel* self,
118+
FlMethodChannelCallback callback,
119+
gpointer user_data) {
120+
g_return_if_fail(FL_IS_METHOD_CHANNEL(self));
121+
self->callback = callback;
122+
self->callback_data = user_data;
123+
}
124+
125+
G_MODULE_EXPORT void fl_method_channel_invoke(FlMethodChannel* self,
126+
const gchar* method,
127+
FlValue* args,
128+
GCancellable* cancellable,
129+
GAsyncReadyCallback callback,
130+
gpointer user_data) {
131+
g_return_if_fail(FL_IS_METHOD_CHANNEL(self));
132+
g_return_if_fail(method != nullptr);
133+
134+
g_autoptr(GTask) task =
135+
callback != nullptr ? g_task_new(self, cancellable, callback, user_data)
136+
: nullptr;
137+
138+
g_autoptr(GError) error = nullptr;
139+
g_autoptr(GBytes) message =
140+
fl_method_codec_encode_method_call(self->codec, method, args, &error);
141+
if (message == nullptr) {
142+
if (task != nullptr)
143+
g_task_return_error(task, error);
144+
return;
145+
}
146+
147+
fl_binary_messenger_send_on_channel(
148+
self->messenger, self->name, message, cancellable,
149+
callback != nullptr ? send_on_channel_ready_cb : nullptr,
150+
g_steal_pointer(&task));
151+
}
152+
153+
G_MODULE_EXPORT gboolean fl_method_channel_invoke_finish(FlMethodChannel* self,
154+
GAsyncResult* result,
155+
gchar** error_code,
156+
gchar** error_message,
157+
FlValue** value,
158+
GError** error) {
159+
g_return_val_if_fail(FL_IS_METHOD_CHANNEL(self), FALSE);
160+
g_return_val_if_fail(g_task_is_valid(result, self), FALSE);
161+
g_return_val_if_fail(error_code, FALSE);
162+
163+
g_autoptr(GTask) task = reinterpret_cast<GTask*>(result);
164+
GAsyncResult* r =
165+
static_cast<GAsyncResult*>(g_task_propagate_pointer(task, nullptr));
166+
167+
g_autoptr(GBytes) response =
168+
fl_binary_messenger_send_on_channel_finish(self->messenger, r, error);
169+
if (response == nullptr)
170+
return FALSE;
171+
172+
return fl_method_codec_decode_response(self->codec, response, error_code,
173+
error_message, value, error);
174+
}
175+
176+
G_MODULE_EXPORT gboolean
177+
fl_method_channel_respond(FlMethodChannel* self,
178+
FlMethodChannelResponseHandle* response_handle,
179+
FlValue* result,
180+
GError** error) {
181+
g_return_val_if_fail(FL_IS_METHOD_CHANNEL(self), FALSE);
182+
g_return_val_if_fail(response_handle != nullptr, FALSE);
183+
184+
// Take reference to ensure it is freed
185+
g_autoptr(FlMethodChannelResponseHandle) handle = response_handle;
186+
187+
g_autoptr(GBytes) response =
188+
fl_method_codec_encode_success_envelope(self->codec, result, error);
189+
if (response == nullptr)
190+
return FALSE;
191+
192+
return fl_binary_messenger_send_response(
193+
self->messenger, handle->response_handle, response, error);
194+
}
195+
196+
G_MODULE_EXPORT gboolean
197+
fl_method_channel_respond_error(FlMethodChannel* self,
198+
FlMethodChannelResponseHandle* response_handle,
199+
const gchar* code,
200+
const gchar* message,
201+
FlValue* details,
202+
GError** error) {
203+
g_return_val_if_fail(FL_IS_METHOD_CHANNEL(self), FALSE);
204+
g_return_val_if_fail(response_handle != nullptr, FALSE);
205+
g_return_val_if_fail(code != nullptr, FALSE);
206+
207+
// Take reference to ensure it is freed
208+
g_autoptr(FlMethodChannelResponseHandle) owned_response_handle =
209+
response_handle;
210+
211+
g_autoptr(GBytes) response = fl_method_codec_encode_error_envelope(
212+
self->codec, code, message, details, error);
213+
if (response == nullptr)
214+
return FALSE;
215+
216+
gboolean result = fl_binary_messenger_send_response(
217+
self->messenger, owned_response_handle->response_handle, response, error);
218+
219+
return result;
220+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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_method_codec.h"
6+
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
7+
8+
#include <gmodule.h>
9+
10+
// Added here to stop the compiler from optimising this function away
11+
G_MODULE_EXPORT GType fl_method_codec_get_type();
12+
13+
G_DEFINE_TYPE(FlMethodCodec, fl_method_codec, G_TYPE_OBJECT)
14+
15+
static void fl_method_codec_class_init(FlMethodCodecClass* klass) {}
16+
17+
static void fl_method_codec_init(FlMethodCodec* self) {}
18+
19+
GBytes* fl_method_codec_encode_method_call(FlMethodCodec* self,
20+
const gchar* name,
21+
FlValue* args,
22+
GError** error) {
23+
g_return_val_if_fail(FL_IS_METHOD_CODEC(self), nullptr);
24+
g_return_val_if_fail(name != nullptr, nullptr);
25+
26+
return FL_METHOD_CODEC_GET_CLASS(self)->encode_method_call(self, name, args,
27+
error);
28+
}
29+
30+
gboolean fl_method_codec_decode_method_call(FlMethodCodec* self,
31+
GBytes* message,
32+
gchar** name,
33+
FlValue** args,
34+
GError** error) {
35+
g_return_val_if_fail(FL_IS_METHOD_CODEC(self), FALSE);
36+
g_return_val_if_fail(message != nullptr, FALSE);
37+
g_return_val_if_fail(name != nullptr, FALSE);
38+
g_return_val_if_fail(args != nullptr, FALSE);
39+
40+
return FL_METHOD_CODEC_GET_CLASS(self)->decode_method_call(self, message,
41+
name, args, error);
42+
}
43+
44+
GBytes* fl_method_codec_encode_success_envelope(FlMethodCodec* self,
45+
FlValue* result,
46+
GError** error) {
47+
g_return_val_if_fail(FL_IS_METHOD_CODEC(self), nullptr);
48+
49+
return FL_METHOD_CODEC_GET_CLASS(self)->encode_success_envelope(self, result,
50+
error);
51+
}
52+
53+
GBytes* fl_method_codec_encode_error_envelope(FlMethodCodec* self,
54+
const gchar* code,
55+
const gchar* message,
56+
FlValue* details,
57+
GError** error) {
58+
g_return_val_if_fail(FL_IS_METHOD_CODEC(self), nullptr);
59+
g_return_val_if_fail(code != nullptr, nullptr);
60+
61+
return FL_METHOD_CODEC_GET_CLASS(self)->encode_error_envelope(
62+
self, code, message, details, error);
63+
}
64+
65+
gboolean fl_method_codec_decode_response(FlMethodCodec* self,
66+
GBytes* message,
67+
gchar** error_code,
68+
gchar** error_message,
69+
FlValue** result,
70+
GError** error) {
71+
g_return_val_if_fail(FL_IS_METHOD_CODEC(self), FALSE);
72+
g_return_val_if_fail(message != nullptr, FALSE);
73+
g_return_val_if_fail(error_code != nullptr, FALSE);
74+
g_return_val_if_fail(error_message != nullptr, FALSE);
75+
g_return_val_if_fail(result != nullptr, FALSE);
76+
77+
return FL_METHOD_CODEC_GET_CLASS(self)->decode_response(
78+
self, message, error_code, error_message, result, error);
79+
}

0 commit comments

Comments
 (0)