8 #include "flutter/fml/logging.h"
9 #include "flutter/fml/macros.h"
10 #include "flutter/shell/platform/embedder/embedder.h"
11 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
14 #include "flutter/shell/platform/windows/testing/egl/mock_manager.h"
15 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
16 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
17 #include "flutter/shell/platform/windows/testing/mock_platform_view_manager.h"
18 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
19 #include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
20 #include "flutter/shell/platform/windows/testing/test_keyboard.h"
21 #include "flutter/shell/platform/windows/testing/windows_test.h"
22 #include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
23 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h"
24 #include "fml/synchronization/waitable_event.h"
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
36 if (::GetMessage(&msg,
nullptr, 0, 0)) {
37 ::TranslateMessage(&msg);
38 ::DispatchMessage(&msg);
47 using ::testing::DoAll;
48 using ::testing::NiceMock;
49 using ::testing::Return;
50 using ::testing::SetArgPointee;
56 FlutterWindowsEngineBuilder builder{GetContext()};
57 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
59 EngineModifier modifier(engine.get());
60 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
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
>(
72 fml::TimePoint::Now().ToEpochDelta().ToNanoseconds());
74 [&](
const FlutterTask*) { finished =
true; });
75 runner->PostFlutterTask(
77 static_cast<uint64_t
>((fml::TimePoint::Now().ToEpochDelta() +
78 fml::TimeDelta::FromMilliseconds(50))
80 auto start = fml::TimePoint::Now();
84 auto duration = fml::TimePoint::Now() - start;
85 EXPECT_GE(duration, fml::TimeDelta::FromMilliseconds(50));
90 auto runner = std::make_unique<TaskRunner>(
92 return static_cast<uint64_t
>(
93 fml::TimePoint::Now().ToEpochDelta().ToNanoseconds());
95 [&](
const FlutterTask*) {});
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);
124 if (::GetMessage(&msg,
nullptr, 0, 0)) {
125 if (msg.message == WM_PAINT) {
128 ::TranslateMessage(&msg);
129 ::DispatchMessage(&msg);
133 DestroyWindow(window);
134 UnregisterClassW(class_name,
nullptr);
138 FlutterWindowsEngineBuilder builder{GetContext()};
139 builder.AddDartEntrypointArgument(
"arg1");
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();
194 EngineModifier modifier(engine.get());
197 bool run_called =
false;
198 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
199 Run, ([&run_called, engine_instance = engine.get()](
200 size_t version,
const FlutterRendererConfig* config,
201 const FlutterProjectArgs* args,
void*
user_data,
204 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
206 EXPECT_EQ(version, FLUTTER_ENGINE_VERSION);
207 EXPECT_NE(config,
nullptr);
209 EXPECT_EQ(config->type, kOpenGL);
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(
229 FlutterThreadPriority::kRaster);
230 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
231 THREAD_PRIORITY_ABOVE_NORMAL);
235 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
236 UpdateAccessibilityFeatures,
238 FlutterAccessibilityFeature flags) {
return kSuccess; });
241 bool update_locales_called =
false;
242 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
244 ([&update_locales_called](
auto engine,
const FlutterLocale** locales,
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;
256 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
258 ([&settings_message_sent](
auto engine,
auto message) {
259 if (std::string(
message->channel) == std::string(
"flutter/settings")) {
260 settings_message_sent = true;
267 bool notify_display_update_called =
false;
269 modifier.embedder_api().NotifyDisplayUpdate = MOCK_ENGINE_PROC(
271 ([¬ify_display_update_called](
273 const FlutterEngineDisplaysUpdateType update_type,
274 const FlutterEngineDisplay* embedder_displays,
275 size_t display_count) {
276 EXPECT_EQ(update_type, kFlutterEngineDisplaysUpdateTypeStartup);
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);
293 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
294 modifier.ReleaseEGLManager();
298 FlutterWindowsEngineBuilder builder{GetContext()};
299 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
300 EngineModifier modifier(engine.get());
301 bool on_vsync_called =
false;
303 modifier.embedder_api().GetCurrentTime =
304 MOCK_ENGINE_PROC(GetCurrentTime, ([]() -> uint64_t {
return 1; }));
305 modifier.embedder_api().OnVsync = MOCK_ENGINE_PROC(
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;
316 modifier.SetStartTime(0);
317 modifier.SetFrameInterval(16600000);
321 EXPECT_TRUE(on_vsync_called);
325 FlutterWindowsEngineBuilder builder{GetContext()};
327 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
328 EngineModifier modifier(engine.get());
330 modifier.embedder_api().NotifyDisplayUpdate =
331 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
332 ([engine_instance = engine.get()](
334 const FlutterEngineDisplaysUpdateType update_type,
335 const FlutterEngineDisplay* embedder_displays,
336 size_t display_count) {
return kSuccess; }));
339 bool run_called =
false;
340 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
341 Run, ([&run_called, engine_instance = engine.get()](
342 size_t version,
const FlutterRendererConfig* config,
343 const FlutterProjectArgs* args,
void*
user_data,
346 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
348 EXPECT_EQ(config->type, kSoftware);
352 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
353 UpdateAccessibilityFeatures,
355 FlutterAccessibilityFeature flags) {
return kSuccess; });
359 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
360 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
361 size_t locales_count) {
return kSuccess; }));
362 modifier.embedder_api().SendPlatformMessage =
363 MOCK_ENGINE_PROC(SendPlatformMessage,
364 ([](
auto engine,
auto message) {
return kSuccess; }));
367 modifier.SetEGLManager(
nullptr);
371 EXPECT_TRUE(run_called);
375 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
379 FlutterWindowsEngineBuilder builder{GetContext()};
380 builder.SetSwitches({
"--enable-impeller=true"});
381 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
382 EngineModifier modifier(engine.get());
384 modifier.embedder_api().NotifyDisplayUpdate =
385 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
386 ([engine_instance = engine.get()](
388 const FlutterEngineDisplaysUpdateType update_type,
389 const FlutterEngineDisplay* embedder_displays,
390 size_t display_count) {
return kSuccess; }));
393 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
394 UpdateAccessibilityFeatures,
396 FlutterAccessibilityFeature flags) {
return kSuccess; });
400 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
401 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
402 size_t locales_count) {
return kSuccess; }));
403 modifier.embedder_api().SendPlatformMessage =
404 MOCK_ENGINE_PROC(SendPlatformMessage,
405 ([](
auto engine,
auto message) {
return kSuccess; }));
408 modifier.SetEGLManager(
nullptr);
410 EXPECT_FALSE(engine->Run());
414 FlutterWindowsEngineBuilder builder{GetContext()};
416 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
417 EngineModifier modifier(engine.get());
419 modifier.embedder_api().NotifyDisplayUpdate =
420 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
421 ([engine_instance = engine.get()](
423 const FlutterEngineDisplaysUpdateType update_type,
424 const FlutterEngineDisplay* embedder_displays,
425 size_t display_count) {
return kSuccess; }));
427 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
428 UpdateAccessibilityFeatures,
430 FlutterAccessibilityFeature flags) {
return kSuccess; });
432 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
433 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
434 size_t locales_count) {
return kSuccess; }));
436 modifier.embedder_api().SendPlatformMessage =
437 MOCK_ENGINE_PROC(SendPlatformMessage,
438 ([](
auto engine,
auto message) {
return kSuccess; }));
440 bool run_called =
false;
441 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
442 Run, ([&run_called, engine_instance = engine.get()](
443 size_t version,
const FlutterRendererConfig* config,
444 const FlutterProjectArgs* args,
void*
user_data,
447 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
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);
472 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
473 modifier.ReleaseEGLManager();
477 FlutterWindowsEngineBuilder builder{GetContext()};
479 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
480 EngineModifier modifier(engine.get());
482 modifier.embedder_api().NotifyDisplayUpdate =
483 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
485 const FlutterEngineDisplaysUpdateType update_type,
486 const FlutterEngineDisplay* embedder_displays,
487 size_t display_count) {
return kSuccess; }));
489 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
490 UpdateAccessibilityFeatures,
492 FlutterAccessibilityFeature flags) {
return kSuccess; });
494 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
495 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
496 size_t locales_count) {
return kSuccess; }));
498 modifier.embedder_api().SendPlatformMessage =
499 MOCK_ENGINE_PROC(SendPlatformMessage,
500 ([](
auto engine,
auto message) {
return kSuccess; }));
502 bool run_called =
false;
503 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
504 Run, ([&run_called](
size_t version,
const FlutterRendererConfig* config,
505 const FlutterProjectArgs* args,
void*
user_data,
508 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
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);
533 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
534 modifier.ReleaseEGLManager();
538 FlutterWindowsEngineBuilder builder{GetContext()};
539 builder.SetEnableFlutterGpu(
true);
540 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
541 EngineModifier modifier(engine.get());
543 modifier.embedder_api().NotifyDisplayUpdate =
544 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
546 const FlutterEngineDisplaysUpdateType update_type,
547 const FlutterEngineDisplay* embedder_displays,
548 size_t display_count) {
return kSuccess; }));
550 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
551 UpdateAccessibilityFeatures,
553 FlutterAccessibilityFeature flags) {
return kSuccess; });
555 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
556 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
557 size_t locales_count) {
return kSuccess; }));
559 modifier.embedder_api().SendPlatformMessage =
560 MOCK_ENGINE_PROC(SendPlatformMessage,
561 ([](
auto engine,
auto message) {
return kSuccess; }));
563 bool run_called =
false;
564 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
565 Run, ([&run_called](
size_t version,
const FlutterRendererConfig* config,
566 const FlutterProjectArgs* args,
void*
user_data,
569 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
571 bool has_flutter_gpu_switch =
false;
572 for (
int i = 0; i < args->command_line_argc; ++i) {
573 if (strcmp(args->command_line_argv[i],
"--enable-flutter-gpu") == 0) {
574 has_flutter_gpu_switch = true;
577 EXPECT_TRUE(has_flutter_gpu_switch);
582 modifier.SetEGLManager(std::make_unique<egl::MockManager>());
586 EXPECT_TRUE(run_called);
588 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
589 modifier.ReleaseEGLManager();
593 FlutterWindowsEngineBuilder builder{GetContext()};
594 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
595 EngineModifier modifier(engine.get());
597 modifier.embedder_api().NotifyDisplayUpdate =
598 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
600 const FlutterEngineDisplaysUpdateType update_type,
601 const FlutterEngineDisplay* embedder_displays,
602 size_t display_count) {
return kSuccess; }));
604 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
605 UpdateAccessibilityFeatures,
607 FlutterAccessibilityFeature flags) {
return kSuccess; });
609 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
610 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
611 size_t locales_count) {
return kSuccess; }));
613 modifier.embedder_api().SendPlatformMessage =
614 MOCK_ENGINE_PROC(SendPlatformMessage,
615 ([](
auto engine,
auto message) {
return kSuccess; }));
617 bool run_called =
false;
618 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
619 Run, ([&run_called](
size_t version,
const FlutterRendererConfig* config,
620 const FlutterProjectArgs* args,
void*
user_data,
623 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
625 bool has_flutter_gpu_switch =
false;
626 for (
int i = 0; i < args->command_line_argc; ++i) {
627 if (strcmp(args->command_line_argv[i],
"--enable-flutter-gpu") == 0) {
628 has_flutter_gpu_switch = true;
631 EXPECT_FALSE(has_flutter_gpu_switch);
636 modifier.SetEGLManager(std::make_unique<egl::MockManager>());
640 EXPECT_TRUE(run_called);
642 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
643 modifier.ReleaseEGLManager();
647 FlutterWindowsEngineBuilder builder{GetContext()};
649 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
650 EngineModifier modifier(engine.get());
652 modifier.embedder_api().NotifyDisplayUpdate =
653 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
655 const FlutterEngineDisplaysUpdateType update_type,
656 const FlutterEngineDisplay* embedder_displays,
657 size_t display_count) {
return kSuccess; }));
659 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
660 UpdateAccessibilityFeatures,
662 FlutterAccessibilityFeature flags) {
return kSuccess; });
664 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
665 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
666 size_t locales_count) {
return kSuccess; }));
668 modifier.embedder_api().SendPlatformMessage =
669 MOCK_ENGINE_PROC(SendPlatformMessage,
670 ([](
auto engine,
auto message) {
return kSuccess; }));
672 bool run_called =
false;
673 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
674 Run, ([&run_called](
size_t version,
const FlutterRendererConfig* config,
675 const FlutterProjectArgs* args,
void*
user_data,
678 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
680 bool has_disable_impeller_switch =
false;
681 for (
int i = 0; i < args->command_line_argc; ++i) {
682 if (strcmp(args->command_line_argv[i],
"--enable-impeller=false") ==
684 has_disable_impeller_switch = true;
687 EXPECT_TRUE(has_disable_impeller_switch);
693 EXPECT_TRUE(run_called);
695 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
699 FlutterWindowsEngineBuilder builder{GetContext()};
700 builder.SetSwitches({
"--enable-impeller=false"});
701 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
702 EngineModifier modifier(engine.get());
704 modifier.embedder_api().NotifyDisplayUpdate =
705 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
707 const FlutterEngineDisplaysUpdateType update_type,
708 const FlutterEngineDisplay* embedder_displays,
709 size_t display_count) {
return kSuccess; }));
711 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
712 UpdateAccessibilityFeatures,
714 FlutterAccessibilityFeature flags) {
return kSuccess; });
716 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
717 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
718 size_t locales_count) {
return kSuccess; }));
720 modifier.embedder_api().SendPlatformMessage =
721 MOCK_ENGINE_PROC(SendPlatformMessage,
722 ([](
auto engine,
auto message) {
return kSuccess; }));
724 bool run_called =
false;
725 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
726 Run, ([&run_called](
size_t version,
const FlutterRendererConfig* config,
727 const FlutterProjectArgs* args,
void*
user_data,
730 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
732 bool has_disable_impeller_switch =
false;
733 for (
int i = 0; i < args->command_line_argc; ++i) {
734 if (strcmp(args->command_line_argv[i],
"--enable-impeller=false") ==
736 has_disable_impeller_switch = true;
739 EXPECT_TRUE(has_disable_impeller_switch);
745 EXPECT_TRUE(run_called);
747 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
751 FlutterWindowsEngineBuilder builder{GetContext()};
752 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
753 EngineModifier modifier(engine.get());
755 const char* channel =
"test";
756 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
760 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
761 SendPlatformMessage, ([&called, test_message](
auto engine,
auto message) {
763 EXPECT_STREQ(
message->channel,
"test");
764 EXPECT_EQ(
message->message_size, test_message.size());
765 EXPECT_EQ(memcmp(
message->message, test_message.data(),
768 EXPECT_EQ(
message->response_handle,
nullptr);
772 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
778 FlutterWindowsEngineBuilder builder{GetContext()};
779 builder.SetDartEntrypoint(
"hiPlatformChannels");
781 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
782 EngineModifier modifier(engine.get());
783 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
785 auto binary_messenger =
786 std::make_unique<BinaryMessengerImpl>(engine->messenger());
789 bool did_call_callback =
false;
790 bool did_call_reply =
false;
791 bool did_call_dart_reply =
false;
792 std::string channel =
"hi";
793 binary_messenger->SetMessageHandler(
795 [&did_call_callback, &did_call_dart_reply](
797 if (message_size == 5) {
798 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
799 char response[] = {
'b',
'y',
'e'};
800 reply(
reinterpret_cast<uint8_t*
>(response), 3);
801 did_call_callback =
true;
803 EXPECT_EQ(message_size, 3);
804 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
805 did_call_dart_reply =
true;
808 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
809 binary_messenger->Send(
810 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
811 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
812 EXPECT_EQ(reply_size, 5);
813 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
814 did_call_reply =
true;
817 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
818 engine->task_runner()->ProcessTasks();
823 FlutterWindowsEngineBuilder builder{GetContext()};
824 builder.SetDartEntrypoint(
"hiPlatformChannels");
826 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
828 EngineModifier modifier(engine.get());
829 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
831 auto binary_messenger =
832 std::make_unique<BinaryMessengerImpl>(engine->messenger());
835 bool did_call_callback =
false;
836 bool did_call_reply =
false;
837 bool did_call_dart_reply =
false;
838 std::string channel =
"hi";
839 std::unique_ptr<std::thread> reply_thread;
840 binary_messenger->SetMessageHandler(
842 [&did_call_callback, &did_call_dart_reply, &reply_thread](
844 if (message_size == 5) {
845 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
846 reply_thread.reset(
new std::thread([reply = std::move(reply)]() {
847 char response[] = {
'b',
'y',
'e'};
848 reply(
reinterpret_cast<uint8_t*
>(response), 3);
850 did_call_callback =
true;
852 EXPECT_EQ(message_size, 3);
853 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
854 did_call_dart_reply =
true;
857 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
858 binary_messenger->Send(
859 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
860 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
861 EXPECT_EQ(reply_size, 5);
862 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
863 did_call_reply =
true;
866 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
867 engine->task_runner()->ProcessTasks();
869 ASSERT_TRUE(reply_thread);
870 reply_thread->join();
874 FlutterWindowsEngineBuilder builder{GetContext()};
875 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
876 EngineModifier modifier(engine.get());
878 const char* channel =
"test";
879 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
880 auto* dummy_response_handle =
881 reinterpret_cast<FlutterPlatformMessageResponseHandle*
>(5);
883 void* reply_user_data =
reinterpret_cast<void*
>(6);
887 bool create_response_handle_called =
false;
888 modifier.embedder_api().PlatformMessageCreateResponseHandle =
890 PlatformMessageCreateResponseHandle,
891 ([&create_response_handle_called, &reply_handler, reply_user_data,
892 dummy_response_handle](
auto engine,
auto reply,
auto user_data,
893 auto response_handle) {
894 create_response_handle_called =
true;
895 EXPECT_EQ(reply, reply_handler);
897 EXPECT_NE(response_handle,
nullptr);
898 *response_handle = dummy_response_handle;
901 bool release_response_handle_called =
false;
902 modifier.embedder_api().PlatformMessageReleaseResponseHandle =
904 PlatformMessageReleaseResponseHandle,
905 ([&release_response_handle_called, dummy_response_handle](
906 auto engine,
auto response_handle) {
907 release_response_handle_called =
true;
908 EXPECT_EQ(response_handle, dummy_response_handle);
911 bool send_message_called =
false;
912 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
913 SendPlatformMessage, ([&send_message_called, test_message,
914 dummy_response_handle](
auto engine,
auto message) {
915 send_message_called =
true;
916 EXPECT_STREQ(
message->channel,
"test");
917 EXPECT_EQ(
message->message_size, test_message.size());
918 EXPECT_EQ(memcmp(
message->message, test_message.data(),
921 EXPECT_EQ(
message->response_handle, dummy_response_handle);
925 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
926 reply_handler, reply_user_data);
927 EXPECT_TRUE(create_response_handle_called);
928 EXPECT_TRUE(release_response_handle_called);
929 EXPECT_TRUE(send_message_called);
933 FlutterWindowsEngineBuilder builder{GetContext()};
934 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
935 EngineModifier modifier(engine.get());
939 modifier.embedder_api().SendSemanticsAction = MOCK_ENGINE_PROC(
940 SendSemanticsAction, ([&called, &
message](
auto engine,
auto info) {
942 EXPECT_EQ(info->view_id, 456);
943 EXPECT_EQ(info->node_id, 42);
944 EXPECT_EQ(info->action, kFlutterSemanticsActionDismiss);
945 EXPECT_EQ(memcmp(info->data,
message.c_str(),
message.size()), 0);
946 EXPECT_EQ(info->data_length,
message.size());
950 auto data = fml::MallocMapping::Copy(
message.c_str(),
message.size());
951 engine->DispatchSemanticsAction(456, 42, kFlutterSemanticsActionDismiss,
958 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
959 THREAD_PRIORITY_BELOW_NORMAL);
962 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
963 THREAD_PRIORITY_ABOVE_NORMAL);
966 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
967 THREAD_PRIORITY_ABOVE_NORMAL);
971 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
974 EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
978 FlutterWindowsEngineBuilder builder{GetContext()};
979 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
980 EngineModifier modifier(engine.get());
982 MockEmbedderApiForKeyboard(modifier,
983 std::make_shared<MockKeyResponseController>());
990 engine->AddPluginRegistrarDestructionCallback(
992 auto result =
reinterpret_cast<int*
>(ref);
996 engine->AddPluginRegistrarDestructionCallback(
998 auto result =
reinterpret_cast<int*
>(ref);
1004 EXPECT_EQ(result1, 1);
1005 EXPECT_EQ(result2, 2);
1009 FlutterWindowsEngineBuilder builder{GetContext()};
1010 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1011 EngineModifier modifier(engine.get());
1013 bool called =
false;
1014 modifier.embedder_api().ScheduleFrame =
1015 MOCK_ENGINE_PROC(ScheduleFrame, ([&called](
auto engine) {
1020 engine->ScheduleFrame();
1021 EXPECT_TRUE(called);
1025 FlutterWindowsEngineBuilder builder{GetContext()};
1026 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1027 EngineModifier modifier(engine.get());
1029 bool called =
false;
1030 modifier.embedder_api().SetNextFrameCallback = MOCK_ENGINE_PROC(
1031 SetNextFrameCallback, ([&called](
auto engine,
auto callback,
auto data) {
1036 engine->SetNextFrameCallback([]() {});
1037 EXPECT_TRUE(called);
1041 FlutterWindowsEngineBuilder builder{GetContext()};
1042 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1043 EXPECT_EQ(engine->GetExecutableName(),
"flutter_windows_unittests.exe");
1049 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
1050 EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
1051 .WillOnce(Return(
true))
1052 .WillOnce(Return(
false));
1054 FlutterWindowsEngineBuilder builder{GetContext()};
1055 builder.SetWindowsProcTable(windows_proc_table);
1056 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1057 EngineModifier modifier(engine.get());
1059 std::optional<FlutterAccessibilityFeature> engine_flags;
1060 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
1061 UpdateAccessibilityFeatures, ([&engine_flags](
auto engine,
auto flags) {
1062 engine_flags = flags;
1065 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
1066 SendPlatformMessage,
1067 [](
auto engine,
const auto message) {
return kSuccess; });
1070 engine->UpdateHighContrastMode();
1072 EXPECT_TRUE(engine->high_contrast_enabled());
1073 EXPECT_TRUE(engine_flags.has_value());
1075 engine_flags.value() &
1076 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
1079 engine_flags.reset();
1080 engine->UpdateHighContrastMode();
1082 EXPECT_FALSE(engine->high_contrast_enabled());
1083 EXPECT_TRUE(engine_flags.has_value());
1085 engine_flags.value() &
1086 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
1090 FlutterWindowsEngineBuilder builder{GetContext()};
1091 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1092 EngineModifier modifier(engine.get());
1094 modifier.embedder_api().PostRenderThreadTask = MOCK_ENGINE_PROC(
1095 PostRenderThreadTask, ([](
auto engine,
auto callback,
auto context) {
1100 bool called =
false;
1101 engine->PostRasterThreadTask([&called]() { called =
true; });
1103 EXPECT_TRUE(called);
1109 std::unique_ptr<WindowBindingHandler> wbh)
1114 BoxConstraints()) {}
1118 NotifyWinEventWrapper,
1119 (ui::AXPlatformNodeWin*, ax::mojom::Event),
1125 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
1130 auto& context = GetContext();
1131 WindowsConfigBuilder builder{context};
1132 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
1136 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
1137 context.AddNativeFunction(
"Signal", native_entry);
1139 EnginePtr engine{builder.RunHeadless()};
1140 ASSERT_NE(engine,
nullptr);
1142 ui::AXPlatformNodeDelegateBase parent_delegate;
1145 auto window_binding_handler =
1146 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1147 EXPECT_CALL(*window_binding_handler, GetAlertDelegate)
1148 .WillOnce(Return(&delegate));
1151 MockFlutterWindowsView view{windows_engine,
1152 std::move(window_binding_handler)};
1153 EngineModifier modifier{windows_engine};
1154 modifier.SetImplicitView(&view);
1158 EXPECT_CALL(view, NotifyWinEventWrapper).Times(1);
1162 windows_engine->task_runner()->ProcessTasks();
1168 auto& context = GetContext();
1169 WindowsConfigBuilder builder{context};
1170 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
1174 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
1175 context.AddNativeFunction(
"Signal", native_entry);
1177 EnginePtr engine{builder.RunHeadless()};
1178 ASSERT_NE(engine,
nullptr);
1185 windows_engine->task_runner()->ProcessTasks();
1192 fml::testing::LogCapture log_capture;
1194 auto& context = GetContext();
1195 WindowsConfigBuilder builder{context};
1196 builder.SetDartEntrypoint(
"sendAccessibilityTooltipEvent");
1200 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
1201 context.AddNativeFunction(
"Signal", native_entry);
1203 ViewControllerPtr controller{builder.Run()};
1204 ASSERT_NE(controller,
nullptr);
1212 windows_engine->task_runner()->ProcessTasks();
1218 EXPECT_EQ(log_capture.str().find(
"tooltip"), std::string::npos);
1230 (std::optional<HWND>, std::optional<WPARAM>, std::optional<LPARAM>, UINT),
1247 FlutterWindowsEngineBuilder builder{GetContext()};
1248 builder.SetDartEntrypoint(
"exitTestExit");
1249 bool finished =
false;
1251 auto engine = builder.Build();
1252 auto window_binding_handler =
1253 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1254 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1256 EngineModifier modifier(engine.get());
1257 modifier.SetImplicitView(&view);
1258 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1259 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1260 EXPECT_CALL(*handler, Quit)
1261 .WillOnce([&finished](std::optional<HWND> hwnd,
1262 std::optional<WPARAM> wparam,
1263 std::optional<LPARAM> lparam,
1264 UINT exit_code) { finished = exit_code == 0; });
1265 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
1266 modifier.SetLifecycleManager(std::move(handler));
1268 engine->lifecycle_manager()->BeginProcessingExit();
1272 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1278 engine->task_runner()->ProcessTasks();
1283 FlutterWindowsEngineBuilder builder{GetContext()};
1284 builder.SetDartEntrypoint(
"exitTestCancel");
1285 bool did_call =
false;
1287 auto engine = builder.Build();
1288 auto window_binding_handler =
1289 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1290 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1292 EngineModifier modifier(engine.get());
1293 modifier.SetImplicitView(&view);
1294 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1295 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1296 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
1297 EXPECT_CALL(*handler, Quit).Times(0);
1298 modifier.SetLifecycleManager(std::move(handler));
1299 engine->lifecycle_manager()->BeginProcessingExit();
1301 auto binary_messenger =
1302 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1303 binary_messenger->SetMessageHandler(
1304 "flutter/platform", [&did_call](
const uint8_t*
message,
1307 EXPECT_NE(contents.find(
"\"method\":\"System.exitApplication\""),
1309 EXPECT_NE(contents.find(
"\"type\":\"required\""), std::string::npos);
1310 EXPECT_NE(contents.find(
"\"exitCode\":0"), std::string::npos);
1312 char response[] =
"";
1313 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1318 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1322 engine->task_runner()->ProcessTasks();
1330 FlutterWindowsEngineBuilder builder{GetContext()};
1331 builder.SetDartEntrypoint(
"exitTestExit");
1332 bool second_close =
false;
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));
1339 EngineModifier modifier(engine.get());
1340 modifier.SetImplicitView(&view);
1341 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1342 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1343 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
true));
1344 EXPECT_CALL(*handler, Quit)
1345 .WillOnce([handler_ptr = handler.get()](
1346 std::optional<HWND> hwnd, std::optional<WPARAM> wparam,
1347 std::optional<LPARAM> lparam, UINT exit_code) {
1348 handler_ptr->WindowsLifecycleManager::Quit(hwnd, wparam, lparam,
1351 EXPECT_CALL(*handler, DispatchMessage)
1353 [&engine](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
1354 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1355 hwnd, msg, wparam, lparam);
1357 modifier.SetLifecycleManager(std::move(handler));
1358 engine->lifecycle_manager()->BeginProcessingExit();
1366 engine->window_proc_delegate_manager()->RegisterTopLevelWindowProcDelegate(
1371 bool* called =
reinterpret_cast<bool*
>(
user_data);
1378 reinterpret_cast<void*
>(&second_close));
1380 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1383 while (!second_close) {
1384 engine->task_runner()->ProcessTasks();
1389 FlutterWindowsEngineBuilder builder{GetContext()};
1390 builder.SetDartEntrypoint(
"exitTestExit");
1391 bool finished =
false;
1393 auto engine = builder.Build();
1394 auto window_binding_handler =
1395 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1396 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1398 EngineModifier modifier(engine.get());
1399 modifier.SetImplicitView(&view);
1400 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1401 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1402 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce([&finished]() {
1407 EXPECT_CALL(*handler, Quit).Times(0);
1408 modifier.SetLifecycleManager(std::move(handler));
1409 engine->lifecycle_manager()->BeginProcessingExit();
1413 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1417 engine->task_runner()->ProcessTasks();
1422 FlutterWindowsEngineBuilder builder{GetContext()};
1424 auto engine = builder.Build();
1425 auto window_binding_handler =
1426 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1427 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1429 EngineModifier modifier(engine.get());
1430 modifier.SetImplicitView(&view);
1431 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1432 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1433 EXPECT_CALL(*handler, IsLastWindowOfProcess).Times(0);
1434 modifier.SetLifecycleManager(std::move(handler));
1436 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1441 FlutterWindowsEngineBuilder builder{GetContext()};
1443 auto engine = builder.Build();
1444 auto window_binding_handler =
1445 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1446 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1448 EngineModifier modifier(engine.get());
1449 modifier.SetImplicitView(&view);
1450 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1451 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1452 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1453 modifier.SetLifecycleManager(std::move(handler));
1454 engine->lifecycle_manager()->BeginProcessingExit();
1456 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1461 FlutterWindowsEngineBuilder builder{GetContext()};
1463 auto engine = builder.Build();
1464 auto window_binding_handler =
1465 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1466 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1468 EngineModifier modifier(engine.get());
1469 modifier.SetImplicitView(&view);
1470 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1471 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1472 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1473 modifier.SetLifecycleManager(std::move(handler));
1474 engine->lifecycle_manager()->BeginProcessingExit();
1476 engine->lifecycle_manager()->ExternalWindowMessage(0, WM_CLOSE, 0, 0);
1480 FlutterWindowsEngineBuilder builder{GetContext()};
1482 auto engine = builder.Build();
1483 auto window_binding_handler =
1484 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1485 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1487 EngineModifier modifier(engine.get());
1488 modifier.SetImplicitView(&view);
1489 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1492 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1493 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1495 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1499 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1502 engine->lifecycle_manager()->OnWindowStateEvent((HWND)1,
1505 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1509 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1512 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1513 (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0);
1515 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1519 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1522 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1523 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1525 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1529 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1534 FlutterWindowsEngineBuilder builder{GetContext()};
1536 auto engine = builder.Build();
1537 auto window_binding_handler =
1538 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1539 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1541 EngineModifier modifier(engine.get());
1542 modifier.SetImplicitView(&view);
1543 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1548 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1550 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1553 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1557 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1562 FlutterWindowsEngineBuilder builder{GetContext()};
1563 HWND outer =
reinterpret_cast<HWND
>(1);
1564 HWND inner =
reinterpret_cast<HWND
>(2);
1566 auto engine = builder.Build();
1567 auto window_binding_handler =
1568 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1569 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1570 ON_CALL(view, GetWindowHandle).WillByDefault([=]() {
return inner; });
1572 EngineModifier modifier(engine.get());
1573 modifier.SetImplicitView(&view);
1574 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1579 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1580 outer, WM_SHOWWINDOW, TRUE, NULL);
1584 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1588 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1594 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1599 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1604 FlutterWindowsEngineBuilder builder{GetContext()};
1605 builder.SetDartEntrypoint(
"enableLifecycleTest");
1606 bool finished =
false;
1608 auto engine = builder.Build();
1609 auto window_binding_handler =
1610 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1611 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1613 EngineModifier modifier(engine.get());
1614 modifier.SetImplicitView(&view);
1615 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1616 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1617 EXPECT_CALL(*handler, SetLifecycleState)
1619 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1621 modifier.SetLifecycleManager(std::move(handler));
1623 auto binary_messenger =
1624 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1626 binary_messenger->SetMessageHandler(
1627 "flutter/unittest", [&finished](
const uint8_t*
message,
1630 EXPECT_NE(contents.find(
"AppLifecycleState.inactive"),
1633 char response[] =
"";
1634 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1640 HWND hwnd =
reinterpret_cast<HWND
>(1);
1643 EXPECT_FALSE(finished);
1647 engine->lifecycle_manager()->BeginProcessingLifecycle();
1651 engine->task_runner()->ProcessTasks();
1656 FlutterWindowsEngineBuilder builder{GetContext()};
1657 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1658 bool enabled_lifecycle =
false;
1659 bool dart_responded =
false;
1661 auto engine = builder.Build();
1662 auto window_binding_handler =
1663 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1664 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1666 EngineModifier modifier(engine.get());
1667 modifier.SetImplicitView(&view);
1668 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1669 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1670 EXPECT_CALL(*handler, SetLifecycleState)
1672 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1674 handler->begin_processing_callback = [&]() { enabled_lifecycle =
true; };
1675 modifier.SetLifecycleManager(std::move(handler));
1677 auto binary_messenger =
1678 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1679 binary_messenger->SetMessageHandler(
1683 EXPECT_NE(contents.find(
"AppLifecycleState."), std::string::npos);
1684 dart_responded =
true;
1685 char response[] =
"";
1686 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1691 while (!enabled_lifecycle) {
1692 engine->task_runner()->ProcessTasks();
1695 HWND hwnd =
reinterpret_cast<HWND
>(1);
1699 while (!dart_responded) {
1700 engine->task_runner()->ProcessTasks();
1705 FlutterWindowsEngineBuilder builder{GetContext()};
1706 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1708 auto engine = builder.Build();
1709 auto window_binding_handler =
1710 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1711 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1713 EngineModifier modifier(engine.get());
1714 modifier.SetImplicitView(&view);
1715 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1717 bool lifecycle_began =
false;
1718 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1719 handler->begin_processing_callback = [&]() { lifecycle_began =
true; };
1720 modifier.SetLifecycleManager(std::move(handler));
1724 while (!lifecycle_began) {
1725 engine->task_runner()->ProcessTasks();
1730 FlutterWindowsEngineBuilder builder{GetContext()};
1731 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1732 auto engine = builder.Build();
1734 EngineModifier modifier{engine.get()};
1735 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1737 bool received_call =
false;
1739 auto manager = std::make_unique<MockPlatformViewManager>(engine.get());
1740 EXPECT_CALL(*manager, AddPlatformView)
1742 received_call =
true;
1745 modifier.SetPlatformViewPlugin(std::move(manager));
1749 while (!received_call) {
1750 engine->task_runner()->ProcessTasks();
1755 FlutterWindowsEngineBuilder builder{GetContext()};
1756 auto engine = builder.Build();
1758 EngineModifier modifier{engine.get()};
1760 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1761 modifier.embedder_api().AddView = MOCK_ENGINE_PROC(
1764 const FlutterAddViewInfo* info) {
return kInternalInconsistency; });
1766 ASSERT_TRUE(engine->
Run());
1770 auto implicit_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1772 std::unique_ptr<FlutterWindowsView> implicit_view =
1773 engine->CreateView(std::move(implicit_window),
1774 false, BoxConstraints());
1776 EXPECT_TRUE(implicit_view);
1779 auto second_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1782 engine->CreateView(std::move(second_window),
1783 false, BoxConstraints()),
1784 "FlutterEngineAddView returned an unexpected result");
1788 FlutterWindowsEngineBuilder builder{GetContext()};
1789 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1790 auto engine = builder.Build();
1792 EngineModifier modifier{engine.get()};
1794 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1795 modifier.embedder_api().RemoveView = MOCK_ENGINE_PROC(
1798 const FlutterRemoveViewInfo* info) {
return kInternalInconsistency; });
1800 ASSERT_TRUE(engine->
Run());
1801 EXPECT_DEBUG_DEATH(engine->RemoveView(123),
1802 "FlutterEngineRemoveView returned an unexpected result");
1806 auto& context = GetContext();
1807 WindowsConfigBuilder builder{context};
1808 builder.SetDartEntrypoint(
"mergedUIThread");
1811 std::optional<std::thread::id> ui_thread_id;
1813 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
1814 ui_thread_id = std::this_thread::get_id();
1816 context.AddNativeFunction(
"Signal", native_entry);
1818 EnginePtr engine{builder.RunHeadless()};
1819 while (!ui_thread_id) {
1822 ASSERT_EQ(*ui_thread_id, std::this_thread::get_id());
1826 FlutterWindowsEngineBuilder builder{GetContext()};
1827 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1828 auto window_binding_handler =
1829 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1830 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1832 EngineModifier modifier(engine.get());
1833 modifier.SetImplicitView(&view);
1835 FlutterViewFocusChangeRequest request;
1838 EXPECT_CALL(view, Focus()).WillOnce(Return(
true));
1839 modifier.OnViewFocusChangeRequest(&request);
1843 auto& context = GetContext();
1844 WindowsConfigBuilder builder{context};
1845 builder.SetDartEntrypoint(
"sendSemanticsTreeInfo");
1850 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
1851 context.AddNativeFunction(
"Signal", native_entry);
1854 EnginePtr engine{builder.RunHeadless()};
1855 ASSERT_NE(engine,
nullptr);
1857 auto window_binding_handler1 =
1858 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1859 auto window_binding_handler2 =
1860 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1865 EXPECT_CALL(*window_binding_handler1, GetPhysicalWindowBounds)
1867 EXPECT_CALL(*window_binding_handler1, GetDpiScale)
1868 .WillRepeatedly(testing::Return(96.0));
1869 EXPECT_CALL(*window_binding_handler2, GetPhysicalWindowBounds)
1871 EXPECT_CALL(*window_binding_handler2, GetDpiScale)
1872 .WillRepeatedly(testing::Return(96.0));
1875 EngineModifier modifier{windows_engine};
1876 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1881 auto view1 = windows_engine->
CreateView(std::move(window_binding_handler1),
1884 auto view2 = windows_engine->CreateView(std::move(window_binding_handler2),
1890 windows_engine->UpdateSemanticsEnabled(
true);
1893 windows_engine->task_runner()->ProcessTasks();
1896 auto accessibility_bridge1 = view1->accessibility_bridge().lock();
1897 auto accessibility_bridge2 = view2->accessibility_bridge().lock();
1902 !accessibility_bridge1->GetPlatformNodeFromTree(view1->view_id() + 1)) {
1903 windows_engine->task_runner()->ProcessTasks();
1907 !accessibility_bridge2->GetPlatformNodeFromTree(view2->view_id() + 1)) {
1908 windows_engine->task_runner()->ProcessTasks();
1912 auto tree1 = accessibility_bridge1->GetTree();
1913 auto tree2 = accessibility_bridge2->GetTree();
1914 EXPECT_NE(tree1->GetFromId(view1->view_id() + 1),
nullptr);
1915 EXPECT_NE(tree2->GetFromId(view2->view_id() + 1),
nullptr);
void UpdateSemanticsEnabled(bool enabled)
std::unique_ptr< FlutterWindowsView > CreateView(std::unique_ptr< WindowBindingHandler > window, bool is_sized_to_content, const BoxConstraints &box_constraints, FlutterWindowsViewSizingDelegate *sizing_delegate=nullptr)
virtual void Quit(std::optional< HWND > window, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
virtual void BeginProcessingLifecycle()
virtual void DispatchMessage(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
virtual bool IsLastWindowOfProcess()
virtual void SetLifecycleState(AppLifecycleState state)
~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(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef ref)
FlutterDesktopBinaryReply callback
TEST_F(AccessibilityPluginTest, DirectAnnounceCall)
UINT GetDpiForMonitor(HMONITOR monitor)
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
static void WindowsPlatformThreadPrioritySetter(FlutterThreadPriority priority)
constexpr FlutterViewId kImplicitViewId