Flutter Engine
 
Loading...
Searching...
No Matches
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
6
7#include <memory>
8#include <vector>
9
11#include "gtest/gtest.h"
12
13namespace flutter {
14
15namespace {
16
17// Stub implementation to validate calls to the API.
18class 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,
39 void* user_data) override {
40 last_message_callback_set_ = callback;
41 }
42
43 void PluginRegistrarSetDestructionHandler(
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.
64class 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.
85class 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.
104TEST(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.
120TEST(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.
136TEST(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.
160TEST(PluginRegistrarTest, ManagerSameInstance) {
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.
175TEST(PluginRegistrarTest, ManagerDifferentInstances) {
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.
192TEST(PluginRegistrarTest, ManagerRemovesOnDestruction) {
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
218TEST(PluginRegistrarTest, TextureRegistrarNotNull) {
219 auto dummy_registrar_handle =
220 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
221 PluginRegistrar registrar(dummy_registrar_handle);
222
224
225 ASSERT_NE(texture_registrar, nullptr);
226}
227
228} // namespace flutter
virtual void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply=nullptr) const =0
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
void AddPlugin(std::unique_ptr< Plugin > plugin)
TextureRegistrar * texture_registrar()
BinaryMessenger * messenger()
static PluginRegistrarManager * GetInstance()
const gchar * channel
G_BEGIN_DECLS GBytes * message
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
FlutterDesktopBinaryReply callback
G_BEGIN_DECLS FlTextureRegistrar * texture_registrar
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
TEST(FrameTimingsRecorderTest, RecordVsync)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply