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

Commit 833cc7b

Browse files
committed
Support platform messages in Linux shell
1 parent 2037e0f commit 833cc7b

File tree

12 files changed

+626
-10
lines changed

12 files changed

+626
-10
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,8 @@ FILE: ../../../flutter/shell/platform/glfw/platform_handler.h
11721172
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
11731173
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
11741174
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
1175+
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
1176+
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h
11751177
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
11761178
FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
11771179
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
@@ -1180,6 +1182,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
11801182
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
11811183
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
11821184
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
1185+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h
11831186
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
11841187
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
11851188
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: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
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 void engine_weak_notify_cb(gpointer user_data, GObject* object) {
49+
FlBinaryMessenger* self = FL_BINARY_MESSENGER(user_data);
50+
self->engine = nullptr;
51+
}
52+
53+
static FlBinaryMessengerResponseHandle* response_handle_new(
54+
const FlutterPlatformMessageResponseHandle* response_handle) {
55+
FlBinaryMessengerResponseHandle* handle =
56+
static_cast<FlBinaryMessengerResponseHandle*>(
57+
g_malloc0(sizeof(FlBinaryMessengerResponseHandle)));
58+
handle->response_handle = response_handle;
59+
60+
return handle;
61+
}
62+
63+
static void response_handle_free(FlBinaryMessengerResponseHandle* handle) {
64+
g_free(handle);
65+
}
66+
67+
static gboolean fl_binary_messenger_platform_message_callback(
68+
FlEngine* engine,
69+
const gchar* channel,
70+
GBytes* message,
71+
const FlutterPlatformMessageResponseHandle* response_handle,
72+
void* user_data) {
73+
FlBinaryMessenger* self = FL_BINARY_MESSENGER(user_data);
74+
75+
FlBinaryMessengerResponseHandle* handle =
76+
response_handle_new(response_handle);
77+
78+
PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>(
79+
g_hash_table_lookup(self->platform_message_handlers, channel));
80+
if (handler == nullptr)
81+
return FALSE;
82+
83+
handler->callback(self, channel, message, handle, handler->user_data);
84+
85+
return TRUE;
86+
}
87+
88+
static void fl_binary_messenger_dispose(GObject* object) {
89+
FlBinaryMessenger* self = FL_BINARY_MESSENGER(object);
90+
91+
if (self->engine != nullptr) {
92+
g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self);
93+
self->engine = nullptr;
94+
}
95+
96+
g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref);
97+
98+
G_OBJECT_CLASS(fl_binary_messenger_parent_class)->dispose(object);
99+
}
100+
101+
static void fl_binary_messenger_class_init(FlBinaryMessengerClass* klass) {
102+
G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_dispose;
103+
}
104+
105+
static void fl_binary_messenger_init(FlBinaryMessenger* self) {
106+
self->platform_message_handlers = g_hash_table_new_full(
107+
g_str_hash, g_str_equal, g_free, platform_message_handler_free);
108+
}
109+
110+
FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
111+
g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr);
112+
113+
FlBinaryMessenger* self = FL_BINARY_MESSENGER(
114+
g_object_new(fl_binary_messenger_get_type(), nullptr));
115+
116+
self->engine = engine;
117+
g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self);
118+
119+
fl_engine_set_platform_message_handler(
120+
engine, fl_binary_messenger_platform_message_callback, self);
121+
122+
return self;
123+
}
124+
125+
G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
126+
FlBinaryMessenger* self,
127+
const gchar* channel,
128+
FlBinaryMessengerCallback callback,
129+
gpointer user_data) {
130+
g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
131+
g_return_if_fail(channel != nullptr);
132+
g_return_if_fail(callback != nullptr);
133+
134+
PlatformMessageHandler* handler =
135+
platform_message_handler_new(callback, user_data);
136+
g_hash_table_replace(self->platform_message_handlers, g_strdup(channel),
137+
handler);
138+
}
139+
140+
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(
141+
FlBinaryMessenger* self,
142+
FlBinaryMessengerResponseHandle* response_handle,
143+
GBytes* response,
144+
GError** error) {
145+
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE);
146+
g_return_val_if_fail(response_handle != nullptr, FALSE);
147+
148+
if (self->engine == nullptr)
149+
return TRUE;
150+
151+
gboolean result = fl_engine_send_platform_message_response(
152+
self->engine, response_handle->response_handle, response, error);
153+
response_handle_free(response_handle);
154+
155+
return result;
156+
}
157+
158+
static void platform_message_ready_cb(GObject* object,
159+
GAsyncResult* result,
160+
gpointer user_data) {
161+
GTask* task = G_TASK(user_data);
162+
g_task_return_pointer(task, result, g_object_unref);
163+
}
164+
165+
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(
166+
FlBinaryMessenger* self,
167+
const gchar* channel,
168+
GBytes* message,
169+
GCancellable* cancellable,
170+
GAsyncReadyCallback callback,
171+
gpointer user_data) {
172+
g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
173+
g_return_if_fail(channel != nullptr);
174+
175+
if (self->engine == nullptr)
176+
return;
177+
178+
fl_engine_send_platform_message(
179+
self->engine, channel, message, cancellable,
180+
callback != nullptr ? platform_message_ready_cb : nullptr,
181+
callback != nullptr ? g_task_new(self, cancellable, callback, user_data)
182+
: nullptr);
183+
}
184+
185+
G_MODULE_EXPORT GBytes* fl_binary_messenger_send_on_channel_finish(
186+
FlBinaryMessenger* self,
187+
GAsyncResult* result,
188+
GError** error) {
189+
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE);
190+
g_return_val_if_fail(g_task_is_valid(result, self), FALSE);
191+
192+
g_autoptr(GTask) task = G_TASK(result);
193+
GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr));
194+
195+
if (self->engine == nullptr)
196+
return nullptr;
197+
198+
return fl_engine_send_platform_message_finish(self->engine, r, error);
199+
}
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)