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/cpp/client_wrapper/include/flutter/method_channel.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h"
11 #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_result_functions.h"
12 #include "flutter/shell/platform/common/cpp/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");
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 recieved 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,
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,
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,
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 =
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,
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
void SetMethodCallHandler(MethodCallHandler< T > handler) const
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
void InvokeMethod(const std::string &method, std::unique_ptr< T > arguments, std::unique_ptr< MethodResult< T >> result=nullptr)
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)
TEST(DartServiceIsolateTest, CanAddAndRemoveHandles)
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler