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::Invoke;
16 using testing::Return;
22 static constexpr int32_t kDefaultPointerDeviceId = 0;
24 class MockFlutterWindow :
public FlutterWindow {
26 MockFlutterWindow(
bool reset_view_on_exit =
true)
27 : FlutterWindow(800, 600), reset_view_on_exit_(reset_view_on_exit) {
28 ON_CALL(*
this, GetDpiScale())
31 virtual ~MockFlutterWindow() {
32 if (reset_view_on_exit_) {
38 UINT GetDpi() {
return GetCurrentDPI(); }
41 LRESULT InjectWindowMessage(UINT
const message,
43 LPARAM
const lparam) {
44 return HandleMessage(
message, wparam, lparam);
47 MOCK_METHOD(
void, OnDpiScale, (
unsigned int), (
override));
48 MOCK_METHOD(
void, OnResize, (
unsigned int,
unsigned int), (
override));
51 (
double,
double, FlutterPointerDeviceKind, int32_t,
int),
55 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
59 (
double,
double, FlutterPointerDeviceKind, int32_t, UINT),
63 (
double,
double, FlutterPointerDeviceKind, int32_t),
65 MOCK_METHOD(
void, OnSetCursor, (), (
override));
66 MOCK_METHOD(
float, GetScrollOffsetMultiplier, (), (
override));
67 MOCK_METHOD(
bool, GetHighContrastEnabled, (), (
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, GetPlatformWindow, (), (
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 ON_CALL(win32window, GetDpiScale()).WillByDefault(Return(1.0));
138 EXPECT_CALL(win32window, GetDpiScale()).Times(1);
141 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
143 win32window.OnCursorRectUpdated(cursor_rect);
149 TEST(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
150 MockFlutterWindow win32window;
151 ON_CALL(win32window, GetDpiScale()).WillByDefault(Return(1.5));
152 EXPECT_CALL(win32window, GetDpiScale()).Times(1);
155 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
158 win32window.OnCursorRectUpdated(cursor_rect);
161 TEST(FlutterWindowTest, OnPointerStarSendsDeviceType) {
163 MockWindowBindingHandlerDelegate delegate;
164 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 win32window.SetView(&delegate);
265 ON_CALL(win32window, GetScrollOffsetMultiplier())
266 .WillByDefault(Return(120.0f));
267 EXPECT_CALL(win32window, GetScrollOffsetMultiplier()).Times(1);
269 EXPECT_CALL(delegate,
270 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
271 kDefaultPointerDeviceId))
274 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
275 kDefaultPointerDeviceId);
278 TEST(FlutterWindowTest, OnWindowRepaint) {
279 MockFlutterWindow win32window;
280 MockWindowBindingHandlerDelegate delegate;
281 win32window.SetView(&delegate);
283 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
285 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
288 TEST(FlutterWindowTest, OnThemeChange) {
289 MockFlutterWindow win32window;
290 MockWindowBindingHandlerDelegate delegate;
291 win32window.SetView(&delegate);
293 ON_CALL(win32window, GetHighContrastEnabled()).WillByDefault(Return(
true));
294 EXPECT_CALL(delegate, UpdateHighContrastEnabled(
true)).Times(1);
296 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
302 TEST(FlutterWindowTest, AccessibilityNodeWithoutView) {
303 MockFlutterWindow win32window;
305 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
308 TEST(FlutterWindowTest, InitialAccessibilityFeatures) {
309 MockFlutterWindow win32window;
310 MockWindowBindingHandlerDelegate delegate;
311 win32window.SetView(&delegate);
313 ON_CALL(win32window, GetHighContrastEnabled()).WillByDefault(Return(
true));
314 EXPECT_CALL(delegate, UpdateHighContrastEnabled(
true)).Times(1);
316 win32window.SendInitialAccessibilityFeatures();
321 TEST(FlutterWindowTest, AlertNode) {
322 std::unique_ptr<MockFlutterWindow> win32window =
323 std::make_unique<MockFlutterWindow>();
324 ON_CALL(*win32window, GetPlatformWindow()).WillByDefault(Return(
nullptr));
325 ON_CALL(*win32window, GetAxFragmentRootDelegate())
326 .WillByDefault(Return(
nullptr));
327 MockFlutterWindowsView view(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(FlutterWindowTest, LifecycleFocusMessages) {
352 MockFlutterWindow win32window;
353 ON_CALL(win32window, GetPlatformWindow).WillByDefault([]() {
354 return reinterpret_cast<HWND
>(1);
356 MockWindowBindingHandlerDelegate delegate;
357 win32window.SetView(&delegate);
360 ON_CALL(delegate, OnWindowStateEvent)
364 ON_CALL(win32window, OnWindowStateEvent)
366 win32window.FlutterWindow::OnWindowStateEvent(event);
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(FlutterWindowTest, CachedLifecycleMessage) {
383 MockFlutterWindow win32window;
384 ON_CALL(win32window, GetPlatformWindow).WillByDefault([]() {
385 return reinterpret_cast<HWND
>(1);
387 ON_CALL(win32window, OnWindowStateEvent)
389 win32window.FlutterWindow::OnWindowStateEvent(event);
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 ON_CALL(delegate, OnWindowStateEvent)
410 win32window.SetView(&delegate);
411 EXPECT_TRUE(focused);
412 EXPECT_TRUE(restored);
415 TEST(FlutterWindowTest, PosthumousWindowMessage) {
416 MockWindowBindingHandlerDelegate delegate;
419 ON_CALL(delegate, OnWindowStateEvent)
423 MockFlutterWindow win32window(
false);
424 ON_CALL(win32window, GetPlatformWindow).WillByDefault([&]() {
425 return win32window.FlutterWindow::GetPlatformWindow();
427 ON_CALL(win32window, OnWindowStateEvent)
429 win32window.FlutterWindow::OnWindowStateEvent(event);
431 win32window.SetView(&delegate);
432 win32window.InitializeChild(
"Title", 1, 1);
433 hwnd = win32window.GetPlatformWindow();
434 SendMessage(hwnd, WM_SIZE, 0, MAKEWORD(1, 1));
435 SendMessage(hwnd, WM_SETFOCUS, 0, 0);
443 EXPECT_GE(msg_count, 1);