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;
21 using ::testing::Invoke;
22 using ::testing::Return;
25 static constexpr int32_t kDefaultPointerDeviceId = 0;
27 class MockFlutterWindow :
public FlutterWindow {
29 MockFlutterWindow(
bool reset_view_on_exit =
true)
30 : reset_view_on_exit_(reset_view_on_exit) {
31 ON_CALL(*
this, GetDpiScale())
34 virtual ~MockFlutterWindow() {
35 if (reset_view_on_exit_) {
41 UINT GetDpi() {
return GetCurrentDPI(); }
44 LRESULT InjectWindowMessage(UINT
const message,
46 LPARAM
const lparam) {
47 return HandleMessage(
message, wparam, lparam);
50 MOCK_METHOD(
void, OnDpiScale, (
unsigned int), (
override));
51 MOCK_METHOD(
void, OnResize, (
unsigned int,
unsigned int), (
override));
54 (
double,
double, FlutterPointerDeviceKind, int32_t,
int),
58 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
62 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
66 (
double,
double, FlutterPointerDeviceKind, int32_t),
68 MOCK_METHOD(
void, OnSetCursor, (), (
override));
69 MOCK_METHOD(
float, GetScrollOffsetMultiplier, (), (
override));
70 MOCK_METHOD(
float, GetDpiScale, (), (
override));
71 MOCK_METHOD(
void, UpdateCursorRect, (
const Rect&), (
override));
72 MOCK_METHOD(
void, OnResetImeComposing, (), (
override));
73 MOCK_METHOD(UINT, Win32DispatchMessage, (UINT, WPARAM, LPARAM), (
override));
74 MOCK_METHOD(BOOL, Win32PeekMessage, (LPMSG, UINT, UINT, UINT), (
override));
75 MOCK_METHOD(uint32_t, Win32MapVkToChar, (uint32_t), (
override));
76 MOCK_METHOD(HWND, GetWindowHandle, (), (
override));
77 MOCK_METHOD(ui::AXFragmentRootDelegateWin*,
78 GetAxFragmentRootDelegate,
85 LRESULT Win32DefWindowProc(HWND hWnd,
88 LPARAM lParam)
override {
89 return kWmResultDefault;
93 bool reset_view_on_exit_;
94 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindow);
97 class MockFlutterWindowsView :
public FlutterWindowsView {
100 std::unique_ptr<WindowBindingHandler> window_binding)
106 NotifyWinEventWrapper,
107 (ui::AXPlatformNodeWin*, ax::mojom::Event),
111 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
114 class FlutterWindowTest :
public WindowsTest {};
118 TEST_F(FlutterWindowTest, CreateDestroy) {
123 TEST_F(FlutterWindowTest, OnBitmapSurfaceUpdated) {
125 int old_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
127 constexpr
size_t row_bytes = 100 * 4;
128 constexpr
size_t height = 100;
129 std::array<char, row_bytes * height> allocation;
132 int new_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
134 EXPECT_EQ(old_handle_count, new_handle_count);
140 TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
141 MockFlutterWindow win32window;
142 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
145 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
147 win32window.OnCursorRectUpdated(cursor_rect);
153 TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
154 MockFlutterWindow win32window;
155 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
158 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
161 win32window.OnCursorRectUpdated(cursor_rect);
164 TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
166 MockWindowBindingHandlerDelegate delegate;
167 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
168 win32window.
SetView(&delegate);
171 EXPECT_CALL(delegate,
172 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
173 kDefaultPointerDeviceId, 0))
175 EXPECT_CALL(delegate,
176 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
177 kDefaultPointerDeviceId, 0))
179 EXPECT_CALL(delegate,
180 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
181 kDefaultPointerDeviceId, 0))
187 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
188 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
192 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
193 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
197 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
198 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
202 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
203 kDefaultPointerDeviceId,
204 kFlutterPointerButtonMousePrimary))
206 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
207 kDefaultPointerDeviceId,
208 kFlutterPointerButtonMousePrimary))
210 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
211 kDefaultPointerDeviceId,
212 kFlutterPointerButtonMousePrimary))
216 EXPECT_CALL(delegate,
217 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
218 kDefaultPointerDeviceId))
220 EXPECT_CALL(delegate,
221 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
222 kDefaultPointerDeviceId))
224 EXPECT_CALL(delegate,
225 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
226 kDefaultPointerDeviceId))
229 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
230 kDefaultPointerDeviceId, 0);
231 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
232 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
233 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
234 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
235 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
236 kDefaultPointerDeviceId);
239 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
240 kDefaultPointerDeviceId, 0);
241 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
242 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
243 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
244 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
245 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
246 kDefaultPointerDeviceId);
249 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
250 kDefaultPointerDeviceId, 0);
251 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
252 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
253 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
254 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
255 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
256 kDefaultPointerDeviceId);
265 TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
266 MockFlutterWindow win32window;
267 MockWindowBindingHandlerDelegate delegate;
268 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
269 win32window.SetView(&delegate);
271 EXPECT_CALL(win32window, GetWindowHandle).WillOnce([&win32window]() {
272 return win32window.FlutterWindow::GetWindowHandle();
274 EXPECT_CALL(win32window, GetScrollOffsetMultiplier).WillOnce(Return(120.0f));
276 EXPECT_CALL(delegate,
277 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
278 kDefaultPointerDeviceId))
281 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
282 kDefaultPointerDeviceId);
285 TEST_F(FlutterWindowTest, OnWindowRepaint) {
286 MockFlutterWindow win32window;
287 MockWindowBindingHandlerDelegate delegate;
288 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
289 win32window.SetView(&delegate);
291 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
293 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
296 TEST_F(FlutterWindowTest, OnThemeChange) {
297 MockFlutterWindow win32window;
298 MockWindowBindingHandlerDelegate delegate;
299 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
300 win32window.SetView(&delegate);
302 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
304 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
310 TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
311 MockFlutterWindow win32window;
313 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
319 std::unique_ptr<FlutterWindowsEngine> engine =
320 FlutterWindowsEngineBuilder{GetContext()}.Build();
321 auto win32window = std::make_unique<MockFlutterWindow>();
322 EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
323 .WillRepeatedly(Return(
nullptr));
324 EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
325 EXPECT_CALL(*win32window.get(), GetWindowHandle).Times(AnyNumber());
326 MockFlutterWindowsView view{engine.get(), std::move(win32window)};
327 std::wstring
message = L
"Test alert";
328 EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
332 IAccessible* alert = view.AlertNode();
333 VARIANT
self{.vt = VT_I4, .lVal = CHILDID_SELF};
335 alert->get_accName(
self, &strptr);
338 alert->get_accDescription(
self, &strptr);
341 alert->get_accValue(
self, &strptr);
345 alert->get_accRole(
self, &role);
346 EXPECT_EQ(role.vt, VT_I4);
347 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
350 TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
351 MockFlutterWindow win32window;
352 EXPECT_CALL(win32window, GetWindowHandle)
353 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
354 MockWindowBindingHandlerDelegate delegate;
357 EXPECT_CALL(delegate, OnWindowStateEvent)
361 EXPECT_CALL(win32window, OnWindowStateEvent)
363 win32window.FlutterWindow::OnWindowStateEvent(event);
365 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
367 win32window.SetView(&delegate);
369 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
372 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
375 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
378 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
382 TEST_F(FlutterWindowTest, CachedLifecycleMessage) {
383 MockFlutterWindow win32window;
384 EXPECT_CALL(win32window, GetWindowHandle)
385 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
386 EXPECT_CALL(win32window, OnWindowStateEvent)
388 win32window.FlutterWindow::OnWindowStateEvent(event);
390 EXPECT_CALL(win32window, OnResize).Times(1);
393 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
396 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
398 MockWindowBindingHandlerDelegate delegate;
399 bool focused =
false;
400 bool restored =
false;
401 EXPECT_CALL(delegate, OnWindowStateEvent)
410 win32window.SetView(&delegate);
411 EXPECT_TRUE(focused);
412 EXPECT_TRUE(restored);
415 TEST_F(FlutterWindowTest, UpdateCursor) {
418 HCURSOR cursor = ::GetCursor();
419 EXPECT_EQ(cursor, ::LoadCursor(
nullptr, IDC_IBEAM));