| Flutter macOS Embedder |

plugin_registrar_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/plugin_registrar.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "flutter/shell/platform/common/client_wrapper/testing/stub_flutter_api.h"
11 #include "gtest/gtest.h"
12
13 namespace flutter {
14
15 namespace {
16
17 // Stub implementation to validate calls to the API.
18 class TestApi : public testing::StubFlutterApi {
19 public:
20 // |flutter::testing::StubFlutterApi|
21 bool MessengerSend(const char* channel,
22 const uint8_t* message,
23 const size_t message_size) override {
24 last_data_sent_ = message;
25 return message_engine_result;
26 }
27
28 bool MessengerSendWithReply(const char* channel,
29 const uint8_t* message,
30 const size_t message_size,
31 const FlutterDesktopBinaryReply reply,
32 void* user_data) override {
33 last_data_sent_ = message;
34 return message_engine_result;
35 }
36
37 void MessengerSetCallback(const char* channel,
38 FlutterDesktopMessageCallback callback,
39 void* user_data) override {
40 last_message_callback_set_ = callback;
41 }
42
43 void PluginRegistrarSetDestructionHandler(
44 FlutterDesktopOnPluginRegistrarDestroyed callback) override {
45 last_destruction_callback_set_ = callback;
46 }
47
48 const uint8_t* last_data_sent() { return last_data_sent_; }
49 FlutterDesktopMessageCallback last_message_callback_set() {
50 return last_message_callback_set_;
51 }
52 FlutterDesktopOnPluginRegistrarDestroyed last_destruction_callback_set() {
53 return last_destruction_callback_set_;
54 }
55
56 private:
57 const uint8_t* last_data_sent_ = nullptr;
58 FlutterDesktopMessageCallback last_message_callback_set_ = nullptr;
59 FlutterDesktopOnPluginRegistrarDestroyed last_destruction_callback_set_ =
60 nullptr;
61 };
62
63 // A PluginRegistrar whose destruction can be watched for by tests.
64 class TestPluginRegistrar : public PluginRegistrar {
65 public:
66 explicit TestPluginRegistrar(FlutterDesktopPluginRegistrarRef core_registrar)
67 : PluginRegistrar(core_registrar) {}
68
69 virtual ~TestPluginRegistrar() {
70 if (destruction_callback_) {
71 destruction_callback_();
72 }
73 }
74
75 void SetDestructionCallback(std::function<void()> callback) {
76 destruction_callback_ = std::move(callback);
77 }
78
79 private:
80 std::function<void()> destruction_callback_;
81 };
82
83 // A test plugin that tries to access registrar state during destruction and
84 // reports it out via a flag provided at construction.
85 class TestPlugin : public Plugin {
86 public:
87 // registrar_valid_at_destruction will be set at destruction to indicate
88 // whether or not |registrar->messenger()| was non-null.
89 TestPlugin(PluginRegistrar* registrar, bool* registrar_valid_at_destruction)
90 : registrar_(registrar),
91 registrar_valid_at_destruction_(registrar_valid_at_destruction) {}
92 virtual ~TestPlugin() {
93 *registrar_valid_at_destruction_ = registrar_->messenger() != nullptr;
94 }
95
96 private:
97 PluginRegistrar* registrar_;
98 bool* registrar_valid_at_destruction_;
99 };
100
101 } // namespace
102
103 // Tests that the registrar runs plugin destructors before its own teardown.
104 TEST(PluginRegistrarTest, PluginDestroyedBeforeRegistrar) {
105 auto dummy_registrar_handle =
106 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
107 bool registrar_valid_at_destruction = false;
108 {
109 PluginRegistrar registrar(dummy_registrar_handle);
110
111 auto plugin = std::make_unique<TestPlugin>(&registrar,
112 &registrar_valid_at_destruction);
113 registrar.AddPlugin(std::move(plugin));
114 }
115 EXPECT_TRUE(registrar_valid_at_destruction);
116 }
117
118 // Tests that the registrar returns a messenger that passes Send through to the
119 // C API.
120 TEST(PluginRegistrarTest, MessengerSend) {
121 testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
122 auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
123
124 auto dummy_registrar_handle =
125 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
126 PluginRegistrar registrar(dummy_registrar_handle);
127 BinaryMessenger* messenger = registrar.messenger();
128
129 std::vector<uint8_t> message = {1, 2, 3, 4};
130 messenger->Send("some_channel", &message[0], message.size());
131 EXPECT_EQ(test_api->last_data_sent(), &message[0]);
132 }
133
134 // Tests that the registrar returns a messenger that passes callback
135 // registration and unregistration through to the C API.
136 TEST(PluginRegistrarTest, MessengerSetMessageHandler) {
137 testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
138 auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
139
140 auto dummy_registrar_handle =
141 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
142 PluginRegistrar registrar(dummy_registrar_handle);
143 BinaryMessenger* messenger = registrar.messenger();
144 const std::string channel_name("foo");
145
146 // Register.
147 BinaryMessageHandler binary_handler = [](const uint8_t* message,
148 const size_t message_size,
149 const BinaryReply& reply) {};
150 messenger->SetMessageHandler(channel_name, std::move(binary_handler));
151 EXPECT_NE(test_api->last_message_callback_set(), nullptr);
152
153 // Unregister.
154 messenger->SetMessageHandler(channel_name, nullptr);
155 EXPECT_EQ(test_api->last_message_callback_set(), nullptr);
156 }
157
158 // Tests that the registrar manager returns the same instance when getting
159 // the wrapper for the same reference.
160 TEST(PluginRegistrarTest, ManagerSameInstance) {
161 PluginRegistrarManager* manager = PluginRegistrarManager::GetInstance();
162 manager->Reset();
163
164 testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
165
166 auto dummy_registrar_handle =
167 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
168
169 EXPECT_EQ(manager->GetRegistrar<PluginRegistrar>(dummy_registrar_handle),
170 manager->GetRegistrar<PluginRegistrar>(dummy_registrar_handle));
171 }
172
173 // Tests that the registrar manager returns different objects for different
174 // references.
175 TEST(PluginRegistrarTest, ManagerDifferentInstances) {
176 PluginRegistrarManager* manager = PluginRegistrarManager::GetInstance();
177 manager->Reset();
178
179 testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
180
181 auto dummy_registrar_handle_a =
182 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
183 auto dummy_registrar_handle_b =
184 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(2);
185
186 EXPECT_NE(manager->GetRegistrar<PluginRegistrar>(dummy_registrar_handle_a),
187 manager->GetRegistrar<PluginRegistrar>(dummy_registrar_handle_b));
188 }
189
190 // Tests that the registrar manager deletes wrappers when the underlying
191 // reference is destroyed.
192 TEST(PluginRegistrarTest, ManagerRemovesOnDestruction) {
193 PluginRegistrarManager* manager = PluginRegistrarManager::GetInstance();
194 manager->Reset();
195
196 testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
197 auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
198
199 auto dummy_registrar_handle =
200 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
201 auto* wrapper =
202 manager->GetRegistrar<TestPluginRegistrar>(dummy_registrar_handle);
203
204 // Simulate destruction of the reference, and ensure that the wrapper
205 // is destroyed.
206 EXPECT_NE(test_api->last_destruction_callback_set(), nullptr);
207 bool destroyed = false;
208 wrapper->SetDestructionCallback([&destroyed]() { destroyed = true; });
209 test_api->last_destruction_callback_set()(dummy_registrar_handle);
210 EXPECT_EQ(destroyed, true);
211
212 // Requesting the wrapper should now create a new object.
213 EXPECT_NE(manager->GetRegistrar<TestPluginRegistrar>(dummy_registrar_handle),
214 nullptr);
215 }
216
217 // Tests that the texture registrar getter returns a non-null TextureRegistrar
218 TEST(PluginRegistrarTest, TextureRegistrarNotNull) {
219 auto dummy_registrar_handle =
220 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
221 PluginRegistrar registrar(dummy_registrar_handle);
222
223 TextureRegistrar* texture_registrar = registrar.texture_registrar();
224
225 ASSERT_NE(texture_registrar, nullptr);
226 }
227
228 } // namespace flutter
flutter::BinaryMessenger
Definition: binary_messenger.h:29
flutter::BinaryMessenger::Send
virtual void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply=nullptr) const =0
flutter::BinaryMessenger::SetMessageHandler
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
flutter::PluginRegistrar
Definition: plugin_registrar.h:27
flutter::PluginRegistrar::AddPlugin
void AddPlugin(std::unique_ptr< Plugin > plugin)
Definition: plugin_registrar.cc:38
flutter::PluginRegistrar::messenger
BinaryMessenger * messenger()
Definition: plugin_registrar.h:43
flutter::PluginRegistrar::texture_registrar
TextureRegistrar * texture_registrar()
Definition: plugin_registrar.h:47
flutter::PluginRegistrarManager
Definition: plugin_registrar.h:86
flutter::PluginRegistrarManager::Reset
void Reset()
Definition: plugin_registrar.h:114
flutter::PluginRegistrarManager::GetInstance
static PluginRegistrarManager * GetInstance()
Definition: plugin_registrar.cc:49
flutter::PluginRegistrarManager::GetRegistrar
T * GetRegistrar(FlutterDesktopPluginRegistrarRef registrar_ref)
Definition: plugin_registrar.h:102
flutter::TextureRegistrar
Definition: texture_registrar.h:85
FlutterDesktopBinaryReply
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
Definition: flutter_messenger.h:26
FlutterDesktopMessageCallback
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
Definition: flutter_messenger.h:49
FlutterDesktopPluginRegistrarRef
struct FlutterDesktopPluginRegistrar * FlutterDesktopPluginRegistrarRef
Definition: flutter_plugin_registrar.h:20
FlutterDesktopOnPluginRegistrarDestroyed
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
Definition: flutter_plugin_registrar.h:23
flutter
Definition: AccessibilityBridgeMac.h:16
flutter::BinaryMessageHandler
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
Definition: binary_messenger.h:25
flutter::BinaryReply
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
Definition: binary_messenger.h:18
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:58
plugin_registrar.h
user_data
void * user_data
Definition: texture_registrar_unittests.cc:27