| Flutter Windows Embedder |

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
8 namespace flutter {
9 namespace testing {
10
11 namespace {
12
13 #ifdef _WIN32
14 #define FLUTTER_NOINLINE __declspec(noinline)
15 #else
16 #define FLUTTER_NOINLINE __attribute__((noinline))
17 #endif
18
19 using 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.
24 FLUTTER_NOINLINE
25 bool TestWindowProcCallback(HWND hwnd,
26 UINT message,
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.
42 bool TestWindowProcCallback2(HWND hwnd,
43 UINT message,
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
54 TEST(WindowProcDelegateManagerTest, CallsCorrectly) {
55 WindowProcDelegateManager manager;
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
76 TEST(WindowProcDelegateManagerTest, ReplacementRegister) {
77 WindowProcDelegateManager manager;
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
102 TEST(WindowProcDelegateManagerTest, RegisterMultiple) {
103 WindowProcDelegateManager manager;
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
128 TEST(WindowProcDelegateManagerTest, ConflictingDelegates) {
129 WindowProcDelegateManager manager;
130
131 bool called_a = false;
132 TestWindowProcDelegate delegate_a =
133 [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
134 called_a = true;
135 return std::optional<LRESULT>(1);
136 };
137 bool called_b = false;
138 TestWindowProcDelegate delegate_b =
139 [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
140 called_b = true;
141 return std::optional<LRESULT>(1);
142 };
143 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
144 &delegate_a);
145 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
146 &delegate_b);
147 auto result = manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
148
149 EXPECT_TRUE(result);
150 // Exactly one of the handlers should be called since each will claim to have
151 // handled the message. Which one is unspecified, since the calling order is
152 // unspecified.
153 EXPECT_TRUE(called_a || called_b);
154 EXPECT_NE(called_a, called_b);
155 }
156
157 TEST(WindowProcDelegateManagerTest, Unregister) {
158 WindowProcDelegateManager manager;
159
160 bool called = false;
161 TestWindowProcDelegate delegate = [&called](HWND hwnd, UINT message,
162 WPARAM wparam, LPARAM lparam) {
163 called = true;
164 return std::optional<LRESULT>();
165 };
166 manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback, &delegate);
167 manager.UnregisterTopLevelWindowProcDelegate(TestWindowProcCallback);
168 auto result = manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);
169
170 EXPECT_FALSE(result);
171 EXPECT_FALSE(called);
172 }
173
174 } // namespace testing
175 } // namespace flutter
window_proc_delegate_manager.h
user_data
void * user_data
Definition: flutter_windows_view_unittests.cc:47
flutter::WindowProcDelegateManager::OnTopLevelWindowProc
std::optional< LRESULT > OnTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: window_proc_delegate_manager.cc:25
flutter::WindowProcDelegateManager::RegisterTopLevelWindowProcDelegate
void RegisterTopLevelWindowProcDelegate(FlutterDesktopWindowProcCallback delegate, void *user_data)
Definition: window_proc_delegate_manager.cc:14
FLUTTER_NOINLINE
#define FLUTTER_NOINLINE
Definition: window_proc_delegate_manager_unittests.cc:16
flutter::WindowProcDelegateManager::UnregisterTopLevelWindowProcDelegate
void UnregisterTopLevelWindowProcDelegate(FlutterDesktopWindowProcCallback delegate)
Definition: window_proc_delegate_manager.cc:20
flutter::WindowProcDelegateManager
Definition: window_proc_delegate_manager.h:20
flutter
Definition: accessibility_bridge_windows.cc:11
flutter::testing::TEST
TEST(AccessibilityBridgeWindows, GetParent)
Definition: accessibility_bridge_windows_unittests.cc:233
message
Win32Message message
Definition: keyboard_unittests.cc:137