This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Support platform messages in Linux shell #17995
Merged
robert-ancell
merged 1 commit into
flutter:master
from
robert-ancell:linux-shell-platform-message
May 4, 2020
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h" | ||
| #include "flutter/shell/platform/linux/fl_binary_messenger_private.h" | ||
|
|
||
| #include "flutter/shell/platform/linux/fl_engine_private.h" | ||
| #include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" | ||
|
|
||
| #include <gmodule.h> | ||
|
|
||
| struct _FlBinaryMessenger { | ||
| GObject parent_instance; | ||
|
|
||
| FlEngine* engine; | ||
|
|
||
| // PlatformMessageHandler keyed by channel name | ||
| GHashTable* platform_message_handlers; | ||
| }; | ||
|
|
||
| G_DEFINE_TYPE(FlBinaryMessenger, fl_binary_messenger, G_TYPE_OBJECT) | ||
|
|
||
| typedef struct { | ||
| FlBinaryMessengerCallback callback; | ||
| gpointer user_data; | ||
| } PlatformMessageHandler; | ||
|
|
||
| PlatformMessageHandler* platform_message_handler_new( | ||
| FlBinaryMessengerCallback callback, | ||
| gpointer user_data) { | ||
| PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>( | ||
| g_malloc0(sizeof(PlatformMessageHandler))); | ||
| handler->callback = callback; | ||
| handler->user_data = user_data; | ||
| return handler; | ||
| } | ||
|
|
||
| void platform_message_handler_free(gpointer data) { | ||
| PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>(data); | ||
| g_free(handler); | ||
| } | ||
|
|
||
| struct _FlBinaryMessengerResponseHandle { | ||
| const FlutterPlatformMessageResponseHandle* response_handle; | ||
| }; | ||
|
|
||
| static void engine_weak_notify_cb(gpointer user_data, GObject* object) { | ||
| FlBinaryMessenger* self = FL_BINARY_MESSENGER(user_data); | ||
| self->engine = nullptr; | ||
| } | ||
|
|
||
| static FlBinaryMessengerResponseHandle* response_handle_new( | ||
| const FlutterPlatformMessageResponseHandle* response_handle) { | ||
| FlBinaryMessengerResponseHandle* handle = | ||
| static_cast<FlBinaryMessengerResponseHandle*>( | ||
| g_malloc0(sizeof(FlBinaryMessengerResponseHandle))); | ||
| handle->response_handle = response_handle; | ||
|
|
||
| return handle; | ||
| } | ||
|
|
||
| static void response_handle_free(FlBinaryMessengerResponseHandle* handle) { | ||
| g_free(handle); | ||
| } | ||
|
|
||
| static gboolean fl_binary_messenger_platform_message_callback( | ||
| FlEngine* engine, | ||
| const gchar* channel, | ||
| GBytes* message, | ||
| const FlutterPlatformMessageResponseHandle* response_handle, | ||
| void* user_data) { | ||
| FlBinaryMessenger* self = FL_BINARY_MESSENGER(user_data); | ||
|
|
||
| FlBinaryMessengerResponseHandle* handle = | ||
| response_handle_new(response_handle); | ||
|
|
||
| PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>( | ||
| g_hash_table_lookup(self->platform_message_handlers, channel)); | ||
| if (handler == nullptr) | ||
| return FALSE; | ||
|
|
||
| handler->callback(self, channel, message, handle, handler->user_data); | ||
|
|
||
| return TRUE; | ||
| } | ||
|
|
||
| static void fl_binary_messenger_dispose(GObject* object) { | ||
| FlBinaryMessenger* self = FL_BINARY_MESSENGER(object); | ||
|
|
||
| if (self->engine != nullptr) { | ||
| g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self); | ||
| self->engine = nullptr; | ||
| } | ||
|
|
||
| g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref); | ||
|
|
||
| G_OBJECT_CLASS(fl_binary_messenger_parent_class)->dispose(object); | ||
| } | ||
|
|
||
| static void fl_binary_messenger_class_init(FlBinaryMessengerClass* klass) { | ||
| G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_dispose; | ||
| } | ||
|
|
||
| static void fl_binary_messenger_init(FlBinaryMessenger* self) { | ||
| self->platform_message_handlers = g_hash_table_new_full( | ||
| g_str_hash, g_str_equal, g_free, platform_message_handler_free); | ||
| } | ||
|
|
||
| FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) { | ||
| g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr); | ||
|
|
||
| FlBinaryMessenger* self = FL_BINARY_MESSENGER( | ||
| g_object_new(fl_binary_messenger_get_type(), nullptr)); | ||
|
|
||
| self->engine = engine; | ||
| g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self); | ||
|
|
||
| fl_engine_set_platform_message_handler( | ||
| engine, fl_binary_messenger_platform_message_callback, self); | ||
|
|
||
| return self; | ||
| } | ||
|
|
||
| G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel( | ||
| FlBinaryMessenger* self, | ||
| const gchar* channel, | ||
| FlBinaryMessengerCallback callback, | ||
| gpointer user_data) { | ||
| g_return_if_fail(FL_IS_BINARY_MESSENGER(self)); | ||
| g_return_if_fail(channel != nullptr); | ||
| g_return_if_fail(callback != nullptr); | ||
|
|
||
| PlatformMessageHandler* handler = | ||
| platform_message_handler_new(callback, user_data); | ||
| g_hash_table_replace(self->platform_message_handlers, g_strdup(channel), | ||
| handler); | ||
| } | ||
|
|
||
| G_MODULE_EXPORT gboolean fl_binary_messenger_send_response( | ||
| FlBinaryMessenger* self, | ||
| FlBinaryMessengerResponseHandle* response_handle, | ||
| GBytes* response, | ||
| GError** error) { | ||
| g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE); | ||
| g_return_val_if_fail(response_handle != nullptr, FALSE); | ||
|
|
||
| if (self->engine == nullptr) | ||
| return TRUE; | ||
|
|
||
| gboolean result = fl_engine_send_platform_message_response( | ||
| self->engine, response_handle->response_handle, response, error); | ||
| response_handle_free(response_handle); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| static void platform_message_ready_cb(GObject* object, | ||
| GAsyncResult* result, | ||
| gpointer user_data) { | ||
| GTask* task = G_TASK(user_data); | ||
| g_task_return_pointer(task, result, g_object_unref); | ||
| } | ||
|
|
||
| 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_return_if_fail(FL_IS_BINARY_MESSENGER(self)); | ||
| g_return_if_fail(channel != nullptr); | ||
|
|
||
| if (self->engine == nullptr) | ||
| return; | ||
|
|
||
| fl_engine_send_platform_message( | ||
| self->engine, channel, message, cancellable, | ||
| callback != nullptr ? platform_message_ready_cb : nullptr, | ||
| callback != nullptr ? g_task_new(self, cancellable, callback, user_data) | ||
| : nullptr); | ||
| } | ||
|
|
||
| G_MODULE_EXPORT GBytes* fl_binary_messenger_send_on_channel_finish( | ||
| FlBinaryMessenger* self, | ||
| GAsyncResult* result, | ||
| GError** error) { | ||
| g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE); | ||
| g_return_val_if_fail(g_task_is_valid(result, self), FALSE); | ||
|
|
||
| g_autoptr(GTask) task = G_TASK(result); | ||
| GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr)); | ||
|
|
||
| if (self->engine == nullptr) | ||
| return nullptr; | ||
|
|
||
| return fl_engine_send_platform_message_finish(self->engine, r, error); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_ | ||
| #define FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_ | ||
|
|
||
| #include <glib-object.h> | ||
|
|
||
| #include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" | ||
|
|
||
| G_BEGIN_DECLS | ||
|
|
||
| /** | ||
| * fl_binary_messenger_new: | ||
| * @engine: The #FlEngine to communicate with. | ||
| * | ||
| * Create a new #FlBinaryMessenger. | ||
| * | ||
| * Returns: a new #FlBinaryMessenger. | ||
| */ | ||
| FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine); | ||
|
|
||
robert-ancell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| G_END_DECLS | ||
|
|
||
| #endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_ | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.