13#include "gmock/gmock.h"
14#include "gtest/gtest.h"
20using ::testing::AnyNumber;
22using ::testing::Invoke;
23using ::testing::Return;
26static constexpr int32_t kDefaultPointerDeviceId = 0;
28class 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(); }
48 return HandleMessage(
message, wparam, lparam);
51 MOCK_METHOD(
void, OnDpiScale, (
unsigned int), (
override));
52 MOCK_METHOD(
void, OnResize, (
unsigned int,
unsigned int), (
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));
75 MOCK_METHOD(uint32_t, Win32MapVkToChar, (uint32_t), (
override));
76 MOCK_METHOD(HWND, GetWindowHandle, (), (
override));
78 GetAxFragmentRootDelegate,
85 LRESULT Win32DefWindowProc(HWND hWnd,
93 bool reset_view_on_exit_;
97class MockFlutterWindowsView :
public FlutterWindowsView {
100 std::unique_ptr<WindowBindingHandler> window_binding)
106 NotifyWinEventWrapper,
114class FlutterWindowTest :
public WindowsTest {};
118TEST_F(FlutterWindowTest, CreateDestroy) {
119 std::unique_ptr<FlutterWindowsEngine>
engine =
125TEST_F(FlutterWindowTest, OnBitmapSurfaceUpdated) {
126 std::unique_ptr<FlutterWindowsEngine>
engine =
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);
144TEST_F(FlutterWindowTest, OnCursorRectUpdatedRegularDPI) {
145 MockFlutterWindow win32window;
146 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.0));
149 EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);
151 win32window.OnCursorRectUpdated(cursor_rect);
157TEST_F(FlutterWindowTest, OnCursorRectUpdatedHighDPI) {
158 MockFlutterWindow win32window;
159 EXPECT_CALL(win32window, GetDpiScale()).WillOnce(Return(1.5));
162 EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);
165 win32window.OnCursorRectUpdated(cursor_rect);
168TEST_F(FlutterWindowTest, OnPointerStarSendsDeviceType) {
169 std::unique_ptr<FlutterWindowsEngine>
engine =
173 EXPECT_CALL(delegate, OnWindowStateEvent).Times(AnyNumber());
174 win32window.
SetView(&delegate);
177 EXPECT_CALL(delegate,
179 kDefaultPointerDeviceId, 0))
181 EXPECT_CALL(delegate,
183 kDefaultPointerDeviceId, 0))
185 EXPECT_CALL(delegate,
187 kDefaultPointerDeviceId, 0))
209 kDefaultPointerDeviceId,
213 kDefaultPointerDeviceId,
217 kDefaultPointerDeviceId,
222 EXPECT_CALL(delegate,
224 kDefaultPointerDeviceId))
226 EXPECT_CALL(delegate,
228 kDefaultPointerDeviceId))
230 EXPECT_CALL(delegate,
232 kDefaultPointerDeviceId))
236 kDefaultPointerDeviceId, 0);
238 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
240 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
242 kDefaultPointerDeviceId);
246 kDefaultPointerDeviceId, 0);
248 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
250 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
252 kDefaultPointerDeviceId);
256 kDefaultPointerDeviceId, 0);
258 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
260 kDefaultPointerDeviceId, WM_LBUTTONDOWN);
262 kDefaultPointerDeviceId);
271TEST_F(FlutterWindowTest, OnScrollCallsGetScrollOffsetMultiplier) {
272 MockFlutterWindow win32window;
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,
284 kDefaultPointerDeviceId))
288 kDefaultPointerDeviceId);
291TEST_F(FlutterWindowTest, OnWindowRepaint) {
292 MockFlutterWindow win32window;
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);
302TEST_F(FlutterWindowTest, OnThemeChange) {
303 MockFlutterWindow win32window;
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);
316TEST_F(FlutterWindowTest, AccessibilityNodeWithoutView) {
317 MockFlutterWindow win32window;
319 EXPECT_EQ(win32window.GetNativeViewAccessible(),
nullptr);
325 std::unique_ptr<FlutterWindowsEngine>
engine =
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";
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);
356TEST_F(FlutterWindowTest, LifecycleFocusMessages) {
357 MockFlutterWindow win32window;
358 EXPECT_CALL(win32window, GetWindowHandle)
359 .WillRepeatedly(Return(
reinterpret_cast<HWND
>(1)));
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));
384 win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0);
390 win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0);
394TEST_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);
411 bool focused =
false;
412 bool restored =
false;
413 EXPECT_CALL(delegate, OnWindowStateEvent)
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)
std::unique_ptr< FlutterWindowsEngine > Build()
~MockFlutterWindowsView()
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
@ kUnfocused
Specifies that a view does not have platform focus.
@ kFocused
Specifies that a view has platform focus.
@ kFlutterPointerButtonMousePrimary
FlutterPointerDeviceKind
The device type that created a pointer event.
@ kFlutterPointerDeviceKindTouch
@ kFlutterPointerDeviceKindStylus
@ kFlutterPointerDeviceKindMouse
G_BEGIN_DECLS GBytes * message
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
TEST_F(DisplayListTest, Defaults)
constexpr LRESULT kWmResultDefault
constexpr int64_t kImplicitViewId
WindowStateEvent
An event representing a change in window state that may update the.