5 #include "flutter/fml/macros.h"
6 #include "flutter/shell/platform/windows/testing/flutter_window_test.h"
7 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
8 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler_delegate.h"
9 #include "flutter/shell/platform/windows/testing/wm_builders.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
15 using testing::AnyNumber;
16 using testing::Invoke;
17 using testing::Return;
23 static constexpr int32_t kDefaultPointerDeviceId = 0;
25 class MockFlutterWindow :
public FlutterWindow {
27 MockFlutterWindow(
bool reset_view_on_exit =
true)
28 : FlutterWindow(800, 600), reset_view_on_exit_(reset_view_on_exit) {
29 ON_CALL(*
this, GetDpiScale())
32 virtual ~MockFlutterWindow() {
33 if (reset_view_on_exit_) {
39 UINT GetDpi() {
return GetCurrentDPI(); }
42 LRESULT InjectWindowMessage(UINT
const message,
44 LPARAM
const lparam) {
45 return HandleMessage(
message, wparam, lparam);
48 MOCK_METHOD(
void, OnDpiScale, (
unsigned int), (
override));
49 MOCK_METHOD(
void, OnResize, (
unsigned int,
unsigned int), (
override));
52 (
double,
double, FlutterPointerDeviceKind, int32_t,
int),
56 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
60 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
64 (
double,
double, FlutterPointerDeviceKind, int32_t),
66 MOCK_METHOD(
void, OnSetCursor, (), (
override));
67 MOCK_METHOD(
float, GetScrollOffsetMultiplier, (), (
override));
68 MOCK_METHOD(
float, GetDpiScale, (), (
override));
69 MOCK_METHOD(
bool, IsVisible, (), (
override));
70 MOCK_METHOD(
void, UpdateCursorRect, (
const Rect&), (
override));
71 MOCK_METHOD(
void, OnResetImeComposing, (), (
override));
72 MOCK_METHOD(UINT, Win32DispatchMessage, (UINT, WPARAM, LPARAM), (
override));
73 MOCK_METHOD(BOOL, Win32PeekMessage, (LPMSG, UINT, UINT, UINT), (
override));
74 MOCK_METHOD(uint32_t, Win32MapVkToChar, (uint32_t), (
override));
75 MOCK_METHOD(HWND, GetWindowHandle, (), (
override));
76 MOCK_METHOD(ui::AXFragmentRootDelegateWin*,
77 GetAxFragmentRootDelegate,
84 LRESULT Win32DefWindowProc(HWND hWnd,
87 LPARAM lParam)
override {
88 return kWmResultDefault;
92 bool reset_view_on_exit_;
93 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindow);
96 class MockFlutterWindowsView :
public FlutterWindowsView {
103 NotifyWinEventWrapper,
104 (ui::AXPlatformNodeWin*, ax::mojom::Event),
108 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
113 TEST(FlutterWindowTest, CreateDestroy) {
114 FlutterWindowTest window(800, 600);
118 TEST(FlutterWindowTest, OnBitmapSurfaceUpdated) {
120 int old_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
122 constexpr
size_t row_bytes = 100 * 4;
123 constexpr
size_t height = 100;
124 std::array<char, row_bytes * height> allocation;
127 int new_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
129 EXPECT_EQ(old_handle_count, new_handle_count);
135 TEST(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
136 MockFlutterWindow win32window;
137 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
140 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
142 win32window.OnCursorRectUpdated(cursor_rect);
148 TEST(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
149 MockFlutterWindow win32window;
150 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
153 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
156 win32window.OnCursorRectUpdated(cursor_rect);
159 TEST(FlutterWindowTest, OnPointerStarSendsDeviceType) {
161 MockWindowBindingHandlerDelegate delegate;
162 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
163 win32window.
SetView(&delegate);
166 EXPECT_CALL(delegate,
167 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
168 kDefaultPointerDeviceId, 0))
170 EXPECT_CALL(delegate,
171 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
172 kDefaultPointerDeviceId, 0))
174 EXPECT_CALL(delegate,
175 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
176 kDefaultPointerDeviceId, 0))
182 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
183 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
187 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
188 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
192 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
193 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
197 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
198 kDefaultPointerDeviceId,
199 kFlutterPointerButtonMousePrimary))
201 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
202 kDefaultPointerDeviceId,
203 kFlutterPointerButtonMousePrimary))
205 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
206 kDefaultPointerDeviceId,
207 kFlutterPointerButtonMousePrimary))
211 EXPECT_CALL(delegate,
212 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
213 kDefaultPointerDeviceId))
215 EXPECT_CALL(delegate,
216 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
217 kDefaultPointerDeviceId))
219 EXPECT_CALL(delegate,
220 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
221 kDefaultPointerDeviceId))
224 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
225 kDefaultPointerDeviceId, 0);
226 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
227 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
228 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
229 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
230 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
231 kDefaultPointerDeviceId);
234 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
235 kDefaultPointerDeviceId, 0);
236 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
237 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
238 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
239 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
240 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
241 kDefaultPointerDeviceId);
244 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
245 kDefaultPointerDeviceId, 0);
246 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
247 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
248 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
249 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
250 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
251 kDefaultPointerDeviceId);
260 TEST(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
261 MockFlutterWindow win32window;
262 MockWindowBindingHandlerDelegate delegate;
263 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
264 win32window.SetView(&delegate);
266 ON_CALL(win32window, GetScrollOffsetMultiplier())
267 .WillByDefault(Return(120.0f));
268 EXPECT_CALL(win32window, GetScrollOffsetMultiplier()).Times(1);
270 EXPECT_CALL(delegate,
271 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
272 kDefaultPointerDeviceId))
275 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
276 kDefaultPointerDeviceId);
279 TEST(FlutterWindowTest, OnWindowRepaint) {
280 MockFlutterWindow win32window;
281 MockWindowBindingHandlerDelegate delegate;
282 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
283 win32window.SetView(&delegate);
285 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
287 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
290 TEST(FlutterWindowTest, OnThemeChange) {
291 MockFlutterWindow win32window;
292 MockWindowBindingHandlerDelegate delegate;
293 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
294 win32window.SetView(&delegate);
296 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
298 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
304 TEST(FlutterWindowTest, AccessibilityNodeWithoutView) {
305 MockFlutterWindow win32window;
307 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
312 TEST(FlutterWindowTest, AlertNode) {
313 std::unique_ptr<MockFlutterWindow> win32window =
314 std::make_unique<MockFlutterWindow>();
315 EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
316 .WillRepeatedly(Return(
nullptr));
317 EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
318 MockFlutterWindowsView view(std::move(win32window));
319 std::wstring
message = L
"Test alert";
320 EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
324 IAccessible* alert = view.AlertNode();
325 VARIANT
self{.vt = VT_I4, .lVal = CHILDID_SELF};
327 alert->get_accName(
self, &strptr);
330 alert->get_accDescription(
self, &strptr);
333 alert->get_accValue(
self, &strptr);
337 alert->get_accRole(
self, &role);
338 EXPECT_EQ(role.vt, VT_I4);
339 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
342 TEST(FlutterWindowTest, LifecycleFocusMessages) {
343 MockFlutterWindow win32window;
344 EXPECT_CALL(win32window, GetWindowHandle)
345 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
346 MockWindowBindingHandlerDelegate delegate;
349 EXPECT_CALL(delegate, OnWindowStateEvent)
353 EXPECT_CALL(win32window, OnWindowStateEvent)
355 win32window.FlutterWindow::OnWindowStateEvent(event);
357 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
359 win32window.SetView(&delegate);
361 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
364 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
367 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
370 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
374 TEST(FlutterWindowTest, CachedLifecycleMessage) {
375 MockFlutterWindow win32window;
376 EXPECT_CALL(win32window, GetWindowHandle)
377 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
378 EXPECT_CALL(win32window, OnWindowStateEvent)
380 win32window.FlutterWindow::OnWindowStateEvent(event);
382 EXPECT_CALL(win32window, OnResize).Times(1);
385 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
388 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
390 MockWindowBindingHandlerDelegate delegate;
391 bool focused =
false;
392 bool restored =
false;
393 EXPECT_CALL(delegate, OnWindowStateEvent)
402 win32window.SetView(&delegate);
403 EXPECT_TRUE(focused);
404 EXPECT_TRUE(restored);
407 TEST(FlutterWindowTest, PosthumousWindowMessage) {
408 MockWindowBindingHandlerDelegate delegate;
411 EXPECT_CALL(delegate, OnWindowStateEvent)
415 MockFlutterWindow win32window(
false);
416 EXPECT_CALL(win32window, GetWindowHandle).WillRepeatedly([&]() {
417 return win32window.FlutterWindow::GetWindowHandle();
419 EXPECT_CALL(win32window, OnWindowStateEvent)
421 win32window.FlutterWindow::OnWindowStateEvent(event);
423 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
424 win32window.SetView(&delegate);
425 win32window.InitializeChild(
"Title", 1, 1);
426 hwnd = win32window.GetWindowHandle();
427 SendMessage(hwnd, WM_SIZE, 0, MAKEWORD(1, 1));
428 SendMessage(hwnd, WM_SETFOCUS, 0, 0);
436 EXPECT_GE(msg_count, 1);