25#include "gmock/gmock.h"
26#include "gtest/gtest.h"
37 ::TranslateMessage(&msg);
47using ::testing::DoAll;
48using ::testing::NiceMock;
49using ::testing::Return;
50using ::testing::SetArgPointee;
57 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
62 ASSERT_TRUE(
engine->Run());
64 ASSERT_EQ(
engine->view(123),
nullptr);
68 bool finished =
false;
69 auto runner = std::make_unique<TaskRunner>(
71 return static_cast<uint64_t
>(
75 runner->PostFlutterTask(
90 auto runner = std::make_unique<TaskRunner>(
92 return static_cast<uint64_t
>(
99 runner->PostTask([
this] { PostTaskLoop(); });
101 std::unique_ptr<TaskRunner> runner;
104 RunnerHolder container{.runner = std::move(runner)};
106 container.PostTaskLoop();
108 const LPCWSTR class_name = L
"FlutterTestWindowClass";
110 wc.lpfnWndProc = DefWindowProc;
111 wc.lpszClassName = class_name;
115 container.runner->PostTask([&] {
116 window = CreateWindowEx(0, class_name, L
"Empty Window", WS_OVERLAPPEDWINDOW,
117 CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
nullptr,
118 nullptr,
nullptr,
nullptr);
119 ShowWindow(
window, SW_SHOW);
125 if (msg.message == WM_PAINT) {
128 ::TranslateMessage(&msg);
134 UnregisterClassW(class_name,
nullptr);
140 builder.AddDartEntrypointArgument(
"arg2");
142 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
144 HMONITOR mock_monitor =
reinterpret_cast<HMONITOR
>(1);
146 MONITORINFOEXW monitor_info = {};
147 monitor_info.cbSize =
sizeof(MONITORINFOEXW);
148 monitor_info.rcMonitor = {0, 0, 1920, 1080};
149 monitor_info.rcWork = {0, 0, 1920, 1080};
150 monitor_info.dwFlags = MONITORINFOF_PRIMARY;
151 wcscpy_s(monitor_info.szDevice, L
"\\\\.\\DISPLAY1");
153 EXPECT_CALL(*windows_proc_table, GetMonitorInfoW(mock_monitor, _))
154 .WillRepeatedly(DoAll(SetArgPointee<1>(monitor_info), Return(
TRUE)));
156 EXPECT_CALL(*windows_proc_table, EnumDisplayMonitors(
nullptr,
nullptr, _, _))
157 .WillRepeatedly([&](HDC hdc, LPCRECT lprcClip, MONITORENUMPROC lpfnEnum,
159 lpfnEnum(mock_monitor,
nullptr, &monitor_info.rcMonitor, dwData);
164 .WillRepeatedly(Return(96));
167 EXPECT_CALL(*windows_proc_table, GetThreadPreferredUILanguages(_, _, _, _))
169 [](
DWORD flags, PULONG count, PZZWSTR languages, PULONG
length) {
173 if (languages ==
nullptr) {
182 wchar_t* lang_buffer = languages;
183 wcscpy(lang_buffer, L
"fr-FR");
185 lang_buffer += wcslen(L
"fr-FR") + 1;
186 *lang_buffer = L
'\0';
191 builder.SetWindowsProcTable(windows_proc_table);
193 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
197 bool run_called =
false;
199 Run, ([&run_called, engine_instance =
engine.get()](
207 EXPECT_NE(config,
nullptr);
212 EXPECT_NE(
args->assets_path,
nullptr);
213 EXPECT_NE(
args->icu_data_path,
nullptr);
214 EXPECT_EQ(
args->dart_entrypoint_argc, 2U);
215 EXPECT_EQ(strcmp(
args->dart_entrypoint_argv[0],
"arg1"), 0);
216 EXPECT_EQ(strcmp(
args->dart_entrypoint_argv[1],
"arg2"), 0);
217 EXPECT_NE(
args->platform_message_callback,
nullptr);
218 EXPECT_NE(
args->custom_task_runners,
nullptr);
219 EXPECT_NE(
args->custom_task_runners->thread_priority_setter,
nullptr);
220 EXPECT_EQ(
args->custom_dart_entrypoint,
nullptr);
221 EXPECT_NE(
args->vsync_callback,
nullptr);
222 EXPECT_EQ(
args->update_semantics_callback,
nullptr);
223 EXPECT_NE(
args->update_semantics_callback2,
nullptr);
224 EXPECT_EQ(
args->update_semantics_node_callback,
nullptr);
225 EXPECT_EQ(
args->update_semantics_custom_action_callback,
nullptr);
226 EXPECT_NE(
args->view_focus_change_request_callback,
nullptr);
228 args->custom_task_runners->thread_priority_setter(
230 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
231 THREAD_PRIORITY_ABOVE_NORMAL);
236 UpdateAccessibilityFeatures,
241 bool update_locales_called =
false;
245 size_t locales_count) {
246 update_locales_called =
true;
248 EXPECT_GT(locales_count, 0);
249 EXPECT_NE(locales,
nullptr);
255 bool settings_message_sent =
false;
259 if (std::string(
message->channel) == std::string(
"flutter/settings")) {
260 settings_message_sent = true;
267 bool notify_display_update_called =
false;
271 ([¬ify_display_update_called](
275 size_t display_count) {
277 notify_display_update_called =
true;
282 modifier.
SetEGLManager(std::make_unique<egl::MockManager>());
286 EXPECT_TRUE(run_called);
287 EXPECT_TRUE(update_locales_called);
288 EXPECT_TRUE(settings_message_sent);
289 EXPECT_TRUE(notify_display_update_called);
299 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
301 bool on_vsync_called =
false;
307 ([&on_vsync_called, engine_instance =
engine.get()](
309 uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos) {
311 EXPECT_EQ(frame_start_time_nanos, 16600000);
312 EXPECT_EQ(frame_target_time_nanos, 33200000);
313 on_vsync_called =
true;
321 EXPECT_TRUE(on_vsync_called);
327 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
332 ([engine_instance =
engine.get()](
336 size_t display_count) {
return kSuccess; }));
339 bool run_called =
false;
341 Run, ([&run_called, engine_instance =
engine.get()](
353 UpdateAccessibilityFeatures,
361 size_t locales_count) {
return kSuccess; }));
371 EXPECT_TRUE(run_called);
381 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
386 ([engine_instance =
engine.get()](
390 size_t display_count) {
return kSuccess; }));
394 UpdateAccessibilityFeatures,
402 size_t locales_count) {
return kSuccess; }));
410 EXPECT_FALSE(
engine->Run());
416 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
421 ([engine_instance =
engine.get()](
425 size_t display_count) {
return kSuccess; }));
428 UpdateAccessibilityFeatures,
434 size_t locales_count) {
return kSuccess; }));
440 bool run_called =
false;
442 Run, ([&run_called, engine_instance =
engine.get()](
449 bool has_impeller_switch =
false;
450 bool has_sdf_switch =
false;
451 for (
int i = 0;
i <
args->command_line_argc; ++
i) {
452 if (strcmp(
args->command_line_argv[
i],
"--enable-impeller") == 0) {
453 has_impeller_switch = true;
455 if (strcmp(
args->command_line_argv[
i],
"--impeller-use-sdfs=true") ==
457 has_sdf_switch = true;
460 EXPECT_TRUE(has_impeller_switch);
461 EXPECT_TRUE(has_sdf_switch);
466 modifier.
SetEGLManager(std::make_unique<egl::MockManager>());
470 EXPECT_TRUE(run_called);
479 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
487 size_t display_count) {
return kSuccess; }));
490 UpdateAccessibilityFeatures,
496 size_t locales_count) {
return kSuccess; }));
502 bool run_called =
false;
510 bool has_impeller_switch =
false;
511 bool has_sdf_switch =
false;
512 for (
int i = 0;
i <
args->command_line_argc; ++
i) {
513 if (strcmp(
args->command_line_argv[
i],
"--enable-impeller") == 0) {
514 has_impeller_switch = true;
516 if (strcmp(
args->command_line_argv[
i],
"--impeller-use-sdfs=true") ==
518 has_sdf_switch = true;
521 EXPECT_TRUE(has_impeller_switch);
522 EXPECT_TRUE(has_sdf_switch);
527 modifier.
SetEGLManager(std::make_unique<egl::MockManager>());
531 EXPECT_TRUE(run_called);
540 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
548 size_t display_count) {
return kSuccess; }));
551 UpdateAccessibilityFeatures,
557 size_t locales_count) {
return kSuccess; }));
563 bool run_called =
false;
571 bool has_disable_impeller_switch =
false;
572 for (
int i = 0;
i <
args->command_line_argc; ++
i) {
573 if (strcmp(
args->command_line_argv[
i],
"--enable-impeller=false") ==
575 has_disable_impeller_switch = true;
578 EXPECT_TRUE(has_disable_impeller_switch);
584 EXPECT_TRUE(run_called);
592 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
600 size_t display_count) {
return kSuccess; }));
603 UpdateAccessibilityFeatures,
609 size_t locales_count) {
return kSuccess; }));
615 bool run_called =
false;
623 bool has_disable_impeller_switch =
false;
624 for (
int i = 0;
i <
args->command_line_argc; ++
i) {
625 if (strcmp(
args->command_line_argv[
i],
"--enable-impeller=false") ==
627 has_disable_impeller_switch = true;
630 EXPECT_TRUE(has_disable_impeller_switch);
636 EXPECT_TRUE(run_called);
643 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
647 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
652 SendPlatformMessage, ([&called, test_message](
auto engine,
auto message) {
654 EXPECT_STREQ(
message->channel,
"test");
655 EXPECT_EQ(
message->message_size, test_message.size());
656 EXPECT_EQ(memcmp(
message->message, test_message.data(),
659 EXPECT_EQ(
message->response_handle,
nullptr);
663 engine->SendPlatformMessage(
channel, test_message.data(), test_message.size(),
672 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
676 auto binary_messenger =
677 std::make_unique<BinaryMessengerImpl>(
engine->messenger());
680 bool did_call_callback =
false;
681 bool did_call_reply =
false;
682 bool did_call_dart_reply =
false;
684 binary_messenger->SetMessageHandler(
686 [&did_call_callback, &did_call_dart_reply](
688 if (message_size == 5) {
689 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
690 char response[] = {
'b',
'y',
'e'};
691 reply(
reinterpret_cast<uint8_t*
>(response), 3);
692 did_call_callback =
true;
694 EXPECT_EQ(message_size, 3);
695 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
696 did_call_dart_reply =
true;
699 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
700 binary_messenger->Send(
701 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
702 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
703 EXPECT_EQ(reply_size, 5);
704 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
705 did_call_reply =
true;
708 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
709 engine->task_runner()->ProcessTasks();
717 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
722 auto binary_messenger =
723 std::make_unique<BinaryMessengerImpl>(
engine->messenger());
726 bool did_call_callback =
false;
727 bool did_call_reply =
false;
728 bool did_call_dart_reply =
false;
730 std::unique_ptr<std::thread> reply_thread;
731 binary_messenger->SetMessageHandler(
733 [&did_call_callback, &did_call_dart_reply, &reply_thread](
735 if (message_size == 5) {
736 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
737 reply_thread.reset(
new std::thread([reply = std::move(reply)]() {
738 char response[] = {
'b',
'y',
'e'};
739 reply(
reinterpret_cast<uint8_t*
>(response), 3);
741 did_call_callback =
true;
743 EXPECT_EQ(message_size, 3);
744 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
745 did_call_dart_reply =
true;
748 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
749 binary_messenger->Send(
750 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
751 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
752 EXPECT_EQ(reply_size, 5);
753 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
754 did_call_reply =
true;
757 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
758 engine->task_runner()->ProcessTasks();
760 ASSERT_TRUE(reply_thread);
761 reply_thread->join();
766 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
770 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
771 auto* dummy_response_handle =
774 void* reply_user_data =
reinterpret_cast<void*
>(6);
778 bool create_response_handle_called =
false;
781 PlatformMessageCreateResponseHandle,
782 ([&create_response_handle_called, &reply_handler, reply_user_data,
784 auto response_handle) {
785 create_response_handle_called =
true;
786 EXPECT_EQ(reply, reply_handler);
788 EXPECT_NE(response_handle,
nullptr);
789 *response_handle = dummy_response_handle;
792 bool release_response_handle_called =
false;
795 PlatformMessageReleaseResponseHandle,
796 ([&release_response_handle_called, dummy_response_handle](
797 auto engine,
auto response_handle) {
798 release_response_handle_called =
true;
799 EXPECT_EQ(response_handle, dummy_response_handle);
802 bool send_message_called =
false;
804 SendPlatformMessage, ([&send_message_called, test_message,
806 send_message_called =
true;
807 EXPECT_STREQ(
message->channel,
"test");
808 EXPECT_EQ(
message->message_size, test_message.size());
809 EXPECT_EQ(memcmp(
message->message, test_message.data(),
812 EXPECT_EQ(
message->response_handle, dummy_response_handle);
816 engine->SendPlatformMessage(
channel, test_message.data(), test_message.size(),
817 reply_handler, reply_user_data);
818 EXPECT_TRUE(create_response_handle_called);
819 EXPECT_TRUE(release_response_handle_called);
820 EXPECT_TRUE(send_message_called);
825 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
831 SendSemanticsAction, ([&called, &
message](
auto engine,
auto info) {
833 EXPECT_EQ(info->view_id, 456);
834 EXPECT_EQ(info->node_id, 42);
836 EXPECT_EQ(memcmp(info->data,
message.c_str(),
message.size()), 0);
837 EXPECT_EQ(info->data_length,
message.size());
849 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
850 THREAD_PRIORITY_BELOW_NORMAL);
853 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
854 THREAD_PRIORITY_ABOVE_NORMAL);
857 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
858 THREAD_PRIORITY_ABOVE_NORMAL);
862 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
865 EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
870 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
874 std::make_shared<MockKeyResponseController>());
881 engine->AddPluginRegistrarDestructionCallback(
883 auto result =
reinterpret_cast<int*
>(ref);
887 engine->AddPluginRegistrarDestructionCallback(
889 auto result =
reinterpret_cast<int*
>(ref);
895 EXPECT_EQ(result1, 1);
896 EXPECT_EQ(result2, 2);
901 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
917 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
927 engine->SetNextFrameCallback([]() {});
933 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
934 EXPECT_EQ(
engine->GetExecutableName(),
"flutter_windows_unittests.exe");
940 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
941 EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
942 .WillOnce(Return(
true))
943 .WillOnce(Return(
false));
947 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
950 std::optional<FlutterAccessibilityFeature> engine_flags;
952 UpdateAccessibilityFeatures, ([&engine_flags](
auto engine,
auto flags) {
953 engine_flags = flags;
961 engine->UpdateHighContrastMode();
963 EXPECT_TRUE(
engine->high_contrast_enabled());
964 EXPECT_TRUE(engine_flags.has_value());
966 engine_flags.value() &
970 engine_flags.reset();
971 engine->UpdateHighContrastMode();
973 EXPECT_FALSE(
engine->high_contrast_enabled());
974 EXPECT_TRUE(engine_flags.has_value());
976 engine_flags.value() &
982 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
992 engine->PostRasterThreadTask([&called]() { called =
true; });
1000 std::unique_ptr<WindowBindingHandler> wbh)
1009 NotifyWinEventWrapper,
1028 context.AddNativeFunction(
"Signal", native_entry);
1031 ASSERT_NE(
engine,
nullptr);
1036 auto window_binding_handler =
1037 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1038 EXPECT_CALL(*window_binding_handler, GetAlertDelegate)
1039 .WillOnce(Return(&delegate));
1042 MockFlutterWindowsView
view{windows_engine,
1043 std::move(window_binding_handler)};
1047 windows_engine->UpdateSemanticsEnabled(
true);
1049 EXPECT_CALL(
view, NotifyWinEventWrapper).Times(1);
1053 windows_engine->task_runner()->ProcessTasks();
1066 context.AddNativeFunction(
"Signal", native_entry);
1069 ASSERT_NE(
engine,
nullptr);
1076 windows_engine->task_runner()->ProcessTasks();
1092 context.AddNativeFunction(
"Signal", native_entry);
1095 ASSERT_NE(controller,
nullptr);
1103 windows_engine->task_runner()->ProcessTasks();
1109 EXPECT_EQ(log_capture.
str().find(
"tooltip"), std::string::npos);
1121 (std::optional<HWND>, std::optional<WPARAM>, std::optional<LPARAM>,
UINT),
1140 bool finished =
false;
1142 auto engine = builder.Build();
1143 auto window_binding_handler =
1144 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1145 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1150 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1152 .WillOnce([&finished](std::optional<HWND> hwnd,
1153 std::optional<WPARAM> wparam,
1154 std::optional<LPARAM> lparam,
1155 UINT exit_code) { finished = exit_code == 0; });
1156 EXPECT_CALL(*
handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
1159 engine->lifecycle_manager()->BeginProcessingExit();
1163 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1169 engine->task_runner()->ProcessTasks();
1176 bool did_call =
false;
1178 auto engine = builder.Build();
1179 auto window_binding_handler =
1180 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1181 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1186 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1187 EXPECT_CALL(*
handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
1188 EXPECT_CALL(*
handler, Quit).Times(0);
1190 engine->lifecycle_manager()->BeginProcessingExit();
1192 auto binary_messenger =
1193 std::make_unique<BinaryMessengerImpl>(
engine->messenger());
1194 binary_messenger->SetMessageHandler(
1195 "flutter/platform", [&did_call](
const uint8_t*
message,
1198 EXPECT_NE(contents.find(
"\"method\":\"System.exitApplication\""),
1200 EXPECT_NE(contents.find(
"\"type\":\"required\""), std::string::npos);
1201 EXPECT_NE(contents.find(
"\"exitCode\":0"), std::string::npos);
1203 char response[] =
"";
1204 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1209 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1213 engine->task_runner()->ProcessTasks();
1223 bool second_close =
false;
1225 auto engine = builder.Build();
1226 auto window_binding_handler =
1227 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1228 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1233 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1234 EXPECT_CALL(*
handler, IsLastWindowOfProcess).WillOnce(Return(
true));
1236 .WillOnce([handler_ptr =
handler.get()](
1237 std::optional<HWND> hwnd, std::optional<WPARAM> wparam,
1238 std::optional<LPARAM> lparam,
UINT exit_code) {
1239 handler_ptr->WindowsLifecycleManager::Quit(hwnd, wparam, lparam,
1245 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1246 hwnd, msg, wparam, lparam);
1249 engine->lifecycle_manager()->BeginProcessingExit();
1257 engine->window_proc_delegate_manager()->RegisterTopLevelWindowProcDelegate(
1262 bool* called =
reinterpret_cast<bool*
>(
user_data);
1269 reinterpret_cast<void*
>(&second_close));
1271 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1274 while (!second_close) {
1275 engine->task_runner()->ProcessTasks();
1282 bool finished =
false;
1284 auto engine = builder.Build();
1285 auto window_binding_handler =
1286 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1287 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1292 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1293 EXPECT_CALL(*
handler, IsLastWindowOfProcess).WillOnce([&finished]() {
1298 EXPECT_CALL(*
handler, Quit).Times(0);
1300 engine->lifecycle_manager()->BeginProcessingExit();
1304 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1308 engine->task_runner()->ProcessTasks();
1315 auto engine = builder.Build();
1316 auto window_binding_handler =
1317 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1318 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1323 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1324 EXPECT_CALL(*
handler, IsLastWindowOfProcess).Times(0);
1327 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1334 auto engine = builder.Build();
1335 auto window_binding_handler =
1336 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1337 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1342 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1343 EXPECT_CALL(*
handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1345 engine->lifecycle_manager()->BeginProcessingExit();
1347 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1354 auto engine = builder.Build();
1355 auto window_binding_handler =
1356 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1357 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1362 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1363 EXPECT_CALL(*
handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1365 engine->lifecycle_manager()->BeginProcessingExit();
1367 engine->lifecycle_manager()->ExternalWindowMessage(0, WM_CLOSE, 0, 0);
1373 auto engine = builder.Build();
1374 auto window_binding_handler =
1375 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1376 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1383 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1384 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1386 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1390 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1393 engine->lifecycle_manager()->OnWindowStateEvent((HWND)1,
1396 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1400 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1403 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1404 (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0);
1406 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1410 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1413 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1414 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1416 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1420 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1427 auto engine = builder.Build();
1428 auto window_binding_handler =
1429 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1430 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1439 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1441 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1444 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1448 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1454 HWND outer =
reinterpret_cast<HWND
>(1);
1455 HWND inner =
reinterpret_cast<HWND
>(2);
1457 auto engine = builder.Build();
1458 auto window_binding_handler =
1459 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1460 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1461 ON_CALL(
view, GetWindowHandle).WillByDefault([=]() {
return inner; });
1470 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1471 outer, WM_SHOWWINDOW,
TRUE, NULL);
1475 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1479 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1485 while (
engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1490 EXPECT_EQ(
engine->lifecycle_manager()->GetLifecycleState(),
1497 bool finished =
false;
1499 auto engine = builder.Build();
1500 auto window_binding_handler =
1501 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1502 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1507 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1508 EXPECT_CALL(*
handler, SetLifecycleState)
1510 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1514 auto binary_messenger =
1515 std::make_unique<BinaryMessengerImpl>(
engine->messenger());
1517 binary_messenger->SetMessageHandler(
1518 "flutter/unittest", [&finished](
const uint8_t*
message,
1521 EXPECT_NE(contents.find(
"AppLifecycleState.inactive"),
1524 char response[] =
"";
1525 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1531 HWND hwnd =
reinterpret_cast<HWND
>(1);
1534 EXPECT_FALSE(finished);
1538 engine->lifecycle_manager()->BeginProcessingLifecycle();
1542 engine->task_runner()->ProcessTasks();
1549 bool enabled_lifecycle =
false;
1550 bool dart_responded =
false;
1552 auto engine = builder.Build();
1553 auto window_binding_handler =
1554 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1555 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1560 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1561 EXPECT_CALL(*
handler, SetLifecycleState)
1563 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1565 handler->begin_processing_callback = [&]() { enabled_lifecycle =
true; };
1568 auto binary_messenger =
1569 std::make_unique<BinaryMessengerImpl>(
engine->messenger());
1570 binary_messenger->SetMessageHandler(
1574 EXPECT_NE(contents.find(
"AppLifecycleState."), std::string::npos);
1575 dart_responded =
true;
1576 char response[] =
"";
1577 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1582 while (!enabled_lifecycle) {
1583 engine->task_runner()->ProcessTasks();
1586 HWND hwnd =
reinterpret_cast<HWND
>(1);
1590 while (!dart_responded) {
1591 engine->task_runner()->ProcessTasks();
1599 auto engine = builder.Build();
1600 auto window_binding_handler =
1601 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1602 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1608 bool lifecycle_began =
false;
1609 auto handler = std::make_unique<MockWindowsLifecycleManager>(
engine.get());
1610 handler->begin_processing_callback = [&]() { lifecycle_began =
true; };
1615 while (!lifecycle_began) {
1616 engine->task_runner()->ProcessTasks();
1623 auto engine = builder.Build();
1626 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1628 bool received_call =
false;
1630 auto manager = std::make_unique<MockPlatformViewManager>(
engine.get());
1631 EXPECT_CALL(*
manager, AddPlatformView)
1633 received_call =
true;
1636 modifier.SetPlatformViewPlugin(std::move(
manager));
1640 while (!received_call) {
1641 engine->task_runner()->ProcessTasks();
1647 auto engine = builder.Build();
1651 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1657 ASSERT_TRUE(
engine->Run());
1661 auto implicit_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1663 std::unique_ptr<FlutterWindowsView> implicit_view =
1664 engine->CreateView(std::move(implicit_window),
1667 EXPECT_TRUE(implicit_view);
1670 auto second_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1673 engine->CreateView(std::move(second_window),
1675 "FlutterEngineAddView returned an unexpected result");
1681 auto engine = builder.Build();
1685 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1691 ASSERT_TRUE(
engine->Run());
1692 EXPECT_DEBUG_DEATH(
engine->RemoveView(123),
1693 "FlutterEngineRemoveView returned an unexpected result");
1702 std::optional<std::thread::id> ui_thread_id;
1705 ui_thread_id = std::this_thread::get_id();
1707 context.AddNativeFunction(
"Signal", native_entry);
1710 while (!ui_thread_id) {
1713 ASSERT_EQ(*ui_thread_id, std::this_thread::get_id());
1718 std::unique_ptr<FlutterWindowsEngine>
engine = builder.Build();
1719 auto window_binding_handler =
1720 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1721 MockFlutterWindowsView
view(
engine.get(), std::move(window_binding_handler));
1729 EXPECT_CALL(
view, Focus()).WillOnce(Return(
true));
1742 context.AddNativeFunction(
"Signal", native_entry);
1746 ASSERT_NE(
engine,
nullptr);
1748 auto window_binding_handler1 =
1749 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1750 auto window_binding_handler2 =
1751 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1756 EXPECT_CALL(*window_binding_handler1, GetPhysicalWindowBounds)
1758 EXPECT_CALL(*window_binding_handler1, GetDpiScale)
1759 .WillRepeatedly(testing::Return(96.0));
1760 EXPECT_CALL(*window_binding_handler2, GetPhysicalWindowBounds)
1762 EXPECT_CALL(*window_binding_handler2, GetDpiScale)
1763 .WillRepeatedly(testing::Return(96.0));
1772 auto view1 = windows_engine->CreateView(std::move(window_binding_handler1),
1775 auto view2 = windows_engine->CreateView(std::move(window_binding_handler2),
1781 windows_engine->UpdateSemanticsEnabled(
true);
1784 windows_engine->task_runner()->ProcessTasks();
1787 auto accessibility_bridge1 = view1->accessibility_bridge().lock();
1788 auto accessibility_bridge2 = view2->accessibility_bridge().lock();
1793 !accessibility_bridge1->GetPlatformNodeFromTree(view1->view_id() + 1)) {
1794 windows_engine->task_runner()->ProcessTasks();
1798 !accessibility_bridge2->GetPlatformNodeFromTree(view2->view_id() + 1)) {
1799 windows_engine->task_runner()->ProcessTasks();
1803 auto tree1 = accessibility_bridge1->GetTree();
1804 auto tree2 = accessibility_bridge2->GetTree();
1805 EXPECT_NE(tree1->GetFromId(view1->view_id() + 1),
nullptr);
1806 EXPECT_NE(tree2->GetFromId(view2->view_id() + 1),
nullptr);
void SetLifecycleManager(std::unique_ptr< WindowsLifecycleManager > &&handler)
void SetFrameInterval(uint64_t frame_interval_nanos)
void OnViewFocusChangeRequest(const FlutterViewFocusChangeRequest *request)
void SetEGLManager(std::unique_ptr< egl::Manager > egl_manager)
void SetStartTime(uint64_t start_time_nanos)
Reset the start_time field that is used to align vsync events.
FlutterEngineProcTable & embedder_api()
void SetImplicitView(FlutterWindowsView *view)
void UpdateSemanticsEnabled(bool enabled)
virtual void Quit(std::optional< HWND > window, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
virtual void BeginProcessingLifecycle()
virtual bool IsLastWindowOfProcess()
virtual void SetLifecycleState(AppLifecycleState state)
void SetDartEntrypoint(std::string entrypoint)
void AddDartEntrypointArgument(std::string arg)
void SetSwitches(std::vector< std::string > switches)
void SetImpellerSwitch(FlutterDesktopImpellerSwitch impeller_switch)
void SetWindowsProcTable(std::shared_ptr< WindowsProcTable > windows_proc_table)
~MockFlutterWindowsView()
MOCK_METHOD(bool, Focus,(),(override))
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
MOCK_METHOD(HWND, GetWindowHandle,(),(const, override))
virtual ~MockWindowsLifecycleManager()
std::function< void()> begin_processing_callback
MOCK_METHOD(void, DispatchMessage,(HWND, UINT, WPARAM, LPARAM),(override))
MOCK_METHOD(void, Quit,(std::optional< HWND >, std::optional< WPARAM >, std::optional< LPARAM >, UINT),(override))
MOCK_METHOD(void, SetLifecycleState,(AppLifecycleState),(override))
void BeginProcessingLifecycle() override
MOCK_METHOD(bool, IsLastWindowOfProcess,(),(override))
MockWindowsLifecycleManager(FlutterWindowsEngine *engine)
void SetDartEntrypoint(std::string_view entrypoint)
static MallocMapping Copy(const T *begin, const T *end)
static constexpr TimeDelta FromMilliseconds(int64_t millis)
constexpr int64_t ToNanoseconds() const
constexpr TimeDelta ToEpochDelta() const
#define FLUTTER_API_SYMBOL(symbol)
FlutterAccessibilityFeature
@ kFlutterAccessibilityFeatureHighContrast
Request that UI be rendered with darker colors.
FlutterEngineDisplaysUpdateType
@ kFlutterEngineDisplaysUpdateTypeStartup
@ kBackground
Suitable for threads that shouldn't disrupt high priority work.
@ kDisplay
Suitable for threads which generate data for the display.
@ kNormal
Default priority level.
@ kRaster
Suitable for thread which raster data.
@ kFlutterSemanticsActionDismiss
A request that the node should be dismissed.
#define FLUTTER_ENGINE_VERSION
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const gchar FlBinaryMessengerMessageHandler handler
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
FlutterDesktopBinaryReply callback
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
TEST_F(DisplayListTest, Defaults)
std::unique_ptr< FlutterDesktopEngine, EngineDeleter > EnginePtr
std::unique_ptr< FlutterDesktopViewController, ViewControllerDeleter > ViewControllerPtr
void MockEmbedderApiForKeyboard(EngineModifier &modifier, std::shared_ptr< MockKeyResponseController > response_controller)
constexpr int64_t kImplicitViewId
UINT GetDpiForMonitor(HMONITOR monitor)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
static void DispatchSemanticsAction(JNIEnv *env, jobject jcaller, jlong shell_holder, jint id, jint action, jobject args, jint args_position)
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
static void WindowsPlatformThreadPrioritySetter(FlutterThreadPriority priority)
static void ScheduleFrame(JNIEnv *env, jobject jcaller, jlong shell_holder)
#define MOCK_ENGINE_PROC(proc, mock_impl)
std::shared_ptr< ContextGLES > context
FlutterEngineScheduleFrameFnPtr ScheduleFrame
FlutterEnginePlatformMessageReleaseResponseHandleFnPtr PlatformMessageReleaseResponseHandle
FlutterEngineUpdateLocalesFnPtr UpdateLocales
FlutterEngineRunsAOTCompiledDartCodeFnPtr RunsAOTCompiledDartCode
FlutterEngineSetNextFrameCallbackFnPtr SetNextFrameCallback
FlutterEngineShutdownFnPtr Shutdown
FlutterEngineOnVsyncFnPtr OnVsync
FlutterEngineGetCurrentTimeFnPtr GetCurrentTime
FlutterEngineNotifyDisplayUpdateFnPtr NotifyDisplayUpdate
FlutterEngineSendPlatformMessageFnPtr SendPlatformMessage
FlutterEnginePlatformMessageCreateResponseHandleFnPtr PlatformMessageCreateResponseHandle
FlutterEngineRunFnPtr Run
FlutterEngineUpdateAccessibilityFeaturesFnPtr UpdateAccessibilityFeatures
FlutterEnginePostRenderThreadTaskFnPtr PostRenderThreadTask
FlutterEngineSendSemanticsActionFnPtr SendSemanticsAction
FlutterViewId view_id
The identifier of the view that received the focus event.
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef controller)
#define CREATE_NATIVE_ENTRY(native_entry)