Skip to content

Commit

Permalink
Default C++ wrapper templates to EncodableValue (flutter#20760)
Browse files Browse the repository at this point in the history
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<EncodableValue>).
  • Loading branch information
stuartmorgan authored Sep 1, 2020
1 parent 1f52ec3 commit 8019058
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 81 deletions.
71 changes: 28 additions & 43 deletions shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <memory>
#include <string>

#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"
Expand Down Expand Up @@ -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<flutter::EncodableValue>>(
[&on_listen_called](
const flutter::EncodableValue* arguments,
std::unique_ptr<flutter::EventSink<flutter::EncodableValue>>&& events)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
auto handler = std::make_unique<StreamHandlerFunctions<>>(
[&on_listen_called](const EncodableValue* arguments,
std::unique_ptr<EventSink<>>&& events)
-> std::unique_ptr<StreamHandlerError<>> {
on_listen_called = true;
return nullptr;
},
[](const flutter::EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
return nullptr;
});
[](const EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<>> { 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<flutter::EncodableValue> call("listen", nullptr);
MethodCall<> call("listen", nullptr);
auto message = codec.EncodeMethodCall(call);
messenger.last_message_handler()(
message->data(), message->size(),
Expand All @@ -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<flutter::EncodableValue>>(
[](const flutter::EncodableValue* arguments,
std::unique_ptr<flutter::EventSink<flutter::EncodableValue>>&& events)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
return nullptr;
},
[](const flutter::EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
return nullptr;
});
auto handler = std::make_unique<StreamHandlerFunctions<>>(
[](const EncodableValue* arguments, std::unique_ptr<EventSink<>>&& events)
-> std::unique_ptr<StreamHandlerError<>> { return nullptr; },
[](const EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<>> { return nullptr; });
channel.SetStreamHandler(std::move(handler));
EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
EXPECT_NE(messenger.last_message_handler(), nullptr);
Expand All @@ -115,17 +104,15 @@ TEST(EventChannelTest, Cancel) {

bool on_listen_called = false;
bool on_cancel_called = false;
auto handler = std::make_unique<
flutter::StreamHandlerFunctions<flutter::EncodableValue>>(
[&on_listen_called](
const flutter::EncodableValue* arguments,
std::unique_ptr<flutter::EventSink<flutter::EncodableValue>>&& events)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
auto handler = std::make_unique<StreamHandlerFunctions<>>(
[&on_listen_called](const EncodableValue* arguments,
std::unique_ptr<EventSink<>>&& events)
-> std::unique_ptr<StreamHandlerError<>> {
on_listen_called = true;
return nullptr;
},
[&on_cancel_called](const flutter::EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
[&on_cancel_called](const EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<>> {
on_cancel_called = true;
return nullptr;
});
Expand All @@ -134,15 +121,15 @@ TEST(EventChannelTest, Cancel) {
EXPECT_NE(messenger.last_message_handler(), nullptr);

// Send dummy listen message.
MethodCall<flutter::EncodableValue> call_listen("listen", nullptr);
MethodCall<> call_listen("listen", nullptr);
auto message = codec.EncodeMethodCall(call_listen);
messenger.last_message_handler()(
message->data(), message->size(),
[](const uint8_t* reply, const size_t reply_size) {});
EXPECT_EQ(on_listen_called, true);

// Send dummy cancel message.
MethodCall<flutter::EncodableValue> call_cancel("cancel", nullptr);
MethodCall<> call_cancel("cancel", nullptr);
message = codec.EncodeMethodCall(call_cancel);
messenger.last_message_handler()(
message->data(), message->size(),
Expand All @@ -164,17 +151,15 @@ TEST(EventChannelTest, ReRegistration) {

bool on_listen_called = false;
bool on_cancel_called = false;
auto handler = std::make_unique<
flutter::StreamHandlerFunctions<flutter::EncodableValue>>(
[&on_listen_called](
const flutter::EncodableValue* arguments,
std::unique_ptr<flutter::EventSink<flutter::EncodableValue>>&& events)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
auto handler = std::make_unique<StreamHandlerFunctions<>>(
[&on_listen_called](const EncodableValue* arguments,
std::unique_ptr<EventSink<>>&& events)
-> std::unique_ptr<StreamHandlerError<>> {
on_listen_called = true;
return nullptr;
},
[&on_cancel_called](const flutter::EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<flutter::EncodableValue>> {
[&on_cancel_called](const EncodableValue* arguments)
-> std::unique_ptr<StreamHandlerError<>> {
on_cancel_called = true;
return nullptr;
});
Expand All @@ -183,7 +168,7 @@ TEST(EventChannelTest, ReRegistration) {
EXPECT_NE(messenger.last_message_handler(), nullptr);

// Send dummy listen message.
MethodCall<flutter::EncodableValue> call("listen", nullptr);
MethodCall<> call("listen", nullptr);
auto message = codec.EncodeMethodCall(call);
messenger.last_message_handler()(
message->data(), message->size(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

namespace flutter {

class EncodableValue;

// A message reply callback.
//
// Used for submitting a reply back to a Flutter message sender.
Expand All @@ -29,7 +31,7 @@ using MessageHandler =

// A channel for communicating with the Flutter engine by sending asynchronous
// messages.
template <typename T>
template <typename T = EncodableValue>
class BasicMessageChannel {
public:
// Creates an instance that sends and receives method calls on the channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <typename T>
template <typename T = EncodableValue>
class EventChannel {
public:
// Creates an instance that sends and receives event handler on the channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
template <typename T = EncodableValue>
class EventSink {
public:
EventSink() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

namespace flutter {

template <typename T>
class EncodableValue;

template <typename T = EncodableValue>
struct StreamHandlerError {
const std::string& error_code;
const std::string& error_message;
Expand All @@ -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 <typename T>
template <typename T = EncodableValue>
class StreamHandler {
public:
StreamHandler() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace flutter {

class EncodableValue;

// Handler types for each of the StreamHandler setup and tear-down
// requests.
template <typename T>
Expand All @@ -26,7 +28,7 @@ using StreamHandlerCancel =

// An implementation of StreamHandler that pass calls through to
// provided function objects.
template <typename T>
template <typename T = EncodableValue>
class StreamHandlerFunctions : public StreamHandler<T> {
public:
// Creates a handler object that calls the provided functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@

namespace flutter {

class EncodableValue;

// An object encapsulating a method call from Flutter whose arguments are of
// type T.
template <typename T>
template <typename T = EncodableValue>
class MethodCall {
public:
// Creates a MethodCall with the given name and arguments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -27,7 +29,7 @@ using MethodCallHandler =

// A channel for communicating with the Flutter engine using invocation of
// asynchronous methods.
template <typename T>
template <typename T = EncodableValue>
class MethodChannel {
public:
// Creates an instance that sends and receives method calls on the channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
template <typename T = EncodableValue>
class MethodResult {
public:
MethodResult() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace flutter {

class EncodableValue;

// Handler types for each of the MethodResult outcomes.
template <typename T>
using ResultHandlerSuccess = std::function<void(const T* result)>;
Expand All @@ -24,7 +26,7 @@ using ResultHandlerNotImplemented = std::function<void()>;

// An implementation of MethodResult that pass calls through to provided
// function objects, for ease of constructing one-off result handlers.
template <typename T>
template <typename T = EncodableValue>
class MethodResultFunctions : public MethodResult<T> {
public:
// Creates a result object that calls the provided functions for the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<EncodableValue> call(method_name, nullptr);
MethodCall<> call(method_name, nullptr);
auto message = codec.EncodeMethodCall(call);

messenger.last_message_handler()(
Expand All @@ -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);
Expand All @@ -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());
Expand All @@ -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<MethodResultFunctions<EncodableValue>>(
auto result_handler = std::make_unique<MethodResultFunctions<>>(
[&received_reply, reply](const EncodableValue* success_value) {
received_reply = true;
EXPECT_EQ(std::get<std::string>(*success_value), reply);
Expand All @@ -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<std::vector<uint8_t>> 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);
}
Expand All @@ -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<MethodResultFunctions<EncodableValue>>(
auto result_handler = std::make_unique<MethodResultFunctions<>>(
nullptr, nullptr,
[&received_not_implemented]() { received_not_implemented = true; });

Expand Down
Loading

0 comments on commit 8019058

Please sign in to comment.