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(
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) {
119 std::unique_ptr<FlutterWindowsEngine> engine =
120 FlutterWindowsEngineBuilder{GetContext()}.Build();
125 TEST_F(FlutterWindowTest, OnBitmapSurfaceUpdated) {
126 std::unique_ptr<FlutterWindowsEngine> engine =
127 FlutterWindowsEngineBuilder{GetContext()}.Build();
128 FlutterWindow win32window(100, 100, engine->display_manager());
129 int old_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
131 constexpr
size_t row_bytes = 100 * 4;
132 constexpr
size_t height = 100;
133 std::array<char, row_bytes * height> allocation;
136 int new_handle_count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
138 EXPECT_EQ(old_handle_count, new_handle_count);
144 TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
145 MockFlutterWindow win32window;
146 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
148 Rect cursor_rect(Point(10, 20), Size(30, 40));
149 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
151 win32window.OnCursorRectUpdated(cursor_rect);
157 TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
158 MockFlutterWindow win32window;
159 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
161 Rect expected_cursor_rect(Point(15, 30), Size(45, 60));
162 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
164 Rect cursor_rect(Point(10, 20), Size(30, 40));
165 win32window.OnCursorRectUpdated(cursor_rect);
168 TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
169 std::unique_ptr<FlutterWindowsEngine> engine =
170 FlutterWindowsEngineBuilder{GetContext()}.Build();
171 FlutterWindow win32window(100, 100, engine->display_manager());
172 MockWindowBindingHandlerDelegate delegate;
173 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
174 win32window.
SetView(&delegate);
177 EXPECT_CALL(delegate,
178 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
179 kDefaultPointerDeviceId, 0))
181 EXPECT_CALL(delegate,
182 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
183 kDefaultPointerDeviceId, 0))
185 EXPECT_CALL(delegate,
186 OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
187 kDefaultPointerDeviceId, 0))
193 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
194 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
198 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
199 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
203 OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
204 kDefaultPointerDeviceId, kFlutterPointerButtonMousePrimary))
208 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
209 kDefaultPointerDeviceId,
210 kFlutterPointerButtonMousePrimary))
212 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
213 kDefaultPointerDeviceId,
214 kFlutterPointerButtonMousePrimary))
216 EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
217 kDefaultPointerDeviceId,
218 kFlutterPointerButtonMousePrimary))
222 EXPECT_CALL(delegate,
223 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
224 kDefaultPointerDeviceId))
226 EXPECT_CALL(delegate,
227 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
228 kDefaultPointerDeviceId))
230 EXPECT_CALL(delegate,
231 OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
232 kDefaultPointerDeviceId))
235 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse,
236 kDefaultPointerDeviceId, 0);
237 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
238 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
239 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
240 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
241 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindMouse,
242 kDefaultPointerDeviceId);
245 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch,
246 kDefaultPointerDeviceId, 0);
247 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
248 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
249 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
250 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
251 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindTouch,
252 kDefaultPointerDeviceId);
255 win32window.
OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus,
256 kDefaultPointerDeviceId, 0);
257 win32window.
OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
258 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
259 win32window.
OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
260 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
261 win32window.
OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
262 kDefaultPointerDeviceId);
271 TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
272 MockFlutterWindow win32window;
273 MockWindowBindingHandlerDelegate delegate;
274 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
275 win32window.SetView(&delegate);
277 EXPECT_CALL(win32window, GetWindowHandle).WillOnce([&win32window]() {
278 return win32window.FlutterWindow::GetWindowHandle();
280 EXPECT_CALL(win32window, GetScrollOffsetMultiplier).WillOnce(Return(120.0f));
282 EXPECT_CALL(delegate,
283 OnScroll(_, _, 0, 0, 120.0f, kFlutterPointerDeviceKindMouse,
284 kDefaultPointerDeviceId))
287 win32window.OnScroll(0.0f, 0.0f, kFlutterPointerDeviceKindMouse,
288 kDefaultPointerDeviceId);
291 TEST_F(FlutterWindowTest, OnWindowRepaint) {
292 MockFlutterWindow win32window;
293 MockWindowBindingHandlerDelegate delegate;
294 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
295 win32window.SetView(&delegate);
297 EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);
299 win32window.InjectWindowMessage(WM_PAINT, 0, 0);
302 TEST_F(FlutterWindowTest, OnThemeChange) {
303 MockFlutterWindow win32window;
304 MockWindowBindingHandlerDelegate delegate;
305 EXPECT_CALL(win32window, OnWindowStateEvent).Times(AnyNumber());
306 win32window.SetView(&delegate);
308 EXPECT_CALL(delegate, OnHighContrastChanged).Times(1);
310 win32window.InjectWindowMessage(WM_THEMECHANGED, 0, 0);
316 TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
317 MockFlutterWindow win32window;
319 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
325 std::unique_ptr<FlutterWindowsEngine> engine =
326 FlutterWindowsEngineBuilder{GetContext()}.Build();
327 auto win32window = std::make_unique<MockFlutterWindow>();
328 EXPECT_CALL(*win32window.get(), GetAxFragmentRootDelegate())
329 .WillRepeatedly(Return(
nullptr));
330 EXPECT_CALL(*win32window.get(), OnWindowStateEvent).Times(AnyNumber());
331 EXPECT_CALL(*win32window.get(), GetWindowHandle).Times(AnyNumber());
332 MockFlutterWindowsView view{engine.get(), std::move(win32window)};
333 std::wstring
message = L
"Test alert";
334 EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
338 IAccessible* alert = view.AlertNode();
339 VARIANT
self{.vt = VT_I4, .lVal = CHILDID_SELF};
341 alert->get_accName(
self, &strptr);
344 alert->get_accDescription(
self, &strptr);
347 alert->get_accValue(
self, &strptr);
351 alert->get_accRole(
self, &role);
352 EXPECT_EQ(role.vt, VT_I4);
353 EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
356 TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
357 MockFlutterWindow win32window;
358 EXPECT_CALL(win32window, GetWindowHandle)
359 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
360 MockWindowBindingHandlerDelegate delegate;
363 EXPECT_CALL(delegate, OnWindowStateEvent)
367 EXPECT_CALL(win32window, OnWindowStateEvent)
369 win32window.FlutterWindow::OnWindowStateEvent(event);
371 EXPECT_CALL(win32window, OnResize).Times(AnyNumber());
373 win32window.SetView(&delegate);
375 win32window.InjectWindowMessage(WM_SIZE, 0, 0);
378 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
381 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
382 Eq(FlutterViewFocusDirection::kUndefined)))
384 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
387 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kUnfocused),
388 Eq(FlutterViewFocusDirection::kUndefined)))
390 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
394 TEST_F(FlutterWindowTest, CachedLifecycleMessage) {
395 MockFlutterWindow win32window;
396 EXPECT_CALL(win32window, GetWindowHandle)
397 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
398 EXPECT_CALL(win32window, OnWindowStateEvent)
400 win32window.FlutterWindow::OnWindowStateEvent(event);
402 EXPECT_CALL(win32window, OnResize).Times(1);
405 win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1));
408 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
410 MockWindowBindingHandlerDelegate delegate;
411 bool focused =
false;
412 bool restored =
false;
413 EXPECT_CALL(delegate, OnWindowStateEvent)
422 EXPECT_CALL(delegate, OnFocus(Eq(FlutterViewFocusState::kFocused),
423 Eq(FlutterViewFocusDirection::kUndefined)))
425 win32window.SetView(&delegate);
426 EXPECT_TRUE(focused);
427 EXPECT_TRUE(restored);
virtual void OnPointerLeave(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id)
virtual bool OnBitmapSurfaceUpdated(const void *allocation, size_t row_bytes, size_t height) override
virtual void OnPointerUp(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
virtual void OnPointerDown(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, UINT button)
virtual void OnPointerMove(double x, double y, FlutterPointerDeviceKind device_kind, int32_t device_id, int modifiers_state)
virtual void SetView(WindowBindingHandlerDelegate *view) override
virtual float GetDpiScale() override
FlutterWindowsView(FlutterViewId view_id, FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > window_binding, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
TEST_F(CompositorOpenGLTest, CreateBackingStore)
WindowStateEvent
An event representing a change in window state that may update the.
constexpr FlutterViewId kImplicitViewId