From 80190580d519cc3933a552d4aa7fe00822769e19 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Tue, 1 Sep 2020 13:56:46 -0400 Subject: [PATCH] Default C++ wrapper templates to EncodableValue (#20760) The C++ wrapper makes heavy use of templates to support arbitrary types in the platform channel classes, but in practice EncodableValue is what essentially all code will use. This defaults those template types to reduce boilerplate in plugin code (e.g., allowing the use of MethodChannel<> instead of MethodChannel). --- .../client_wrapper/event_channel_unittests.cc | 71 ++++++++----------- .../include/flutter/basic_message_channel.h | 4 +- .../include/flutter/event_channel.h | 4 +- .../include/flutter/event_sink.h | 4 +- .../include/flutter/event_stream_handler.h | 6 +- .../flutter/event_stream_handler_functions.h | 4 +- .../include/flutter/method_call.h | 4 +- .../include/flutter/method_channel.h | 4 +- .../include/flutter/method_result.h | 4 +- .../include/flutter/method_result_functions.h | 4 +- .../method_channel_unittests.cc | 17 +++-- .../standard_method_codec_unittests.cc | 33 ++++----- 12 files changed, 78 insertions(+), 81 deletions(-) diff --git a/shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc b/shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc index b06ff03f8dfdf..f70d2e81749b0 100644 --- a/shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc +++ b/shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h" - #include #include #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h" +#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h" #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler_functions.h" #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h" #include "gtest/gtest.h" @@ -51,25 +50,21 @@ TEST(EventChannelTest, Registration) { EventChannel channel(&messenger, channel_name, &codec); bool on_listen_called = false; - auto handler = std::make_unique< - flutter::StreamHandlerFunctions>( - [&on_listen_called]( - const flutter::EncodableValue* arguments, - std::unique_ptr>&& events) - -> std::unique_ptr> { + auto handler = std::make_unique>( + [&on_listen_called](const EncodableValue* arguments, + std::unique_ptr>&& events) + -> std::unique_ptr> { on_listen_called = true; return nullptr; }, - [](const flutter::EncodableValue* arguments) - -> std::unique_ptr> { - return nullptr; - }); + [](const EncodableValue* arguments) + -> std::unique_ptr> { return nullptr; }); channel.SetStreamHandler(std::move(handler)); EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); EXPECT_NE(messenger.last_message_handler(), nullptr); // Send dummy listen message. - MethodCall call("listen", nullptr); + MethodCall<> call("listen", nullptr); auto message = codec.EncodeMethodCall(call); messenger.last_message_handler()( message->data(), message->size(), @@ -86,17 +81,11 @@ TEST(EventChannelTest, Unregistration) { const StandardMethodCodec& codec = StandardMethodCodec::GetInstance(); EventChannel channel(&messenger, channel_name, &codec); - auto handler = std::make_unique< - flutter::StreamHandlerFunctions>( - [](const flutter::EncodableValue* arguments, - std::unique_ptr>&& events) - -> std::unique_ptr> { - return nullptr; - }, - [](const flutter::EncodableValue* arguments) - -> std::unique_ptr> { - return nullptr; - }); + auto handler = std::make_unique>( + [](const EncodableValue* arguments, std::unique_ptr>&& events) + -> std::unique_ptr> { return nullptr; }, + [](const EncodableValue* arguments) + -> std::unique_ptr> { return nullptr; }); channel.SetStreamHandler(std::move(handler)); EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); EXPECT_NE(messenger.last_message_handler(), nullptr); @@ -115,17 +104,15 @@ TEST(EventChannelTest, Cancel) { bool on_listen_called = false; bool on_cancel_called = false; - auto handler = std::make_unique< - flutter::StreamHandlerFunctions>( - [&on_listen_called]( - const flutter::EncodableValue* arguments, - std::unique_ptr>&& events) - -> std::unique_ptr> { + auto handler = std::make_unique>( + [&on_listen_called](const EncodableValue* arguments, + std::unique_ptr>&& events) + -> std::unique_ptr> { on_listen_called = true; return nullptr; }, - [&on_cancel_called](const flutter::EncodableValue* arguments) - -> std::unique_ptr> { + [&on_cancel_called](const EncodableValue* arguments) + -> std::unique_ptr> { on_cancel_called = true; return nullptr; }); @@ -134,7 +121,7 @@ TEST(EventChannelTest, Cancel) { EXPECT_NE(messenger.last_message_handler(), nullptr); // Send dummy listen message. - MethodCall call_listen("listen", nullptr); + MethodCall<> call_listen("listen", nullptr); auto message = codec.EncodeMethodCall(call_listen); messenger.last_message_handler()( message->data(), message->size(), @@ -142,7 +129,7 @@ TEST(EventChannelTest, Cancel) { EXPECT_EQ(on_listen_called, true); // Send dummy cancel message. - MethodCall call_cancel("cancel", nullptr); + MethodCall<> call_cancel("cancel", nullptr); message = codec.EncodeMethodCall(call_cancel); messenger.last_message_handler()( message->data(), message->size(), @@ -164,17 +151,15 @@ TEST(EventChannelTest, ReRegistration) { bool on_listen_called = false; bool on_cancel_called = false; - auto handler = std::make_unique< - flutter::StreamHandlerFunctions>( - [&on_listen_called]( - const flutter::EncodableValue* arguments, - std::unique_ptr>&& events) - -> std::unique_ptr> { + auto handler = std::make_unique>( + [&on_listen_called](const EncodableValue* arguments, + std::unique_ptr>&& events) + -> std::unique_ptr> { on_listen_called = true; return nullptr; }, - [&on_cancel_called](const flutter::EncodableValue* arguments) - -> std::unique_ptr> { + [&on_cancel_called](const EncodableValue* arguments) + -> std::unique_ptr> { on_cancel_called = true; return nullptr; }); @@ -183,7 +168,7 @@ TEST(EventChannelTest, ReRegistration) { EXPECT_NE(messenger.last_message_handler(), nullptr); // Send dummy listen message. - MethodCall call("listen", nullptr); + MethodCall<> call("listen", nullptr); auto message = codec.EncodeMethodCall(call); messenger.last_message_handler()( message->data(), message->size(), diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h b/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h index 1aca146eff3cd..756cfb9a5e3f7 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h @@ -13,6 +13,8 @@ namespace flutter { +class EncodableValue; + // A message reply callback. // // Used for submitting a reply back to a Flutter message sender. @@ -29,7 +31,7 @@ using MessageHandler = // A channel for communicating with the Flutter engine by sending asynchronous // messages. -template +template class BasicMessageChannel { public: // Creates an instance that sends and receives method calls on the channel diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h b/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h index 23fd7940752db..cda97d5776015 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h @@ -16,6 +16,8 @@ namespace flutter { +class EncodableValue; + // A named channel for communicating with the Flutter application using // asynchronous event streams. Incoming requests for event stream setup are // decoded from binary on receipt, and C++ responses and events are encoded into @@ -27,7 +29,7 @@ namespace flutter { // The C++ type of stream configuration arguments, events, and error details are // templated, but only values supported by the specified MethodCodec can be // used. -template +template class EventChannel { public: // Creates an instance that sends and receives event handler on the channel diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/event_sink.h b/shell/platform/common/cpp/client_wrapper/include/flutter/event_sink.h index 764ea9d9f1fb8..8c3a3d9fc0351 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/event_sink.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/event_sink.h @@ -7,9 +7,11 @@ namespace flutter { +class EncodableValue; + // Event callback. Events to be sent to Flutter application // act as clients of this interface for sending events. -template +template class EventSink { public: EventSink() = default; diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler.h b/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler.h index 50d57b887f029..99b8f2e6447cc 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler.h @@ -9,7 +9,9 @@ namespace flutter { -template +class EncodableValue; + +template struct StreamHandlerError { const std::string& error_code; const std::string& error_message; @@ -29,7 +31,7 @@ struct StreamHandlerError { // resources when the last such call is not OnListen(). In typical situations, // this means that the implementation should register itself with // platform-specific event sources OnListen() and deregister again OnCancel(). -template +template class StreamHandler { public: StreamHandler() = default; diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler_functions.h b/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler_functions.h index 88fe8a1bc3639..df57b071e57e0 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler_functions.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/event_stream_handler_functions.h @@ -12,6 +12,8 @@ namespace flutter { +class EncodableValue; + // Handler types for each of the StreamHandler setup and tear-down // requests. template @@ -26,7 +28,7 @@ using StreamHandlerCancel = // An implementation of StreamHandler that pass calls through to // provided function objects. -template +template class StreamHandlerFunctions : public StreamHandler { public: // Creates a handler object that calls the provided functions diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/method_call.h b/shell/platform/common/cpp/client_wrapper/include/flutter/method_call.h index 80274e7b0c5b0..01059e94ae5ce 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/method_call.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/method_call.h @@ -10,9 +10,11 @@ namespace flutter { +class EncodableValue; + // An object encapsulating a method call from Flutter whose arguments are of // type T. -template +template class MethodCall { public: // Creates a MethodCall with the given name and arguments. diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h b/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h index 0fe94701c963b..3f73430507ffa 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h @@ -16,6 +16,8 @@ namespace flutter { +class EncodableValue; + // A handler for receiving a method call from the Flutter engine. // // Implementations must asynchronously call exactly one of the methods on @@ -27,7 +29,7 @@ using MethodCallHandler = // A channel for communicating with the Flutter engine using invocation of // asynchronous methods. -template +template class MethodChannel { public: // Creates an instance that sends and receives method calls on the channel diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/method_result.h b/shell/platform/common/cpp/client_wrapper/include/flutter/method_result.h index c2b2df5791058..fd7e40dd570eb 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/method_result.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/method_result.h @@ -9,9 +9,11 @@ namespace flutter { +class EncodableValue; + // Encapsulates a result returned from a MethodCall. Only one method should be // called on any given instance. -template +template class MethodResult { public: MethodResult() = default; diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/method_result_functions.h b/shell/platform/common/cpp/client_wrapper/include/flutter/method_result_functions.h index 762128f444324..e377138a79183 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/method_result_functions.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/method_result_functions.h @@ -12,6 +12,8 @@ namespace flutter { +class EncodableValue; + // Handler types for each of the MethodResult outcomes. template using ResultHandlerSuccess = std::function; @@ -24,7 +26,7 @@ using ResultHandlerNotImplemented = std::function; // An implementation of MethodResult that pass calls through to provided // function objects, for ease of constructing one-off result handlers. -template +template class MethodResultFunctions : public MethodResult { public: // Creates a result object that calls the provided functions for the diff --git a/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc b/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc index 13cbb50f88c63..fed501d32bdb3 100644 --- a/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc +++ b/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc @@ -72,7 +72,7 @@ TEST(MethodChannelTest, Registration) { EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); EXPECT_NE(messenger.last_message_handler(), nullptr); // Send a test message to trigger the handler test assertions. - MethodCall call(method_name, nullptr); + MethodCall<> call(method_name, nullptr); auto message = codec.EncodeMethodCall(call); messenger.last_message_handler()( @@ -86,7 +86,7 @@ TEST(MethodChannelTest, Unregistration) { TestBinaryMessenger messenger; const std::string channel_name("some_channel"); MethodChannel channel(&messenger, channel_name, - &flutter::StandardMethodCodec::GetInstance()); + &StandardMethodCodec::GetInstance()); channel.SetMethodCallHandler([](const auto& call, auto result) {}); EXPECT_EQ(messenger.last_message_handler_channel(), channel_name); @@ -101,7 +101,7 @@ TEST(MethodChannelTest, InvokeWithoutResponse) { TestBinaryMessenger messenger; const std::string channel_name("some_channel"); MethodChannel channel(&messenger, channel_name, - &flutter::StandardMethodCodec::GetInstance()); + &StandardMethodCodec::GetInstance()); channel.InvokeMethod("foo", nullptr); EXPECT_TRUE(messenger.send_called()); @@ -112,11 +112,11 @@ TEST(MethodChannelTest, InvokeWithResponse) { TestBinaryMessenger messenger; const std::string channel_name("some_channel"); MethodChannel channel(&messenger, channel_name, - &flutter::StandardMethodCodec::GetInstance()); + &StandardMethodCodec::GetInstance()); bool received_reply = false; const std::string reply = "bar"; - auto result_handler = std::make_unique>( + auto result_handler = std::make_unique>( [&received_reply, reply](const EncodableValue* success_value) { received_reply = true; EXPECT_EQ(std::get(*success_value), reply); @@ -130,8 +130,7 @@ TEST(MethodChannelTest, InvokeWithResponse) { // Call the underlying reply handler to ensure it's processed correctly. EncodableValue reply_value(reply); std::unique_ptr> encoded_reply = - flutter::StandardMethodCodec::GetInstance().EncodeSuccessEnvelope( - &reply_value); + StandardMethodCodec::GetInstance().EncodeSuccessEnvelope(&reply_value); messenger.last_reply_handler()(encoded_reply->data(), encoded_reply->size()); EXPECT_TRUE(received_reply); } @@ -140,10 +139,10 @@ TEST(MethodChannelTest, InvokeNotImplemented) { TestBinaryMessenger messenger; const std::string channel_name("some_channel"); MethodChannel channel(&messenger, channel_name, - &flutter::StandardMethodCodec::GetInstance()); + &StandardMethodCodec::GetInstance()); bool received_not_implemented = false; - auto result_handler = std::make_unique>( + auto result_handler = std::make_unique>( nullptr, nullptr, [&received_not_implemented]() { received_not_implemented = true; }); diff --git a/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc b/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc index bb7a6f930f788..0dc765cd8cdd8 100644 --- a/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc +++ b/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc @@ -13,8 +13,7 @@ namespace { // Returns true if the given method calls have the same method name, and their // arguments have equivalent values. -bool MethodCallsAreEqual(const MethodCall& a, - const MethodCall& b) { +bool MethodCallsAreEqual(const MethodCall<>& a, const MethodCall<>& b) { if (a.method_name() != b.method_name()) { return false; } @@ -34,26 +33,23 @@ bool MethodCallsAreEqual(const MethodCall& a, TEST(StandardMethodCodec, HandlesMethodCallsWithNullArguments) { const StandardMethodCodec& codec = StandardMethodCodec::GetInstance(); - MethodCall call("hello", nullptr); + MethodCall<> call("hello", nullptr); auto encoded = codec.EncodeMethodCall(call); ASSERT_NE(encoded.get(), nullptr); - std::unique_ptr> decoded = - codec.DecodeMethodCall(*encoded); + std::unique_ptr> decoded = codec.DecodeMethodCall(*encoded); ASSERT_NE(decoded.get(), nullptr); EXPECT_TRUE(MethodCallsAreEqual(call, *decoded)); } TEST(StandardMethodCodec, HandlesMethodCallsWithArgument) { const StandardMethodCodec& codec = StandardMethodCodec::GetInstance(); - MethodCall call( - "hello", std::make_unique(EncodableList{ - EncodableValue(42), - EncodableValue("world"), - })); + MethodCall<> call("hello", std::make_unique(EncodableList{ + EncodableValue(42), + EncodableValue("world"), + })); auto encoded = codec.EncodeMethodCall(call); ASSERT_NE(encoded.get(), nullptr); - std::unique_ptr> decoded = - codec.DecodeMethodCall(*encoded); + std::unique_ptr> decoded = codec.DecodeMethodCall(*encoded); ASSERT_NE(decoded.get(), nullptr); EXPECT_TRUE(MethodCallsAreEqual(call, *decoded)); } @@ -66,7 +62,7 @@ TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithNullResult) { EXPECT_EQ(*encoded, bytes); bool decoded_successfully = false; - MethodResultFunctions result_handler( + MethodResultFunctions<> result_handler( [&decoded_successfully](const EncodableValue* result) { decoded_successfully = true; EXPECT_EQ(result, nullptr); @@ -86,7 +82,7 @@ TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithResult) { EXPECT_EQ(*encoded, bytes); bool decoded_successfully = false; - MethodResultFunctions result_handler( + MethodResultFunctions<> result_handler( [&decoded_successfully](const EncodableValue* result) { decoded_successfully = true; EXPECT_EQ(std::get(*result), 42); @@ -106,7 +102,7 @@ TEST(StandardMethodCodec, HandlesErrorEnvelopesWithNulls) { EXPECT_EQ(*encoded, bytes); bool decoded_successfully = false; - MethodResultFunctions result_handler( + MethodResultFunctions<> result_handler( nullptr, [&decoded_successfully](const std::string& code, const std::string& message, @@ -140,7 +136,7 @@ TEST(StandardMethodCodec, HandlesErrorEnvelopesWithDetails) { EXPECT_EQ(*encoded, bytes); bool decoded_successfully = false; - MethodResultFunctions result_handler( + MethodResultFunctions<> result_handler( nullptr, [&decoded_successfully](const std::string& code, const std::string& message, @@ -163,12 +159,11 @@ TEST(StandardMethodCodec, HandlesCustomTypeArguments) { const StandardMethodCodec& codec = StandardMethodCodec::GetInstance( &PointExtensionSerializer::GetInstance()); Point point(7, 9); - MethodCall call( + MethodCall<> call( "hello", std::make_unique(CustomEncodableValue(point))); auto encoded = codec.EncodeMethodCall(call); ASSERT_NE(encoded.get(), nullptr); - std::unique_ptr> decoded = - codec.DecodeMethodCall(*encoded); + std::unique_ptr> decoded = codec.DecodeMethodCall(*encoded); ASSERT_NE(decoded.get(), nullptr); const Point& decoded_point = std::any_cast(