Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
window_proc_delegate_manager_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/windows/window_proc_delegate_manager.h"
6#include "gtest/gtest.h"
7
8namespace flutter {
9namespace testing {
10
11namespace {
12
13#ifdef _WIN32
14#define FLUTTER_NOINLINE __declspec(noinline)
15#else
16#define FLUTTER_NOINLINE __attribute__((noinline))
17#endif
18
19using TestWindowProcDelegate = std::function<std::optional<
20 LRESULT>(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)>;
21
22// A FlutterDesktopWindowProcCallback that forwards to a std::function provided
23// as user_data.
25bool TestWindowProcCallback(HWND hwnd,
27 WPARAM wparam,
28 LPARAM lparam,
29 void* user_data,
30 LRESULT* result) {
31 TestWindowProcDelegate& delegate =
32 *static_cast<TestWindowProcDelegate*>(user_data);
33 auto delegate_result = delegate(hwnd, message, wparam, lparam);
34 if (delegate_result) {
35 *result = *delegate_result;
36 }
37 return delegate_result.has_value();
38}
39
40// Same as the above, but with a different address, to test multiple
41// registration.
42bool TestWindowProcCallback2(HWND hwnd,
44 WPARAM wparam,
45 LPARAM lparam,
46 void* user_data,
47 LRESULT* result) {
48 return TestWindowProcCallback(hwnd, message, wparam, lparam, user_data,
49 result);
50}
51
52} // namespace
53
54TEST(WindowProcDelegateManagerTest, CallsCorrectly) {
56 HWND dummy_hwnd;
57
58 bool called = false;
59 TestWindowProcDelegate delegate = [&called, &dummy_hwnd](
60 HWND hwnd, UINT message, WPARAM wparam,
61 LPARAM lparam) {
62 called = true;
63 EXPECT_EQ(hwnd, dummy_hwnd);
64 EXPECT_EQ(message, 2);
65 EXPECT_EQ(wparam, 3);
66 EXPECT_EQ(lparam, 4);
67 return std::optional<LRESULT>();
68 };
69 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback, &delegate);
70 auto result = manager.OnTopLevelWindowProc(dummy_hwnd, 2, 3, 4);
71
72 EXPECT_TRUE(called);
73 EXPECT_FALSE(result);
74}
75
76TEST(WindowProcDelegateManagerTest, ReplacementRegister) {
78
79 bool called_a = false;
80 TestWindowProcDelegate delegate_a =
81 [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
82 called_a = true;
83 return std::optional<LRESULT>();
84 };
85 bool called_b = false;
86 TestWindowProcDelegate delegate_b =
87 [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
88 called_b = true;
89 return std::optional<LRESULT>();
90 };
91 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
92 &delegate_a);
93 // The function pointer is the same, so this should replace, not add.
94 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
95 &delegate_b);
96 manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
97
98 EXPECT_FALSE(called_a);
99 EXPECT_TRUE(called_b);
100}
101
102TEST(WindowProcDelegateManagerTest, RegisterMultiple) {
104
105 bool called_a = false;
106 TestWindowProcDelegate delegate_a =
107 [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
108 called_a = true;
109 return std::optional<LRESULT>();
110 };
111 bool called_b = false;
112 TestWindowProcDelegate delegate_b =
113 [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
114 called_b = true;
115 return std::optional<LRESULT>();
116 };
117 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
118 &delegate_a);
119 // Function pointer is different, so both should be called.
120 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
121 &delegate_b);
122 manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
123
124 EXPECT_TRUE(called_a);
125 EXPECT_TRUE(called_b);
126}
127
128TEST(WindowProcDelegateManagerTest, Ordered) {
129 TestWindowProcDelegate delegate_1 = [](HWND hwnd, UINT message, WPARAM wparam,
130 LPARAM lparam) { return 1; };
131 TestWindowProcDelegate delegate_2 = [](HWND hwnd, UINT message, WPARAM wparam,
132 LPARAM lparam) { return 2; };
133
134 // Result should be 1 if delegate '1' is registered before delegate '2'.
135 {
137 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
138 &delegate_1);
139 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
140 &delegate_2);
141
142 std::optional<LRESULT> result =
143 manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
144
145 EXPECT_EQ(result, 1);
146 }
147
148 // Result should be 2 if delegate '2' is registered before delegate '1'.
149 {
151 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
152 &delegate_2);
153 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
154 &delegate_1);
155
156 std::optional<LRESULT> result =
157 manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
158
159 EXPECT_EQ(result, 2);
160 }
161}
162
163TEST(WindowProcDelegateManagerTest, ConflictingDelegates) {
165
166 bool called_a = false;
167 TestWindowProcDelegate delegate_a =
168 [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
169 called_a = true;
170 return std::optional<LRESULT>(1);
171 };
172 bool called_b = false;
173 TestWindowProcDelegate delegate_b =
174 [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
175 called_b = true;
176 return std::optional<LRESULT>(1);
177 };
178 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
179 &delegate_a);
180 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
181 &delegate_b);
182 auto result = manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
183
185 // Exactly one of the handlers should be called since each will claim to have
186 // handled the message. Which one is unspecified, since the calling order is
187 // unspecified.
188 EXPECT_TRUE(called_a || called_b);
189 EXPECT_NE(called_a, called_b);
190}
191
192TEST(WindowProcDelegateManagerTest, Unregister) {
194
195 bool called = false;
196 TestWindowProcDelegate delegate = [&called](HWND hwnd, UINT message,
197 WPARAM wparam, LPARAM lparam) {
198 called = true;
199 return std::optional<LRESULT>();
200 };
201 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback, &delegate);
202 manager.UnregisterTopLevelWindowProcDelegate(TestWindowProcCallback);
203 auto result = manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
204
205 EXPECT_FALSE(result);
206 EXPECT_FALSE(called);
207}
208
209} // namespace testing
210} // namespace flutter
#define TEST(S, s, D, expected)
void RegisterTopLevelWindowProcDelegate(FlutterDesktopWindowProcCallback callback, void *user_data)
GAsyncResult * result
Win32Message message
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
#define EXPECT_TRUE(handle)
Definition unit_test.h:685
LONG_PTR LRESULT
unsigned int UINT
LONG_PTR LPARAM
UINT_PTR WPARAM