Flutter Engine
The Flutter Engine
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
15namespace flutter {
16
17namespace {
18
19class 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 int length = static_cast<int>(message_size);
28 last_message_ =
29 std::vector<uint8_t>(message, message + length * sizeof(uint8_t));
30 }
31
32 void SetMessageHandler(const std::string& channel,
33 BinaryMessageHandler handler) override {
34 last_message_handler_channel_ = channel;
35 last_message_handler_ = handler;
36 }
37
38 bool send_called() { return send_called_; }
39
40 BinaryReply last_reply_handler() { return last_reply_handler_; }
41
42 std::string last_message_handler_channel() {
43 return last_message_handler_channel_;
44 }
45
46 BinaryMessageHandler last_message_handler() { return last_message_handler_; }
47
48 std::vector<uint8_t> last_message() { return last_message_; }
49
50 private:
51 mutable bool send_called_ = false;
52 mutable BinaryReply last_reply_handler_;
53 std::string last_message_handler_channel_;
54 BinaryMessageHandler last_message_handler_;
55 mutable std::vector<uint8_t> last_message_;
56};
57
58} // namespace
59
60// Tests that SetMethodCallHandler sets a handler that correctly interacts with
61// the binary messenger.
62TEST(MethodChannelTest, Registration) {
63 TestBinaryMessenger messenger;
64 const std::string channel_name("some_channel");
66 MethodChannel channel(&messenger, channel_name, &codec);
67
68 bool callback_called = false;
69 const std::string method_name("hello");
71 [&callback_called, method_name](const auto& call, auto result) {
72 callback_called = true;
73 // Ensure that the wrapper received a correctly decoded call and a
74 // result.
75 EXPECT_EQ(call.method_name(), method_name);
76 EXPECT_NE(result, nullptr);
77 result->Success();
78 });
79 EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
80 EXPECT_NE(messenger.last_message_handler(), nullptr);
81 // Send a test message to trigger the handler test assertions.
82 MethodCall<> call(method_name, nullptr);
83 auto message = codec.EncodeMethodCall(call);
84
85 messenger.last_message_handler()(
86 message->data(), message->size(),
87 [](const uint8_t* reply, size_t reply_size) {});
88 EXPECT_TRUE(callback_called);
89}
90
91// Tests that SetMethodCallHandler with a null handler unregisters the handler.
92TEST(MethodChannelTest, Unregistration) {
93 TestBinaryMessenger messenger;
94 const std::string channel_name("some_channel");
95 MethodChannel channel(&messenger, channel_name,
97
98 channel.SetMethodCallHandler([](const auto& call, auto result) {});
99 EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
100 EXPECT_NE(messenger.last_message_handler(), nullptr);
101
102 channel.SetMethodCallHandler(nullptr);
103 EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
104 EXPECT_EQ(messenger.last_message_handler(), nullptr);
105}
106
107TEST(MethodChannelTest, InvokeWithoutResponse) {
108 TestBinaryMessenger messenger;
109 const std::string channel_name("some_channel");
110 MethodChannel channel(&messenger, channel_name,
112
113 channel.InvokeMethod("foo", nullptr);
114 EXPECT_TRUE(messenger.send_called());
115 EXPECT_EQ(messenger.last_reply_handler(), nullptr);
116}
117
118TEST(MethodChannelTest, InvokeWithResponse) {
119 TestBinaryMessenger messenger;
120 const std::string channel_name("some_channel");
121 MethodChannel channel(&messenger, channel_name,
123
124 bool received_reply = false;
125 const std::string reply = "bar";
126 auto result_handler = std::make_unique<MethodResultFunctions<>>(
127 [&received_reply, reply](const EncodableValue* success_value) {
128 received_reply = true;
129 EXPECT_EQ(std::get<std::string>(*success_value), reply);
130 },
131 nullptr, nullptr);
132
133 channel.InvokeMethod("foo", nullptr, std::move(result_handler));
134 EXPECT_TRUE(messenger.send_called());
135 ASSERT_NE(messenger.last_reply_handler(), nullptr);
136
137 // Call the underlying reply handler to ensure it's processed correctly.
138 EncodableValue reply_value(reply);
139 std::unique_ptr<std::vector<uint8_t>> encoded_reply =
141 messenger.last_reply_handler()(encoded_reply->data(), encoded_reply->size());
142 EXPECT_TRUE(received_reply);
143}
144
145TEST(MethodChannelTest, InvokeNotImplemented) {
146 TestBinaryMessenger messenger;
147 const std::string channel_name("some_channel");
148 MethodChannel channel(&messenger, channel_name,
150
151 bool received_not_implemented = false;
152 auto result_handler = std::make_unique<MethodResultFunctions<>>(
153 nullptr, nullptr,
154 [&received_not_implemented]() { received_not_implemented = true; });
155
156 channel.InvokeMethod("foo", nullptr, std::move(result_handler));
157 EXPECT_EQ(messenger.send_called(), true);
158 ASSERT_NE(messenger.last_reply_handler(), nullptr);
159
160 // Call the underlying reply handler to ensure it's reported as unimplemented.
161 messenger.last_reply_handler()(nullptr, 0);
162 EXPECT_TRUE(received_not_implemented);
163}
164
165// Tests that calling Resize generates the binary message expected by the Dart
166// implementation.
167TEST(MethodChannelTest, Resize) {
168 TestBinaryMessenger messenger;
169 const std::string channel_name("flutter/test");
170 MethodChannel channel(&messenger, channel_name,
172
173 channel.Resize(3);
174
175 // Because the Dart implementation for the control channel implements its own
176 // custom deserialization logic, this test compares the generated bytes array
177 // to the expected one (for instance, the deserialization logic expects the
178 // size parameter of the resize method call to be an uint32).
179 //
180 // The expected content was created from the following Dart code:
181 // MethodCall call = MethodCall('resize', ['flutter/test',3]);
182 // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
183 const int expected_message_size = 29;
184
185 EXPECT_EQ(messenger.send_called(), true);
186 EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
187 expected_message_size);
188
189 int expected[expected_message_size] = {
190 7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117,
191 116, 116, 101, 114, 47, 116, 101, 115, 116, 3, 3, 0, 0, 0};
192 for (int i = 0; i < expected_message_size; i++) {
193 EXPECT_EQ(messenger.last_message()[i], expected[i]);
194 }
195}
196
197// Tests that calling SetWarnsOnOverflow generates the binary message expected
198// by the Dart implementation.
199TEST(MethodChannelTest, SetWarnsOnOverflow) {
200 TestBinaryMessenger messenger;
201
202 const std::string channel_name("flutter/test");
203 MethodChannel channel(&messenger, channel_name,
205
206 channel.SetWarnsOnOverflow(false);
207
208 // The expected content was created from the following Dart code:
209 // MethodCall call = MethodCall('overflow',['flutter/test', true]);
210 // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
211 const int expected_message_size = 27;
212
213 EXPECT_EQ(messenger.send_called(), true);
214 EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
215 expected_message_size);
216
217 int expected[expected_message_size] = {
218 7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12,
219 102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1};
220 for (int i = 0; i < expected_message_size; i++) {
221 EXPECT_EQ(messenger.last_message()[i], expected[i]);
222 }
223}
224
225} // namespace flutter
static void SetWarnsOnOverflow(NSObject< FlutterBinaryMessenger > *binaryMessenger, NSString *channel, BOOL warns)
static FlutterBinaryMessengerConnection SetMessageHandler(NSObject< FlutterBinaryMessenger > *messenger, NSString *name, FlutterBinaryMessageHandler handler, NSObject< FlutterTaskQueue > *taskQueue)
void SetMethodCallHandler(MethodCallHandler< T > handler) const
void Resize(int new_size)
void InvokeMethod(const std::string &method, std::unique_ptr< T > arguments, std::unique_ptr< MethodResult< T > > result=nullptr)
void SetWarnsOnOverflow(bool warns)
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCall(const MethodCall< T > &method_call) const
Definition: method_codec.h:48
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelope(const T *result=nullptr) const
Definition: method_codec.h:55
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply) const override
GAsyncResult * result
size_t length
Win32Message message
def call(args)
Definition: dom.py:159
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
TEST(FrameTimingsRecorderTest, RecordVsync)
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678