Flutter Engine
The 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
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
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
#define TEST(S, s, D, expected)
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
static PluginRegistrarManager * GetInstance()
void AddPlugin(std::unique_ptr< Plugin > plugin)
TextureRegistrar * texture_registrar()
BinaryMessenger * messenger()
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
Win32Message message
G_BEGIN_DECLS FlTextureRegistrar * texture_registrar
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
Definition switches.h:218
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
#define EXPECT_TRUE(handle)
Definition unit_test.h:685