From 9d91b943e8fb788f517a5fb222070dca9e9c43c9 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Sun, 16 Aug 2020 14:49:30 -0700 Subject: [PATCH 1/2] Revert "Revert "[windows] Expose the binary messenger from FlutterEngine (#20399)" (#20550)" This reverts commit 3ebcde6a1715e8025e0f61716b3e4115e4cc277e. --- ci/licenses_golden/licenses_flutter | 2 + .../common/cpp/client_wrapper/BUILD.gn | 3 +- .../client_wrapper/binary_messenger_impl.h | 50 ++++++ .../client_wrapper/core_implementations.cc | 150 ++++++++++++++++++ .../cpp/client_wrapper/core_wrapper_files.gni | 17 +- .../client_wrapper/engine_method_result.cc | 46 +----- .../cpp/client_wrapper/plugin_registrar.cc | 115 +------------- .../common/cpp/client_wrapper/publish.gni | 4 +- .../testing/stub_flutter_api.cc | 8 - .../client_wrapper/testing/stub_flutter_api.h | 3 - .../cpp/public/flutter_plugin_registrar.h | 13 -- .../testing/stub_flutter_glfw_api.cc | 8 + .../testing/stub_flutter_glfw_api.h | 3 + shell/platform/glfw/public/flutter_glfw.h | 16 ++ .../platform/windows/client_wrapper/BUILD.gn | 8 +- .../windows/client_wrapper/flutter_engine.cc | 5 + .../flutter_engine_unittests.cc | 10 ++ .../include/flutter/flutter_engine.h | 10 ++ .../testing/stub_flutter_windows_api.cc | 6 + shell/platform/windows/flutter_windows.cc | 7 +- .../windows/flutter_windows_engine.cc | 12 +- .../platform/windows/flutter_windows_engine.h | 5 + .../platform/windows/public/flutter_windows.h | 4 + shell/platform/windows/window_state.h | 2 +- 24 files changed, 314 insertions(+), 193 deletions(-) create mode 100644 shell/platform/common/cpp/client_wrapper/binary_messenger_impl.h create mode 100644 shell/platform/common/cpp/client_wrapper/core_implementations.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 3264b905c063d..b6ffe648568e7 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -836,7 +836,9 @@ FILE: ../../../flutter/shell/platform/android/surface/android_surface_mock.h FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/basic_message_channel_unittests.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/binary_messenger_impl.h FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/byte_buffer_streams.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/core_implementations.cc FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/encodable_value_unittests.cc FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/engine_method_result.cc FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc diff --git a/shell/platform/common/cpp/client_wrapper/BUILD.gn b/shell/platform/common/cpp/client_wrapper/BUILD.gn index e1adbbaf3e510..e84ea9ee7ad7e 100644 --- a/shell/platform/common/cpp/client_wrapper/BUILD.gn +++ b/shell/platform/common/cpp/client_wrapper/BUILD.gn @@ -8,7 +8,8 @@ import("core_wrapper_files.gni") # Client library build for internal use by the shell implementation. source_set("client_wrapper") { sources = core_cpp_client_wrapper_sources - public = core_cpp_client_wrapper_includes + public = core_cpp_client_wrapper_includes + + core_cpp_client_wrapper_internal_headers deps = [ "//flutter/shell/platform/common/cpp:common_cpp_library_headers" ] diff --git a/shell/platform/common/cpp/client_wrapper/binary_messenger_impl.h b/shell/platform/common/cpp/client_wrapper/binary_messenger_impl.h new file mode 100644 index 0000000000000..28fa475c11633 --- /dev/null +++ b/shell/platform/common/cpp/client_wrapper/binary_messenger_impl.h @@ -0,0 +1,50 @@ +// 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_COMMON_CPP_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_ +#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_ + +#include + +#include +#include + +#include "include/flutter/binary_messenger.h" + +namespace flutter { + +// Wrapper around a FlutterDesktopMessengerRef that implements the +// BinaryMessenger API. +class BinaryMessengerImpl : public BinaryMessenger { + public: + explicit BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger); + + virtual ~BinaryMessengerImpl(); + + // Prevent copying. + BinaryMessengerImpl(BinaryMessengerImpl const&) = delete; + BinaryMessengerImpl& operator=(BinaryMessengerImpl const&) = delete; + + // |flutter::BinaryMessenger| + void Send(const std::string& channel, + const uint8_t* message, + size_t message_size, + BinaryReply reply) const override; + + // |flutter::BinaryMessenger| + void SetMessageHandler(const std::string& channel, + BinaryMessageHandler handler) override; + + private: + // Handle for interacting with the C API. + FlutterDesktopMessengerRef messenger_; + + // A map from channel names to the BinaryMessageHandler that should be called + // for incoming messages on that channel. + std::map handlers_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_ diff --git a/shell/platform/common/cpp/client_wrapper/core_implementations.cc b/shell/platform/common/cpp/client_wrapper/core_implementations.cc new file mode 100644 index 0000000000000..2cafc7f9fe3a5 --- /dev/null +++ b/shell/platform/common/cpp/client_wrapper/core_implementations.cc @@ -0,0 +1,150 @@ +// 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. + +// This file contains the implementations of any class in the wrapper that +// - is not fully inline, and +// - is necessary for all clients of the wrapper (either app or plugin). +// It exists instead of the usual structure of having some_class_name.cc files +// so that changes to the set of things that need non-header implementations +// are not breaking changes for the template. +// +// If https://github.com/flutter/flutter/issues/57146 is fixed, this can be +// removed in favor of the normal structure since templates will no longer +// manually include files. + +#include + +#include + +#include "binary_messenger_impl.h" +#include "include/flutter/engine_method_result.h" + +namespace flutter { + +// ========== binary_messenger_impl.h ========== + +namespace { +// Passes |message| to |user_data|, which must be a BinaryMessageHandler, along +// with a BinaryReply that will send a response on |message|'s response handle. +// +// This serves as an adaptor between the function-pointer-based message callback +// interface provided by the C API and the std::function-based message handler +// interface of BinaryMessenger. +void ForwardToHandler(FlutterDesktopMessengerRef messenger, + const FlutterDesktopMessage* message, + void* user_data) { + auto* response_handle = message->response_handle; + BinaryReply reply_handler = [messenger, response_handle]( + const uint8_t* reply, + size_t reply_size) mutable { + if (!response_handle) { + std::cerr << "Error: Response can be set only once. Ignoring " + "duplicate response." + << std::endl; + return; + } + FlutterDesktopMessengerSendResponse(messenger, response_handle, reply, + reply_size); + // The engine frees the response handle once + // FlutterDesktopSendMessageResponse is called. + response_handle = nullptr; + }; + + const BinaryMessageHandler& message_handler = + *static_cast(user_data); + + message_handler(message->message, message->message_size, + std::move(reply_handler)); +} +} // namespace + +BinaryMessengerImpl::BinaryMessengerImpl( + FlutterDesktopMessengerRef core_messenger) + : messenger_(core_messenger) {} + +BinaryMessengerImpl::~BinaryMessengerImpl() = default; + +void BinaryMessengerImpl::Send(const std::string& channel, + const uint8_t* message, + size_t message_size, + BinaryReply reply) const { + if (reply == nullptr) { + FlutterDesktopMessengerSend(messenger_, channel.c_str(), message, + message_size); + return; + } + struct Captures { + BinaryReply reply; + }; + auto captures = new Captures(); + captures->reply = reply; + + auto message_reply = [](const uint8_t* data, size_t data_size, + void* user_data) { + auto captures = reinterpret_cast(user_data); + captures->reply(data, data_size); + delete captures; + }; + bool result = FlutterDesktopMessengerSendWithReply( + messenger_, channel.c_str(), message, message_size, message_reply, + captures); + if (!result) { + delete captures; + } +} + +void BinaryMessengerImpl::SetMessageHandler(const std::string& channel, + BinaryMessageHandler handler) { + if (!handler) { + handlers_.erase(channel); + FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr, + nullptr); + return; + } + // Save the handler, to keep it alive. + handlers_[channel] = std::move(handler); + BinaryMessageHandler* message_handler = &handlers_[channel]; + // Set an adaptor callback that will invoke the handler. + FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), + ForwardToHandler, message_handler); +} + +// ========== engine_method_result.h ========== + +namespace internal { + +ReplyManager::ReplyManager(BinaryReply reply_handler) + : reply_handler_(std::move(reply_handler)) { + assert(reply_handler_); +} + +ReplyManager::~ReplyManager() { + if (reply_handler_) { + // Warn, rather than send a not-implemented response, since the engine may + // no longer be valid at this point. + std::cerr + << "Warning: Failed to respond to a message. This is a memory leak." + << std::endl; + } +} + +void ReplyManager::SendResponseData(const std::vector* data) { + if (!reply_handler_) { + std::cerr + << "Error: Only one of Success, Error, or NotImplemented can be " + "called," + << " and it can be called exactly once. Ignoring duplicate result." + << std::endl; + return; + } + + const uint8_t* message = data && !data->empty() ? data->data() : nullptr; + size_t message_size = data ? data->size() : 0; + reply_handler_(message, message_size); + reply_handler_ = nullptr; +} + +} // namespace internal + +} // namespace flutter diff --git a/shell/platform/common/cpp/client_wrapper/core_wrapper_files.gni b/shell/platform/common/cpp/client_wrapper/core_wrapper_files.gni index f86d87e024313..264bf774e6111 100644 --- a/shell/platform/common/cpp/client_wrapper/core_wrapper_files.gni +++ b/shell/platform/common/cpp/client_wrapper/core_wrapper_files.gni @@ -27,13 +27,26 @@ core_cpp_client_wrapper_includes = ], "abspath") +# Headers that aren't public for clients of the wrapper, but are considered +# public for the purpose of BUILD dependencies (e.g., to allow +# windows/client_wrapper implementation files to include them). +core_cpp_client_wrapper_internal_headers = + get_path_info([ + "binary_messenger_impl.h", + "byte_buffer_streams.h", + ], + "abspath") + # TODO: Once the wrapper API is more stable, consolidate to as few files as is # reasonable (without forcing different kinds of clients to take unnecessary # code) to simplify use. core_cpp_client_wrapper_sources = get_path_info([ - "byte_buffer_streams.h", - "engine_method_result.cc", + "core_implementations.cc", "plugin_registrar.cc", "standard_codec.cc", ], "abspath") + +# Temporary shim, published for backwards compatibility. +# See comment in the file for more detail. +temporary_shim_files = get_path_info([ "engine_method_result.cc" ], "abspath") diff --git a/shell/platform/common/cpp/client_wrapper/engine_method_result.cc b/shell/platform/common/cpp/client_wrapper/engine_method_result.cc index 03e17a82e6bd5..65eaf5d4358cb 100644 --- a/shell/platform/common/cpp/client_wrapper/engine_method_result.cc +++ b/shell/platform/common/cpp/client_wrapper/engine_method_result.cc @@ -2,44 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "include/flutter/engine_method_result.h" +// This file is deprecated in favor of core_implementations.cc. This is a +// temporary forwarding implementation so that the switch to +// core_implementations.cc isn't an immediate breaking change, allowing for the +// template to be updated to include it and update the template version before +// removing this file. -#include -#include - -namespace flutter { -namespace internal { - -ReplyManager::ReplyManager(BinaryReply reply_handler) - : reply_handler_(std::move(reply_handler)) { - assert(reply_handler_); -} - -ReplyManager::~ReplyManager() { - if (reply_handler_) { - // Warn, rather than send a not-implemented response, since the engine may - // no longer be valid at this point. - std::cerr - << "Warning: Failed to respond to a message. This is a memory leak." - << std::endl; - } -} - -void ReplyManager::SendResponseData(const std::vector* data) { - if (!reply_handler_) { - std::cerr - << "Error: Only one of Success, Error, or NotImplemented can be " - "called," - << " and it can be called exactly once. Ignoring duplicate result." - << std::endl; - return; - } - - const uint8_t* message = data && !data->empty() ? data->data() : nullptr; - size_t message_size = data ? data->size() : 0; - reply_handler_(message, message_size); - reply_handler_ = nullptr; -} - -} // namespace internal -} // namespace flutter +#include "core_implementations.cc" diff --git a/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc b/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc index 7cdd6af903ae2..a779d6e26df53 100644 --- a/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc +++ b/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc @@ -7,125 +7,12 @@ #include #include +#include "binary_messenger_impl.h" #include "include/flutter/engine_method_result.h" #include "include/flutter/method_channel.h" namespace flutter { -namespace { - -// Passes |message| to |user_data|, which must be a BinaryMessageHandler, along -// with a BinaryReply that will send a response on |message|'s response handle. -// -// This serves as an adaptor between the function-pointer-based message callback -// interface provided by the C API and the std::function-based message handler -// interface of BinaryMessenger. -void ForwardToHandler(FlutterDesktopMessengerRef messenger, - const FlutterDesktopMessage* message, - void* user_data) { - auto* response_handle = message->response_handle; - BinaryReply reply_handler = [messenger, response_handle]( - const uint8_t* reply, - size_t reply_size) mutable { - if (!response_handle) { - std::cerr << "Error: Response can be set only once. Ignoring " - "duplicate response." - << std::endl; - return; - } - FlutterDesktopMessengerSendResponse(messenger, response_handle, reply, - reply_size); - // The engine frees the response handle once - // FlutterDesktopSendMessageResponse is called. - response_handle = nullptr; - }; - - const BinaryMessageHandler& message_handler = - *static_cast(user_data); - - message_handler(message->message, message->message_size, - std::move(reply_handler)); -} - -} // namespace - -// Wrapper around a FlutterDesktopMessengerRef that implements the -// BinaryMessenger API. -class BinaryMessengerImpl : public BinaryMessenger { - public: - explicit BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger) - : messenger_(core_messenger) {} - - virtual ~BinaryMessengerImpl() = default; - - // Prevent copying. - BinaryMessengerImpl(BinaryMessengerImpl const&) = delete; - BinaryMessengerImpl& operator=(BinaryMessengerImpl const&) = delete; - - // |flutter::BinaryMessenger| - void Send(const std::string& channel, - const uint8_t* message, - size_t message_size, - BinaryReply reply) const override; - - // |flutter::BinaryMessenger| - void SetMessageHandler(const std::string& channel, - BinaryMessageHandler handler) override; - - private: - // Handle for interacting with the C API. - FlutterDesktopMessengerRef messenger_; - - // A map from channel names to the BinaryMessageHandler that should be called - // for incoming messages on that channel. - std::map handlers_; -}; - -void BinaryMessengerImpl::Send(const std::string& channel, - const uint8_t* message, - size_t message_size, - BinaryReply reply) const { - if (reply == nullptr) { - FlutterDesktopMessengerSend(messenger_, channel.c_str(), message, - message_size); - return; - } - struct Captures { - BinaryReply reply; - }; - auto captures = new Captures(); - captures->reply = reply; - - auto message_reply = [](const uint8_t* data, size_t data_size, - void* user_data) { - auto captures = reinterpret_cast(user_data); - captures->reply(data, data_size); - delete captures; - }; - bool result = FlutterDesktopMessengerSendWithReply( - messenger_, channel.c_str(), message, message_size, message_reply, - captures); - if (!result) { - delete captures; - } -} - -void BinaryMessengerImpl::SetMessageHandler(const std::string& channel, - BinaryMessageHandler handler) { - if (!handler) { - handlers_.erase(channel); - FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr, - nullptr); - return; - } - // Save the handler, to keep it alive. - handlers_[channel] = std::move(handler); - BinaryMessageHandler* message_handler = &handlers_[channel]; - // Set an adaptor callback that will invoke the handler. - FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), - ForwardToHandler, message_handler); -} - // ===== PluginRegistrar ===== PluginRegistrar::PluginRegistrar(FlutterDesktopPluginRegistrarRef registrar) diff --git a/shell/platform/common/cpp/client_wrapper/publish.gni b/shell/platform/common/cpp/client_wrapper/publish.gni index e52bf6a319369..907197b6cced6 100644 --- a/shell/platform/common/cpp/client_wrapper/publish.gni +++ b/shell/platform/common/cpp/client_wrapper/publish.gni @@ -71,7 +71,9 @@ template("publish_client_wrapper_core") { "visibility", ]) public = core_cpp_client_wrapper_includes - sources = core_cpp_client_wrapper_sources + [ _wrapper_readme ] + sources = core_cpp_client_wrapper_sources + + core_cpp_client_wrapper_internal_headers + [ _wrapper_readme ] + + temporary_shim_files } } diff --git a/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.cc b/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.cc index 580df48645aa9..1f60548952249 100644 --- a/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.cc +++ b/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.cc @@ -52,14 +52,6 @@ void FlutterDesktopRegistrarSetDestructionHandler( } } -void FlutterDesktopRegistrarEnableInputBlocking( - FlutterDesktopPluginRegistrarRef registrar, - const char* channel) { - if (s_stub_implementation) { - s_stub_implementation->RegistrarEnableInputBlocking(channel); - } -} - bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char* channel, const uint8_t* message, diff --git a/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h b/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h index 284d15e974947..ae55cdc9010f0 100644 --- a/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h +++ b/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h @@ -38,9 +38,6 @@ class StubFlutterApi { virtual void RegistrarSetDestructionHandler( FlutterDesktopOnRegistrarDestroyed callback) {} - // Called for FlutterDesktopRegistrarEnableInputBlocking. - virtual void RegistrarEnableInputBlocking(const char* channel) {} - // Called for FlutterDesktopMessengerSend. virtual bool MessengerSend(const char* channel, const uint8_t* message, diff --git a/shell/platform/common/cpp/public/flutter_plugin_registrar.h b/shell/platform/common/cpp/public/flutter_plugin_registrar.h index 95f0abf139608..e27e125530ac9 100644 --- a/shell/platform/common/cpp/public/flutter_plugin_registrar.h +++ b/shell/platform/common/cpp/public/flutter_plugin_registrar.h @@ -31,19 +31,6 @@ FLUTTER_EXPORT void FlutterDesktopRegistrarSetDestructionHandler( FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopOnRegistrarDestroyed callback); -// Enables input blocking on the given channel. -// -// If set, then the Flutter window will disable input callbacks -// while waiting for the handler for messages on that channel to run. This is -// useful if handling the message involves showing a modal window, for instance. -// -// This must be called after FlutterDesktopSetMessageHandler, as setting a -// handler on a channel will reset the input blocking state back to the -// default of disabled. -FLUTTER_EXPORT void FlutterDesktopRegistrarEnableInputBlocking( - FlutterDesktopPluginRegistrarRef registrar, - const char* channel); - #if defined(__cplusplus) } // extern "C" #endif diff --git a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc index 38614fc15c554..8875a1b51d23d 100644 --- a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc +++ b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc @@ -182,3 +182,11 @@ FlutterDesktopPluginRegistrarRef FlutterDesktopGetPluginRegistrar( // The stub ignores this, so just return an arbitrary non-zero value. return reinterpret_cast(2); } + +void FlutterDesktopRegistrarEnableInputBlocking( + FlutterDesktopPluginRegistrarRef registrar, + const char* channel) { + if (s_stub_implementation) { + s_stub_implementation->RegistrarEnableInputBlocking(channel); + } +} diff --git a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h index 25792e8c14be1..765a02e45f7f5 100644 --- a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h +++ b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h @@ -88,6 +88,9 @@ class StubFlutterGlfwApi { // Called for FlutterDesktopShutDownEngine. virtual bool ShutDownEngine() { return true; } + + // Called for FlutterDesktopRegistrarEnableInputBlocking. + virtual void RegistrarEnableInputBlocking(const char* channel) {} }; // A test helper that owns a stub implementation, making it the test stub for diff --git a/shell/platform/glfw/public/flutter_glfw.h b/shell/platform/glfw/public/flutter_glfw.h index 45a6420f93c87..e8b4513877852 100644 --- a/shell/platform/glfw/public/flutter_glfw.h +++ b/shell/platform/glfw/public/flutter_glfw.h @@ -219,10 +219,26 @@ FLUTTER_EXPORT bool FlutterDesktopShutDownEngine( FlutterDesktopEngineRef engine); // Returns the window associated with this registrar's engine instance. +// // This is a GLFW shell-specific extension to flutter_plugin_registrar.h FLUTTER_EXPORT FlutterDesktopWindowRef FlutterDesktopRegistrarGetWindow(FlutterDesktopPluginRegistrarRef registrar); +// Enables input blocking on the given channel. +// +// If set, then the Flutter window will disable input callbacks +// while waiting for the handler for messages on that channel to run. This is +// useful if handling the message involves showing a modal window, for instance. +// +// This must be called after FlutterDesktopSetMessageHandler, as setting a +// handler on a channel will reset the input blocking state back to the +// default of disabled. +// +// This is a GLFW shell-specific extension to flutter_plugin_registrar.h +FLUTTER_EXPORT void FlutterDesktopRegistrarEnableInputBlocking( + FlutterDesktopPluginRegistrarRef registrar, + const char* channel); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/shell/platform/windows/client_wrapper/BUILD.gn b/shell/platform/windows/client_wrapper/BUILD.gn index 27f8fb77a24c2..fe54c2ba2a484 100644 --- a/shell/platform/windows/client_wrapper/BUILD.gn +++ b/shell/platform/windows/client_wrapper/BUILD.gn @@ -20,10 +20,12 @@ _wrapper_sources = [ # This code will be merged into .../common/cpp/client_wrapper for client use, # so uses header paths that assume the merged state. Include the header -# header directory of the core wrapper files so these includes will work. +# directories of the core wrapper files so these includes will work. config("relative_core_wrapper_headers") { - include_dirs = - [ "//flutter/shell/platform/common/cpp/client_wrapper/include/flutter" ] + include_dirs = [ + "//flutter/shell/platform/common/cpp/client_wrapper", + "//flutter/shell/platform/common/cpp/client_wrapper/include/flutter", + ] } # Windows client wrapper build for internal use by the shell implementation. diff --git a/shell/platform/windows/client_wrapper/flutter_engine.cc b/shell/platform/windows/client_wrapper/flutter_engine.cc index 1f55ed8077b80..8bf94420646c7 100644 --- a/shell/platform/windows/client_wrapper/flutter_engine.cc +++ b/shell/platform/windows/client_wrapper/flutter_engine.cc @@ -7,6 +7,8 @@ #include #include +#include "binary_messenger_impl.h" + namespace flutter { FlutterEngine::FlutterEngine(const DartProject& project) { @@ -25,6 +27,9 @@ FlutterEngine::FlutterEngine(const DartProject& project) { } engine_ = FlutterDesktopEngineCreate(c_engine_properties); + + auto core_messenger = FlutterDesktopEngineGetMessenger(engine_); + messenger_ = std::make_unique(core_messenger); } FlutterEngine::~FlutterEngine() { diff --git a/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc b/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc index 05880ebf50436..8fe83225b114f 100644 --- a/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc +++ b/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc @@ -93,4 +93,14 @@ TEST(FlutterEngineTest, ProcessMessages) { EXPECT_EQ(next_event_time.count(), 99); } +TEST(FlutterEngineTest, GetMessenger) { + DartProject project(L"data"); + testing::ScopedStubFlutterWindowsApi scoped_api_stub( + std::make_unique()); + auto test_api = static_cast(scoped_api_stub.stub()); + + FlutterEngine engine(DartProject(L"fake/project/path")); + EXPECT_NE(engine.messenger(), nullptr); +} + } // namespace flutter diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h index b4e3ee1b0cbff..94edb4064dd2c 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h @@ -12,6 +12,7 @@ #include #include +#include "binary_messenger.h" #include "dart_project.h" #include "plugin_registrar.h" #include "plugin_registry.h" @@ -57,6 +58,12 @@ class FlutterEngine : public PluginRegistry { FlutterDesktopPluginRegistrarRef GetRegistrarForPlugin( const std::string& plugin_name) override; + // Returns the messenger to use for creating channels to communicate with the + // Flutter engine. + // + // This pointer will remain valid for the lifetime of this instance. + BinaryMessenger* messenger() { return messenger_.get(); } + private: // For access to RelinquishEngine. friend class FlutterViewController; @@ -70,6 +77,9 @@ class FlutterEngine : public PluginRegistry { // Handle for interacting with the C API's engine reference. FlutterDesktopEngineRef engine_ = nullptr; + // Messenger for communicating with the engine. + std::unique_ptr messenger_; + // Whether or not this wrapper owns |engine_|. bool owns_engine_ = true; diff --git a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc index c8cd7a8299fe1..de8b54902a6b6 100644 --- a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc +++ b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc @@ -101,6 +101,12 @@ FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar( return reinterpret_cast(1); } +FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger( + FlutterDesktopEngineRef engine) { + // The stub ignores this, so just return an arbitrary non-zero value. + return reinterpret_cast(2); +} + HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef controller) { if (s_stub_implementation) { return s_stub_implementation->ViewGetHWND(); diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index ce7b82308ff75..57b641e3fc8a1 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -119,6 +119,11 @@ FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar( return EngineFromHandle(engine)->GetRegistrar(); } +FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger( + FlutterDesktopEngineRef engine) { + return EngineFromHandle(engine)->messenger(); +} + HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view_ref) { return std::get(*view_ref->view->GetRenderTarget()); } @@ -151,7 +156,7 @@ void FlutterDesktopResyncOutputStreams() { FlutterDesktopMessengerRef FlutterDesktopRegistrarGetMessenger( FlutterDesktopPluginRegistrarRef registrar) { - return registrar->messenger.get(); + return registrar->messenger; } void FlutterDesktopRegistrarSetDestructionHandler( diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 957c9432d8cb2..0dca78da26948 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -85,15 +85,15 @@ FlutterWindowsEngine::FlutterWindowsEngine(const FlutterProjectBundle& project) } }); - // Set up the structure of the state/handle objects; engine and view paramater - // will be filled in late. - auto messenger = std::make_unique(); + // Set up the structure of the state/handle objects; engine and view + // paramaters will be filled in later. + messenger_ = std::make_unique(); message_dispatcher_ = - std::make_unique(messenger.get()); - messenger->dispatcher = message_dispatcher_.get(); + std::make_unique(messenger_.get()); + messenger_->dispatcher = message_dispatcher_.get(); plugin_registrar_ = std::make_unique(); - plugin_registrar_->messenger = std::move(messenger); + plugin_registrar_->messenger = messenger_.get(); plugin_registrar_->view = std::make_unique(); } diff --git a/shell/platform/windows/flutter_windows_engine.h b/shell/platform/windows/flutter_windows_engine.h index 61784a76f8083..53e65f429e77e 100644 --- a/shell/platform/windows/flutter_windows_engine.h +++ b/shell/platform/windows/flutter_windows_engine.h @@ -60,6 +60,8 @@ class FlutterWindowsEngine { FLUTTER_API_SYMBOL(FlutterEngine) engine() { return engine_; } + FlutterDesktopMessengerRef messenger() { return messenger_.get(); } + Win32TaskRunner* task_runner() { return task_runner_.get(); } // Callback passed to Flutter engine for notifying window of platform @@ -81,6 +83,9 @@ class FlutterWindowsEngine { // Task runner for tasks posted from the engine. std::unique_ptr task_runner_; + // The plugin messenger handle given to API clients. + std::unique_ptr messenger_; + // Message dispatch manager for messages from engine_. std::unique_ptr message_dispatcher_; diff --git a/shell/platform/windows/public/flutter_windows.h b/shell/platform/windows/public/flutter_windows.h index 544aa6888f8d8..7cd0b89f2fb6a 100644 --- a/shell/platform/windows/public/flutter_windows.h +++ b/shell/platform/windows/public/flutter_windows.h @@ -136,6 +136,10 @@ FLUTTER_EXPORT FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char* plugin_name); +// Returns the messenger associated with the engine. +FLUTTER_EXPORT FlutterDesktopMessengerRef +FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); + // ========== View ========== // Return backing HWND for manipulation in host application. diff --git a/shell/platform/windows/window_state.h b/shell/platform/windows/window_state.h index 5807905109781..08fb538505093 100644 --- a/shell/platform/windows/window_state.h +++ b/shell/platform/windows/window_state.h @@ -35,7 +35,7 @@ struct FlutterDesktopView { // State associated with the plugin registrar. struct FlutterDesktopPluginRegistrar { // The plugin messenger handle given to API clients. - std::unique_ptr messenger; + FlutterDesktopMessenger* messenger; // The handle for the view associated with this registrar. std::unique_ptr view; From 4c2fc9983cc93896bb733f37426f452a1b4877b0 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Sun, 16 Aug 2020 14:54:54 -0700 Subject: [PATCH 2/2] Update to restructure the legacy target as well --- shell/platform/common/cpp/client_wrapper/BUILD.gn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/common/cpp/client_wrapper/BUILD.gn b/shell/platform/common/cpp/client_wrapper/BUILD.gn index e84ea9ee7ad7e..6c297103d4360 100644 --- a/shell/platform/common/cpp/client_wrapper/BUILD.gn +++ b/shell/platform/common/cpp/client_wrapper/BUILD.gn @@ -24,7 +24,8 @@ source_set("client_wrapper") { # legacy version is removed. source_set("client_wrapper_legacy_encodable_value") { sources = core_cpp_client_wrapper_sources - public = core_cpp_client_wrapper_includes + public = core_cpp_client_wrapper_includes + + core_cpp_client_wrapper_internal_headers deps = [ "//flutter/shell/platform/common/cpp:common_cpp_library_headers" ]