| Flutter Windows Embedder |

plugin_registrar_windows_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 <memory>
6 #include <string>
7
8 #include "flutter/shell/platform/windows/client_wrapper/include/flutter/plugin_registrar_windows.h"
9 #include "flutter/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h"
10 #include "gtest/gtest.h"
11
12 namespace flutter {
13
14 namespace {
15
16 // Stub implementation to validate calls to the API.
17 class TestWindowsApi : public testing::StubFlutterWindowsApi {
18 public:
19 void PluginRegistrarRegisterTopLevelWindowProcDelegate(
20 FlutterDesktopWindowProcCallback delegate,
21 void* user_data) override {
22 ++registered_delegate_count_;
23 last_registered_delegate_ = delegate;
24 last_registered_user_data_ = user_data;
25 }
26
27 void PluginRegistrarUnregisterTopLevelWindowProcDelegate(
28 FlutterDesktopWindowProcCallback delegate) override {
29 --registered_delegate_count_;
30 }
31
32 int registered_delegate_count() { return registered_delegate_count_; }
33
34 FlutterDesktopWindowProcCallback last_registered_delegate() {
35 return last_registered_delegate_;
36 }
37
38 void* last_registered_user_data() { return last_registered_user_data_; }
39
40 private:
41 int registered_delegate_count_ = 0;
42 FlutterDesktopWindowProcCallback last_registered_delegate_ = nullptr;
43 void* last_registered_user_data_ = nullptr;
44 };
45
46 // A test plugin that tries to access registrar state during destruction and
47 // reports it out via a flag provided at construction.
48 class TestPlugin : public Plugin {
49 public:
50 // registrar_valid_at_destruction will be set at destruction to indicate
51 // whether or not |registrar->GetView()| was non-null.
52 TestPlugin(PluginRegistrarWindows* registrar,
53 bool* registrar_valid_at_destruction)
54 : registrar_(registrar),
55 registrar_valid_at_destruction_(registrar_valid_at_destruction) {}
56 virtual ~TestPlugin() {
57 *registrar_valid_at_destruction_ = registrar_->GetView() != nullptr;
58 }
59
60 private:
61 PluginRegistrarWindows* registrar_;
62 bool* registrar_valid_at_destruction_;
63 };
64
65 } // namespace
66
67 TEST(PluginRegistrarWindowsTest, GetView) {
68 testing::ScopedStubFlutterWindowsApi scoped_api_stub(
69 std::make_unique<TestWindowsApi>());
70 auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
71 PluginRegistrarWindows registrar(
72 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));
73 EXPECT_NE(registrar.GetView(), nullptr);
74 }
75
76 // Tests that the registrar runs plugin destructors before its own teardown.
77 TEST(PluginRegistrarWindowsTest, PluginDestroyedBeforeRegistrar) {
78 auto dummy_registrar_handle =
79 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
80 bool registrar_valid_at_destruction = false;
81 {
82 PluginRegistrarWindows registrar(dummy_registrar_handle);
83
84 auto plugin = std::make_unique<TestPlugin>(&registrar,
85 &registrar_valid_at_destruction);
86 registrar.AddPlugin(std::move(plugin));
87 }
88 EXPECT_TRUE(registrar_valid_at_destruction);
89 }
90
91 TEST(PluginRegistrarWindowsTest, RegisterUnregister) {
92 testing::ScopedStubFlutterWindowsApi scoped_api_stub(
93 std::make_unique<TestWindowsApi>());
94 auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
95 PluginRegistrarWindows registrar(
96 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));
97
98 WindowProcDelegate delegate = [](HWND hwnd, UINT message, WPARAM wparam,
99 LPARAM lparam) {
100 return std::optional<LRESULT>();
101 };
102 int id_a = registrar.RegisterTopLevelWindowProcDelegate(delegate);
103 EXPECT_EQ(test_api->registered_delegate_count(), 1);
104 int id_b = registrar.RegisterTopLevelWindowProcDelegate(delegate);
105 // All the C++-level delegates are driven by a since C callback, so the
106 // registration count should stay the same.
107 EXPECT_EQ(test_api->registered_delegate_count(), 1);
108
109 // Unregistering one of the two delegates shouldn't cause the underlying C
110 // callback to be unregistered.
111 registrar.UnregisterTopLevelWindowProcDelegate(id_a);
112 EXPECT_EQ(test_api->registered_delegate_count(), 1);
113 // Unregistering both should unregister it.
114 registrar.UnregisterTopLevelWindowProcDelegate(id_b);
115 EXPECT_EQ(test_api->registered_delegate_count(), 0);
116
117 EXPECT_NE(id_a, id_b);
118 }
119
120 TEST(PluginRegistrarWindowsTest, CallsRegisteredDelegates) {
121 testing::ScopedStubFlutterWindowsApi scoped_api_stub(
122 std::make_unique<TestWindowsApi>());
123 auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
124 PluginRegistrarWindows registrar(
125 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));
126
127 HWND dummy_hwnd;
128 bool called_a = false;
129 WindowProcDelegate delegate_a = [&called_a, &dummy_hwnd](
130 HWND hwnd, UINT message, WPARAM wparam,
131 LPARAM lparam) {
132 called_a = true;
133 EXPECT_EQ(hwnd, dummy_hwnd);
134 EXPECT_EQ(message, 2);
135 EXPECT_EQ(wparam, 3);
136 EXPECT_EQ(lparam, 4);
137 return std::optional<LRESULT>();
138 };
139 bool called_b = false;
140 WindowProcDelegate delegate_b = [&called_b](HWND hwnd, UINT message,
141 WPARAM wparam, LPARAM lparam) {
142 called_b = true;
143 return std::optional<LRESULT>();
144 };
145 int id_a = registrar.RegisterTopLevelWindowProcDelegate(delegate_a);
146 int id_b = registrar.RegisterTopLevelWindowProcDelegate(delegate_b);
147
148 LRESULT result = 0;
149 bool handled = test_api->last_registered_delegate()(
150 dummy_hwnd, 2, 3, 4, test_api->last_registered_user_data(), &result);
151 EXPECT_TRUE(called_a);
152 EXPECT_TRUE(called_b);
153 EXPECT_FALSE(handled);
154 }
155
156 TEST(PluginRegistrarWindowsTest, StopsOnceHandled) {
157 testing::ScopedStubFlutterWindowsApi scoped_api_stub(
158 std::make_unique<TestWindowsApi>());
159 auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
160 PluginRegistrarWindows registrar(
161 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));
162
163 bool called_a = false;
164 WindowProcDelegate delegate_a = [&called_a](HWND hwnd, UINT message,
165 WPARAM wparam, LPARAM lparam) {
166 called_a = true;
167 return std::optional<LRESULT>(7);
168 };
169 bool called_b = false;
170 WindowProcDelegate delegate_b = [&called_b](HWND hwnd, UINT message,
171 WPARAM wparam, LPARAM lparam) {
172 called_b = true;
173 return std::optional<LRESULT>(7);
174 };
175 int id_a = registrar.RegisterTopLevelWindowProcDelegate(delegate_a);
176 int id_b = registrar.RegisterTopLevelWindowProcDelegate(delegate_b);
177
178 HWND dummy_hwnd;
179 LRESULT result = 0;
180 bool handled = test_api->last_registered_delegate()(
181 dummy_hwnd, 2, 3, 4, test_api->last_registered_user_data(), &result);
182 // Only one of the delegates should have been called, since each claims to
183 // have fully handled the message.
184 EXPECT_TRUE(called_a || called_b);
185 EXPECT_NE(called_a, called_b);
186 // The return value should propagate through.
187 EXPECT_TRUE(handled);
188 EXPECT_EQ(result, 7);
189 }
190
191 } // namespace flutter
flutter::PluginRegistrarWindows::UnregisterTopLevelWindowProcDelegate
void UnregisterTopLevelWindowProcDelegate(int proc_id)
Definition: plugin_registrar_windows.h:76
flutter::PluginRegistrarWindows::RegisterTopLevelWindowProcDelegate
int RegisterTopLevelWindowProcDelegate(WindowProcDelegate delegate)
Definition: plugin_registrar_windows.h:65
user_data
void * user_data
Definition: flutter_windows_view_unittests.cc:47
flutter::PluginRegistrarWindows
Definition: plugin_registrar_windows.h:28
flutter::TEST
TEST(FlutterEngineTest, CreateDestroy)
Definition: flutter_engine_unittests.cc:103
flutter
Definition: accessibility_bridge_windows.cc:11
plugin_registrar_windows.h
flutter::PluginRegistrar::AddPlugin
void AddPlugin(std::unique_ptr< Plugin > plugin)
Definition: plugin_registrar.cc:38
flutter::WindowProcDelegate
std::function< std::optional< LRESULT >(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)> WindowProcDelegate
Definition: plugin_registrar_windows.h:24
message
Win32Message message
Definition: keyboard_unittests.cc:137
FlutterDesktopPluginRegistrar
Definition: window_state.h:31
flutter::PluginRegistrarWindows::GetView
FlutterView * GetView()
Definition: plugin_registrar_windows.h:50
FlutterDesktopWindowProcCallback
bool(* FlutterDesktopWindowProcCallback)(HWND, UINT, WPARAM, LPARAM, void *, LRESULT *result)
Definition: flutter_windows.h:238