Flutter Engine
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,
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.
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  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) {
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) {
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) {
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 
224 
225  ASSERT_NE(texture_registrar, nullptr);
226 }
227 
228 } // namespace flutter
T * GetRegistrar(FlutterDesktopPluginRegistrarRef registrar_ref)
void * user_data
Dart_NativeFunction function
Definition: fuchsia.cc:51
G_BEGIN_DECLS FlTextureRegistrar * texture_registrar
BinaryMessenger * messenger()
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
FlKeyEvent FlKeyResponderAsyncCallback callback
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data observatory The hostname IP address on which the Dart Observatory should be served If not defaults to or::depending on whether ipv6 is specified disable Disable the Dart Observatory The observatory is never available in release mode Bind to the IPv6 localhost address for the Dart Observatory Ignored if observatory host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however skia deterministic Skips the call to thus avoiding swapping out some Skia function pointers based on available CPU features This is used to obtain deterministic behavior in Skia rendering disable service auth Disable the requirement for authentication codes for communicating with the VM service start Start the application paused in the Dart debugger trace Trace Skia calls This is useful when debugging the GPU threed By Skia tracing is not enabled to reduce the number of traced events trace Filters out all trace events except those that are specified in this comma separated list of allowed prefixes cache Only cache the shader in SkSL instead of binary or GLSL This should only be used during development phases The generated SkSLs can later be used in the release build for shader precompilation at launch in order to eliminate the shader compile jank trace Trace to the system 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 prefetched default font manager
Definition: switches.h:177
static PluginRegistrarManager * GetInstance()
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
TEST(DartServiceIsolateTest, CanAddAndRemoveHandles)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
virtual void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply=nullptr) const =0
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
TextureRegistrar * texture_registrar()