| Flutter iOS Embedder |

method_channel_unittests.cc
Go to the documentation of this file.
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/common/client_wrapper/include/flutter/method_channel.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h"
11 #include "flutter/shell/platform/common/client_wrapper/include/flutter/method_result_functions.h"
12 #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
13 #include "gtest/gtest.h"
14
15 namespace flutter {
16
17 namespace {
18
19 class TestBinaryMessenger : public BinaryMessenger {
20 public:
21 void Send(const std::string& channel,
22 const uint8_t* message,
23 size_t message_size,
24 BinaryReply reply) const override {
25 send_called_ = true;
26 last_reply_handler_ = reply;
27 }
28
29 void SetMessageHandler(const std::string& channel,
30 BinaryMessageHandler handler) override {
31 last_message_handler_channel_ = channel;
32 last_message_handler_ = handler;
33 }
34
35 bool send_called() { return send_called_; }
36
37 BinaryReply last_reply_handler() { return last_reply_handler_; }
38
39 std::string last_message_handler_channel() {
40 return last_message_handler_channel_;
41 }
42
43 BinaryMessageHandler last_message_handler() { return last_message_handler_; }
44
45 private:
46 mutable bool send_called_ = false;
47 mutable BinaryReply last_reply_handler_;
48 std::string last_message_handler_channel_;
49 BinaryMessageHandler last_message_handler_;
50 };
51
52 } // namespace
53
54 // Tests that SetMethodCallHandler sets a handler that correctly interacts with
55 // the binary messenger.
56 TEST(MethodChannelTest, Registration) {
57 TestBinaryMessenger messenger;
58 const std::string channel_name("some_channel");
59 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
60 MethodChannel channel(&messenger, channel_name, &codec);
61
62 bool callback_called = false;
63 const std::string method_name("hello");
64 channel.SetMethodCallHandler(
65 [&callback_called, method_name](const auto& call, auto result) {
66 callback_called = true;
67 // Ensure that the wrapper received a correctly decoded call and a
68 // result.
69 EXPECT_EQ(call.method_name(), method_name);
70 EXPECT_NE(result, nullptr);
71 result->Success();
72 });
73 EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
74 EXPECT_NE(messenger.last_message_handler(), nullptr);
75 // Send a test message to trigger the handler test assertions.
76 MethodCall<> call(method_name, nullptr);
77 auto message = codec.EncodeMethodCall(call);
78
79 messenger.last_message_handler()(
80 message->data(), message->size(),
81 [](const uint8_t* reply, size_t reply_size) {});
82 EXPECT_TRUE(callback_called);
83 }
84
85 // Tests that SetMethodCallHandler with a null handler unregisters the handler.
86 TEST(MethodChannelTest, Unregistration) {
87 TestBinaryMessenger messenger;
88 const std::string channel_name("some_channel");
89 MethodChannel channel(&messenger, channel_name,
90 &StandardMethodCodec::GetInstance());
91
92 channel.SetMethodCallHandler([](const auto& call, auto result) {});
93 EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
94 EXPECT_NE(messenger.last_message_handler(), nullptr);
95
96 channel.SetMethodCallHandler(nullptr);
97 EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
98 EXPECT_EQ(messenger.last_message_handler(), nullptr);
99 }
100
101 TEST(MethodChannelTest, InvokeWithoutResponse) {
102 TestBinaryMessenger messenger;
103 const std::string channel_name("some_channel");
104 MethodChannel channel(&messenger, channel_name,
105 &StandardMethodCodec::GetInstance());
106
107 channel.InvokeMethod("foo", nullptr);
108 EXPECT_TRUE(messenger.send_called());
109 EXPECT_EQ(messenger.last_reply_handler(), nullptr);
110 }
111
112 TEST(MethodChannelTest, InvokeWithResponse) {
113 TestBinaryMessenger messenger;
114 const std::string channel_name("some_channel");
115 MethodChannel channel(&messenger, channel_name,
116 &StandardMethodCodec::GetInstance());
117
118 bool received_reply = false;
119 const std::string reply = "bar";
120 auto result_handler = std::make_unique<MethodResultFunctions<>>(
121 [&received_reply, reply](const EncodableValue* success_value) {
122 received_reply = true;
123 EXPECT_EQ(std::get<std::string>(*success_value), reply);
124 },
125 nullptr, nullptr);
126
127 channel.InvokeMethod("foo", nullptr, std::move(result_handler));
128 EXPECT_TRUE(messenger.send_called());
129 ASSERT_NE(messenger.last_reply_handler(), nullptr);
130
131 // Call the underlying reply handler to ensure it's processed correctly.
132 EncodableValue reply_value(reply);
133 std::unique_ptr<std::vector<uint8_t>> encoded_reply =
134 StandardMethodCodec::GetInstance().EncodeSuccessEnvelope(&reply_value);
135 messenger.last_reply_handler()(encoded_reply->data(), encoded_reply->size());
136 EXPECT_TRUE(received_reply);
137 }
138
139 TEST(MethodChannelTest, InvokeNotImplemented) {
140 TestBinaryMessenger messenger;
141 const std::string channel_name("some_channel");
142 MethodChannel channel(&messenger, channel_name,
143 &StandardMethodCodec::GetInstance());
144
145 bool received_not_implemented = false;
146 auto result_handler = std::make_unique<MethodResultFunctions<>>(
147 nullptr, nullptr,
148 [&received_not_implemented]() { received_not_implemented = true; });
149
150 channel.InvokeMethod("foo", nullptr, std::move(result_handler));
151 EXPECT_EQ(messenger.send_called(), true);
152 ASSERT_NE(messenger.last_reply_handler(), nullptr);
153
154 // Call the underlying reply handler to ensure it's reported as unimplemented.
155 messenger.last_reply_handler()(nullptr, 0);
156 EXPECT_TRUE(received_not_implemented);
157 }
158
159 } // namespace flutter
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:46
flutter::MethodChannel
Definition: method_channel.h:33
method_result_functions.h
flutter::StandardMethodCodec
Definition: standard_method_codec.h:18
flutter::MethodChannel::InvokeMethod
void InvokeMethod(const std::string &method, std::unique_ptr< T > arguments, std::unique_ptr< MethodResult< T >> result=nullptr)
Definition: method_channel.h:52
standard_method_codec.h
binary_messenger.h
flutter::MethodChannel::SetMethodCallHandler
void SetMethodCallHandler(MethodCallHandler< T > handler) const
Definition: method_channel.h:98
flutter::MethodCall
Definition: method_call.h:18
SetMessageHandler
static FlutterBinaryMessengerConnection SetMessageHandler(NSObject< FlutterBinaryMessenger > *messenger, NSString *name, FlutterBinaryMessageHandler handler, NSObject< FlutterTaskQueue > *taskQueue)
Definition: FlutterChannels.mm:50
flutter::BinaryReply
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
Definition: binary_messenger.h:17
flutter::MethodCodec::EncodeSuccessEnvelope
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelope(const T *result=nullptr) const
Definition: method_codec.h:55
flutter::MethodCodec::EncodeMethodCall
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCall(const MethodCall< T > &method_call) const
Definition: method_codec.h:48
flutter
Definition: accessibility_bridge.h:28
flutter::EncodableValue
Definition: encodable_value.h:165
method_channel.h
flutter::BinaryMessageHandler
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
Definition: binary_messenger.h:24
flutter::StandardMethodCodec::GetInstance
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:340