5 #include "flutter/fml/macros.h"
7 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
8 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
9 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler_delegate.h"
10 #include "flutter/shell/platform/windows/testing/windows_test.h"
11 #include "flutter/shell/platform/windows/testing/wm_builders.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
20 using ::testing::AnyNumber;
22 using ::testing::Invoke;
23 using ::testing::Return;
26 static constexpr int32_t kDefaultPointerDeviceId = 0;
28 class MockFlutterWindow :
public FlutterWindow {
30 MockFlutterWindow(
bool reset_view_on_exit =
true)
31 : reset_view_on_exit_(reset_view_on_exit) {
32 ON_CALL(*
this, GetDpiScale())
35 virtual ~MockFlutterWindow() {
36 if (reset_view_on_exit_) {
42 UINT GetDpi() {
return GetCurrentDPI(); }
45 LRESULT InjectWindowMessage(UINT
const message,
47 LPARAM
const lparam) {
48 return HandleMessage(
message, wparam, lparam);
51 MOCK_METHOD(
void, OnDpiScale, (
unsigned int), (
override));
52 MOCK_METHOD(
void, OnResize, (
unsigned int,
unsigned int), (
override));
55 (
double,
double, FlutterPointerDeviceKind, int32_t,
int),
59 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
63 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
67 (
double,
double, FlutterPointerDeviceKind, int32_t),
69 MOCK_METHOD(
void, OnSetCursor, (), (
override));
70 MOCK_METHOD(
float, GetScrollOffsetMultiplier, (), (
override));
71 MOCK_METHOD(
float, GetDpiScale, (), (
override));
72 MOCK_METHOD(
void, UpdateCursorRect, (
const Rect&), (
override));
73 MOCK_METHOD(
void, OnResetImeComposing, (), (
override));
74 MOCK_METHOD(UINT, Win32DispatchMessage, (UINT, WPARAM, LPARAM), (
override));
75 MOCK_METHOD(BOOL, Win32PeekMessage, (LPMSG, UINT, UINT, UINT), (
override));
76 MOCK_METHOD(uint32_t, Win32MapVkToChar, (uint32_t), (
override));
77 MOCK_METHOD(HWND, GetWindowHandle, (), (
override));
78 MOCK_METHOD(ui::AXFragmentRootDelegateWin*,
79 GetAxFragmentRootDelegate,
86 LRESULT Win32DefWindowProc(HWND hWnd,
89 LPARAM lParam)
override {
90 return kWmResultDefault;
94 bool reset_view_on_exit_;
95 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindow);
98 class MockFlutterWindowsView :
public FlutterWindowsView {
101 std::unique_ptr<WindowBindingHandler> window_binding)
107 NotifyWinEventWrapper,
108 (ui::AXPlatformNodeWin*, ax::mojom::Event),
112 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
115 class FlutterWindowTest :
public WindowsTest {};
119 TEST_F(FlutterWindowTest, CreateDestroy) {
124 TEST_F(FlutterWindowTest, OnBitmapSurfaceUpdated) {
126 int old_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
128 constexpr
size_t row_bytes = 100 * 4;
129 constexpr
size_t height = 100;
130 std::array<char, row_bytes * height> allocation;
133 int new_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
135 EXPECT_EQ(old_handle_count, new_handle_count);
141 TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
142 MockFlutterWindow win32window;
143 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
146 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
148 win32window.OnCursorRectUpdated(cursor_rect);
154 TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
155 MockFlutterWindow win32window;
156 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
159 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
162 win32window.OnCursorRectUpdated(cursor_rect);
165 TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
167 MockWindowBindingHandlerDelegate delegate;
168 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
169 win32window.
SetView(&delegate);
172 EXPECT_CALL(delegate,
173 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
174 kDefaultPointerDeviceId, 0))
176 EXPECT_CALL(delegate,
177 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
178 kDefaultPointerDeviceId, 0))
180 EXPECT_CALL(delegate,
181 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
182 kDefaultPointerDeviceId, 0))
188 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
189 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
193 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
194 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
198 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
199 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
203 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
204 kDefaultPointerDeviceId,
205 kFlutterPointerButtonMousePrimary))
207 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
208 kDefaultPointerDeviceId,
209 kFlutterPointerButtonMousePrimary))
211 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
212 kDefaultPointerDeviceId,
213 kFlutterPointerButtonMousePrimary))
217 EXPECT_CALL(delegate,
218 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
219 kDefaultPointerDeviceId))
221 EXPECT_CALL(delegate,
222 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
223 kDefaultPointerDeviceId))
225 EXPECT_CALL(delegate,
226 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
227 kDefaultPointerDeviceId))
230 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
231 kDefaultPointerDeviceId, 0);
232 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
233 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
234 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
235 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
236 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
237 kDefaultPointerDeviceId);
240 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
241 kDefaultPointerDeviceId, 0);
242 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
243 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
244 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
245 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
246 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
247 kDefaultPointerDeviceId);
250 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
251 kDefaultPointerDeviceId, 0);
252 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
253 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
254 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
255 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
256 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
257 kDefaultPointerDeviceId);
266 TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
267 MockFlutterWindow win32window;
268 MockWindowBindingHandlerDelegate delegate;
269 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
270 win32window.SetView(&delegate);
272 EXPECT_CALL(win32window, GetWindowHandle).WillOnce([&win32window]() {
273 return win32window.FlutterWindow::GetWindowHandle();
275 EXPECT_CALL(win32window, GetScrollOffsetMultiplier).WillOnce(Return(120.0f));
277 EXPECT_CALL(delegate,
278 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
279 kDefaultPointerDeviceId))
282 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
283 kDefaultPointerDeviceId);
286 TEST_F(FlutterWindowTest, OnWindowRepaint) {
287 MockFlutterWindow win32window;
288 MockWindowBindingHandlerDelegate delegate;
289 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
290 win32window.SetView(&delegate);
292 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
294 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
297 TEST_F(FlutterWindowTest, OnThemeChange) {
298 MockFlutterWindow win32window;
299 MockWindowBindingHandlerDelegate delegate;
300 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
301 win32window.SetView(&delegate);
303 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
305 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
311 TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
312 MockFlutterWindow win32window;
314 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
320 std::unique_ptr<FlutterWindowsEngine> engine =
321 FlutterWindowsEngineBuilder{GetContext()}.Build();
322 auto win32window = std::make_unique<MockFlutterWindow>();
323 EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
324 .WillRepeatedly(Return(
nullptr));
325 EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
326 EXPECT_CALL(*win32window.get(), GetWindowHandle).Times(AnyNumber());
327 MockFlutterWindowsView view{engine.get(), std::move(win32window)};
328 std::wstring
message = L
"Test alert";
329 EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
333 IAccessible* alert = view.AlertNode();
334 VARIANT
self{.vt = VT_I4, .lVal = CHILDID_SELF};
336 alert->get_accName(
self, &strptr);
339 alert->get_accDescription(
self, &strptr);
342 alert->get_accValue(
self, &strptr);
346 alert->get_accRole(
self, &role);
347 EXPECT_EQ(role.vt, VT_I4);
348 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
351 TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
352 MockFlutterWindow win32window;
353 EXPECT_CALL(win32window, GetWindowHandle)
354 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
355 MockWindowBindingHandlerDelegate delegate;
358 EXPECT_CALL(delegate, OnWindowStateEvent)
362 EXPECT_CALL(win32window, OnWindowStateEvent)
364 win32window.FlutterWindow::OnWindowStateEvent(event);
366 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
368 win32window.SetView(&delegate);
370 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
373 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
376 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
377 Eq(FlutterViewFocusDirection::kUndefined)))
379 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
382 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kUnfocused),
383 Eq(FlutterViewFocusDirection::kUndefined)))
385 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
389 TEST_F(FlutterWindowTest, CachedLifecycleMessage) {
390 MockFlutterWindow win32window;
391 EXPECT_CALL(win32window, GetWindowHandle)
392 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
393 EXPECT_CALL(win32window, OnWindowStateEvent)
395 win32window.FlutterWindow::OnWindowStateEvent(event);
397 EXPECT_CALL(win32window, OnResize).Times(1);
400 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
403 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
405 MockWindowBindingHandlerDelegate delegate;
406 bool focused =
false;
407 bool restored =
false;
408 EXPECT_CALL(delegate, OnWindowStateEvent)
417 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
418 Eq(FlutterViewFocusDirection::kUndefined)))
420 win32window.SetView(&delegate);
421 EXPECT_TRUE(focused);
422 EXPECT_TRUE(restored);
425 TEST_F(FlutterWindowTest, UpdateCursor) {
428 HCURSOR cursor = ::GetCursor();
429 EXPECT_EQ(cursor, ::LoadCursor(
nullptr, IDC_IBEAM));