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

Commit 9907e35

Browse files
committed
Support platform messages in Linux shell
1 parent df4596d commit 9907e35

File tree

12 files changed

+619
-9
lines changed

12 files changed

+619
-9
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,8 @@ FILE: ../../../flutter/shell/platform/glfw/platform_handler.h
11621162
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
11631163
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
11641164
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
1165+
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
1166+
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h
11651167
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
11661168
FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
11671169
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
@@ -1170,6 +1172,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
11701172
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
11711173
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
11721174
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
1175+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h
11731176
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
11741177
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
11751178
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h

shell/platform/linux/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ if (build_glfw_shell) {
4343
}
4444

4545
_public_headers = [
46+
"public/flutter_linux/fl_binary_messenger.h",
4647
"public/flutter_linux/fl_dart_project.h",
48+
"public/flutter_linux/fl_engine.h",
4749
"public/flutter_linux/fl_view.h",
4850
"public/flutter_linux/flutter_linux.h",
4951
]
@@ -56,6 +58,7 @@ source_set("flutter_linux") {
5658
public = _public_headers
5759

5860
sources = [
61+
"fl_binary_messenger.cc",
5962
"fl_dart_project.cc",
6063
"fl_engine.cc",
6164
"fl_renderer.cc",
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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_binary_messenger.h"
6+
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
7+
8+
#include "flutter/shell/platform/linux/fl_engine_private.h"
9+
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
10+
11+
#include <gmodule.h>
12+
13+
struct _FlBinaryMessenger {
14+
GObject parent_instance;
15+
16+
FlEngine* engine;
17+
18+
// PlatformMessageHandler keyed by channel name
19+
GHashTable* platform_message_handlers;
20+
};
21+
22+
G_DEFINE_TYPE(FlBinaryMessenger, fl_binary_messenger, G_TYPE_OBJECT)
23+
24+
typedef struct {
25+
FlBinaryMessengerCallback callback;
26+
gpointer user_data;
27+
} PlatformMessageHandler;
28+
29+
PlatformMessageHandler* platform_message_handler_new(
30+
FlBinaryMessengerCallback callback,
31+
gpointer user_data) {
32+
PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>(
33+
g_malloc0(sizeof(PlatformMessageHandler)));
34+
handler->callback = callback;
35+
handler->user_data = user_data;
36+
return handler;
37+
}
38+
39+
void platform_message_handler_free(gpointer data) {
40+
PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>(data);
41+
g_free(handler);
42+
}
43+
44+
struct _FlBinaryMessengerResponseHandle {
45+
const FlutterPlatformMessageResponseHandle* response_handle;
46+
};
47+
48+
static FlBinaryMessengerResponseHandle* response_handle_new(
49+
const FlutterPlatformMessageResponseHandle* response_handle) {
50+
FlBinaryMessengerResponseHandle* handle =
51+
static_cast<FlBinaryMessengerResponseHandle*>(
52+
g_malloc0(sizeof(FlBinaryMessengerResponseHandle)));
53+
handle->response_handle = response_handle;
54+
55+
return handle;
56+
}
57+
58+
static void response_handle_free(FlBinaryMessengerResponseHandle* handle) {
59+
g_free(handle);
60+
}
61+
62+
typedef struct {
63+
FlBinaryMessenger* self;
64+
GAsyncReadyCallback callback;
65+
gpointer user_data;
66+
} PlatformMessageData;
67+
68+
static PlatformMessageData* platform_message_data_new(
69+
FlBinaryMessenger* self,
70+
GAsyncReadyCallback callback,
71+
gpointer user_data) {
72+
PlatformMessageData* data =
73+
static_cast<PlatformMessageData*>(g_malloc0(sizeof(PlatformMessageData)));
74+
data->self = self;
75+
data->callback = callback;
76+
data->user_data = data->user_data;
77+
78+
return data;
79+
}
80+
81+
static void platform_message_data_free(PlatformMessageData* data) {
82+
g_free(data);
83+
}
84+
85+
static gboolean fl_binary_messenger_platform_message_callback(
86+
FlEngine* engine,
87+
const gchar* channel,
88+
GBytes* message,
89+
const FlutterPlatformMessageResponseHandle* response_handle,
90+
void* user_data) {
91+
FlBinaryMessenger* self = static_cast<FlBinaryMessenger*>(user_data);
92+
93+
FlBinaryMessengerResponseHandle* handle =
94+
response_handle_new(response_handle);
95+
96+
PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>(
97+
g_hash_table_lookup(self->platform_message_handlers, channel));
98+
if (handler == nullptr)
99+
return FALSE;
100+
101+
handler->callback(self, channel, message, handle, handler->user_data);
102+
103+
return TRUE;
104+
}
105+
106+
static void fl_binary_messenger_dispose(GObject* object) {
107+
FlBinaryMessenger* self = FL_BINARY_MESSENGER(object);
108+
109+
g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref);
110+
}
111+
112+
static void fl_binary_messenger_class_init(FlBinaryMessengerClass* klass) {
113+
G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_dispose;
114+
}
115+
116+
static void fl_binary_messenger_init(FlBinaryMessenger* self) {
117+
self->platform_message_handlers = g_hash_table_new_full(
118+
g_str_hash, g_str_equal, g_free, platform_message_handler_free);
119+
}
120+
121+
FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
122+
FlBinaryMessenger* self = static_cast<FlBinaryMessenger*>(
123+
g_object_new(fl_binary_messenger_get_type(), nullptr));
124+
self->engine = engine;
125+
fl_engine_set_platform_message_handler(
126+
engine, fl_binary_messenger_platform_message_callback, self);
127+
return self;
128+
}
129+
130+
G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
131+
FlBinaryMessenger* self,
132+
const gchar* channel,
133+
FlBinaryMessengerCallback callback,
134+
gpointer user_data) {
135+
g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
136+
g_return_if_fail(channel != nullptr);
137+
g_return_if_fail(callback != nullptr);
138+
139+
PlatformMessageHandler* handler =
140+
platform_message_handler_new(callback, user_data);
141+
g_hash_table_replace(self->platform_message_handlers, g_strdup(channel),
142+
handler);
143+
}
144+
145+
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(
146+
FlBinaryMessenger* self,
147+
FlBinaryMessengerResponseHandle* response_handle,
148+
GBytes* response,
149+
GError** error) {
150+
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE);
151+
g_return_val_if_fail(response_handle != nullptr, FALSE);
152+
153+
gboolean result = fl_engine_send_platform_message_response(
154+
self->engine, response_handle->response_handle, response, error);
155+
response_handle_free(response_handle);
156+
157+
return result;
158+
}
159+
160+
static void platform_message_ready_cb(GObject* object,
161+
GAsyncResult* result,
162+
gpointer user_data) {
163+
PlatformMessageData* data = static_cast<PlatformMessageData*>(user_data);
164+
if (data->callback != nullptr)
165+
data->callback(G_OBJECT(data->self), result, data->user_data);
166+
platform_message_data_free(data);
167+
}
168+
169+
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(
170+
FlBinaryMessenger* self,
171+
const gchar* channel,
172+
GBytes* message,
173+
GCancellable* cancellable,
174+
GAsyncReadyCallback callback,
175+
gpointer user_data) {
176+
g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
177+
g_return_if_fail(channel != nullptr);
178+
179+
fl_engine_send_platform_message(
180+
self->engine, channel, message, cancellable, platform_message_ready_cb,
181+
platform_message_data_new(self, callback, user_data));
182+
}
183+
184+
G_MODULE_EXPORT GBytes* fl_binary_messenger_send_on_channel_finish(
185+
FlBinaryMessenger* self,
186+
GAsyncResult* result,
187+
GError** error) {
188+
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE);
189+
g_return_val_if_fail(g_task_is_valid(result, self->engine), FALSE);
190+
191+
return fl_engine_send_platform_message_finish(self->engine, result, error);
192+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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_BINARY_MESSENGER_PRIVATE_H_
6+
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_
7+
8+
#include <glib-object.h>
9+
10+
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
11+
12+
G_BEGIN_DECLS
13+
14+
/**
15+
* fl_binary_messenger_new:
16+
* @engine: The #FlEngine to communicate with.
17+
*
18+
* Create a new #FlBinaryMessenger.
19+
*
20+
* Returns: a new #FlBinaryMessenger.
21+
*/
22+
FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine);
23+
24+
G_END_DECLS
25+
26+
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_

0 commit comments

Comments
 (0)