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);
46 using ::testing::NiceMock;
47 using ::testing::Return;
53 FlutterWindowsEngineBuilder builder{GetContext()};
54 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
56 EngineModifier modifier(engine.get());
57 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
59 ASSERT_TRUE(engine->Run());
61 ASSERT_EQ(engine->view(123),
nullptr);
65 FlutterWindowsEngineBuilder builder{GetContext()};
66 builder.AddDartEntrypointArgument(
"arg1");
67 builder.AddDartEntrypointArgument(
"arg2");
69 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
70 EngineModifier modifier(engine.get());
73 bool run_called =
false;
74 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
75 Run, ([&run_called, engine_instance = engine.get()](
76 size_t version,
const FlutterRendererConfig* config,
77 const FlutterProjectArgs* args,
void*
user_data,
80 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
82 EXPECT_EQ(version, FLUTTER_ENGINE_VERSION);
83 EXPECT_NE(config,
nullptr);
85 EXPECT_EQ(config->type, kOpenGL);
88 EXPECT_NE(args->assets_path,
nullptr);
89 EXPECT_NE(args->icu_data_path,
nullptr);
90 EXPECT_EQ(args->dart_entrypoint_argc, 2U);
91 EXPECT_EQ(strcmp(args->dart_entrypoint_argv[0],
"arg1"), 0);
92 EXPECT_EQ(strcmp(args->dart_entrypoint_argv[1],
"arg2"), 0);
93 EXPECT_NE(args->platform_message_callback,
nullptr);
94 EXPECT_NE(args->custom_task_runners,
nullptr);
95 EXPECT_NE(args->custom_task_runners->thread_priority_setter,
nullptr);
96 EXPECT_EQ(args->custom_dart_entrypoint,
nullptr);
97 EXPECT_NE(args->vsync_callback,
nullptr);
98 EXPECT_EQ(args->update_semantics_callback,
nullptr);
99 EXPECT_NE(args->update_semantics_callback2,
nullptr);
100 EXPECT_EQ(args->update_semantics_node_callback,
nullptr);
101 EXPECT_EQ(args->update_semantics_custom_action_callback,
nullptr);
102 EXPECT_NE(args->view_focus_change_request_callback,
nullptr);
104 args->custom_task_runners->thread_priority_setter(
105 FlutterThreadPriority::kRaster);
106 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
107 THREAD_PRIORITY_ABOVE_NORMAL);
111 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
112 UpdateAccessibilityFeatures,
114 FlutterAccessibilityFeature flags) {
return kSuccess; });
117 bool update_locales_called =
false;
118 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
120 ([&update_locales_called](
auto engine,
const FlutterLocale** locales,
121 size_t locales_count) {
122 update_locales_called =
true;
124 EXPECT_GT(locales_count, 0);
125 EXPECT_NE(locales,
nullptr);
131 bool settings_message_sent =
false;
132 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
134 ([&settings_message_sent](
auto engine,
auto message) {
135 if (std::string(
message->channel) == std::string(
"flutter/settings")) {
136 settings_message_sent = true;
143 bool notify_display_update_called =
false;
144 modifier.SetFrameInterval(16600000);
145 modifier.embedder_api().NotifyDisplayUpdate = MOCK_ENGINE_PROC(
147 ([¬ify_display_update_called, engine_instance = engine.get()](
149 const FlutterEngineDisplaysUpdateType update_type,
150 const FlutterEngineDisplay* embedder_displays,
151 size_t display_count) {
152 EXPECT_EQ(update_type, kFlutterEngineDisplaysUpdateTypeStartup);
153 EXPECT_EQ(display_count, 1);
155 FlutterEngineDisplay display = embedder_displays[0];
157 EXPECT_EQ(display.display_id, 0);
158 EXPECT_EQ(display.single_display,
true);
159 EXPECT_EQ(std::floor(display.refresh_rate), 60.0);
161 notify_display_update_called =
true;
166 modifier.SetEGLManager(std::make_unique<egl::MockManager>());
170 EXPECT_TRUE(run_called);
171 EXPECT_TRUE(update_locales_called);
172 EXPECT_TRUE(settings_message_sent);
173 EXPECT_TRUE(notify_display_update_called);
177 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
178 modifier.ReleaseEGLManager();
182 FlutterWindowsEngineBuilder builder{GetContext()};
183 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
184 EngineModifier modifier(engine.get());
185 bool on_vsync_called =
false;
187 modifier.embedder_api().GetCurrentTime =
188 MOCK_ENGINE_PROC(GetCurrentTime, ([]() -> uint64_t {
return 1; }));
189 modifier.embedder_api().OnVsync = MOCK_ENGINE_PROC(
191 ([&on_vsync_called, engine_instance = engine.get()](
193 uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos) {
195 EXPECT_EQ(frame_start_time_nanos, 16600000);
196 EXPECT_EQ(frame_target_time_nanos, 33200000);
197 on_vsync_called =
true;
200 modifier.SetStartTime(0);
201 modifier.SetFrameInterval(16600000);
205 EXPECT_TRUE(on_vsync_called);
209 FlutterWindowsEngineBuilder builder{GetContext()};
210 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
211 EngineModifier modifier(engine.get());
213 modifier.embedder_api().NotifyDisplayUpdate =
214 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
215 ([engine_instance = engine.get()](
217 const FlutterEngineDisplaysUpdateType update_type,
218 const FlutterEngineDisplay* embedder_displays,
219 size_t display_count) {
return kSuccess; }));
222 bool run_called =
false;
223 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
224 Run, ([&run_called, engine_instance = engine.get()](
225 size_t version,
const FlutterRendererConfig* config,
226 const FlutterProjectArgs* args,
void*
user_data,
229 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
231 EXPECT_EQ(config->type, kSoftware);
235 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
236 UpdateAccessibilityFeatures,
238 FlutterAccessibilityFeature flags) {
return kSuccess; });
242 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
243 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
244 size_t locales_count) {
return kSuccess; }));
245 modifier.embedder_api().SendPlatformMessage =
246 MOCK_ENGINE_PROC(SendPlatformMessage,
247 ([](
auto engine,
auto message) {
return kSuccess; }));
250 modifier.SetEGLManager(
nullptr);
254 EXPECT_TRUE(run_called);
258 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
262 FlutterWindowsEngineBuilder builder{GetContext()};
263 builder.SetSwitches({
"--enable-impeller=true"});
264 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
265 EngineModifier modifier(engine.get());
267 modifier.embedder_api().NotifyDisplayUpdate =
268 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
269 ([engine_instance = engine.get()](
271 const FlutterEngineDisplaysUpdateType update_type,
272 const FlutterEngineDisplay* embedder_displays,
273 size_t display_count) {
return kSuccess; }));
276 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
277 UpdateAccessibilityFeatures,
279 FlutterAccessibilityFeature flags) {
return kSuccess; });
283 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
284 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
285 size_t locales_count) {
return kSuccess; }));
286 modifier.embedder_api().SendPlatformMessage =
287 MOCK_ENGINE_PROC(SendPlatformMessage,
288 ([](
auto engine,
auto message) {
return kSuccess; }));
291 modifier.SetEGLManager(
nullptr);
293 EXPECT_FALSE(engine->
Run());
297 FlutterWindowsEngineBuilder builder{GetContext()};
298 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
299 EngineModifier modifier(engine.get());
301 const char* channel =
"test";
302 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
306 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
307 SendPlatformMessage, ([&called, test_message](
auto engine,
auto message) {
309 EXPECT_STREQ(
message->channel,
"test");
310 EXPECT_EQ(
message->message_size, test_message.size());
311 EXPECT_EQ(memcmp(
message->message, test_message.data(),
314 EXPECT_EQ(
message->response_handle,
nullptr);
318 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
324 FlutterWindowsEngineBuilder builder{GetContext()};
325 builder.SetDartEntrypoint(
"hiPlatformChannels");
327 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
328 EngineModifier modifier(engine.get());
329 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
331 auto binary_messenger =
332 std::make_unique<BinaryMessengerImpl>(engine->messenger());
335 bool did_call_callback =
false;
336 bool did_call_reply =
false;
337 bool did_call_dart_reply =
false;
338 std::string channel =
"hi";
339 binary_messenger->SetMessageHandler(
341 [&did_call_callback, &did_call_dart_reply](
343 if (message_size == 5) {
344 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
345 char response[] = {
'b',
'y',
'e'};
346 reply(
reinterpret_cast<uint8_t*
>(response), 3);
347 did_call_callback =
true;
349 EXPECT_EQ(message_size, 3);
350 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
351 did_call_dart_reply =
true;
354 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
355 binary_messenger->Send(
356 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
357 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
358 EXPECT_EQ(reply_size, 5);
359 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
360 did_call_reply =
true;
363 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
364 engine->task_runner()->ProcessTasks();
369 FlutterWindowsEngineBuilder builder{GetContext()};
370 builder.SetDartEntrypoint(
"hiPlatformChannels");
372 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
374 EngineModifier modifier(engine.get());
375 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
377 auto binary_messenger =
378 std::make_unique<BinaryMessengerImpl>(engine->messenger());
381 bool did_call_callback =
false;
382 bool did_call_reply =
false;
383 bool did_call_dart_reply =
false;
384 std::string channel =
"hi";
385 std::unique_ptr<std::thread> reply_thread;
386 binary_messenger->SetMessageHandler(
388 [&did_call_callback, &did_call_dart_reply, &reply_thread](
390 if (message_size == 5) {
391 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
392 reply_thread.reset(
new std::thread([reply = std::move(reply)]() {
393 char response[] = {
'b',
'y',
'e'};
394 reply(
reinterpret_cast<uint8_t*
>(response), 3);
396 did_call_callback =
true;
398 EXPECT_EQ(message_size, 3);
399 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
400 did_call_dart_reply =
true;
403 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
404 binary_messenger->Send(
405 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
406 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
407 EXPECT_EQ(reply_size, 5);
408 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
409 did_call_reply =
true;
412 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
413 engine->task_runner()->ProcessTasks();
415 ASSERT_TRUE(reply_thread);
416 reply_thread->join();
420 FlutterWindowsEngineBuilder builder{GetContext()};
421 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
422 EngineModifier modifier(engine.get());
424 const char* channel =
"test";
425 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
426 auto* dummy_response_handle =
427 reinterpret_cast<FlutterPlatformMessageResponseHandle*
>(5);
429 void* reply_user_data =
reinterpret_cast<void*
>(6);
433 bool create_response_handle_called =
false;
434 modifier.embedder_api().PlatformMessageCreateResponseHandle =
436 PlatformMessageCreateResponseHandle,
437 ([&create_response_handle_called, &reply_handler, reply_user_data,
438 dummy_response_handle](
auto engine,
auto reply,
auto user_data,
439 auto response_handle) {
440 create_response_handle_called =
true;
441 EXPECT_EQ(reply, reply_handler);
443 EXPECT_NE(response_handle,
nullptr);
444 *response_handle = dummy_response_handle;
447 bool release_response_handle_called =
false;
448 modifier.embedder_api().PlatformMessageReleaseResponseHandle =
450 PlatformMessageReleaseResponseHandle,
451 ([&release_response_handle_called, dummy_response_handle](
452 auto engine,
auto response_handle) {
453 release_response_handle_called =
true;
454 EXPECT_EQ(response_handle, dummy_response_handle);
457 bool send_message_called =
false;
458 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
459 SendPlatformMessage, ([&send_message_called, test_message,
460 dummy_response_handle](
auto engine,
auto message) {
461 send_message_called =
true;
462 EXPECT_STREQ(
message->channel,
"test");
463 EXPECT_EQ(
message->message_size, test_message.size());
464 EXPECT_EQ(memcmp(
message->message, test_message.data(),
467 EXPECT_EQ(
message->response_handle, dummy_response_handle);
471 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
472 reply_handler, reply_user_data);
473 EXPECT_TRUE(create_response_handle_called);
474 EXPECT_TRUE(release_response_handle_called);
475 EXPECT_TRUE(send_message_called);
479 FlutterWindowsEngineBuilder builder{GetContext()};
480 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
481 EngineModifier modifier(engine.get());
485 modifier.embedder_api().DispatchSemanticsAction = MOCK_ENGINE_PROC(
486 DispatchSemanticsAction,
487 ([&called, &
message](
auto engine,
auto target,
auto action,
auto data,
490 EXPECT_EQ(target, 42);
491 EXPECT_EQ(
action, kFlutterSemanticsActionDismiss);
493 EXPECT_EQ(data_length,
message.size());
497 auto data = fml::MallocMapping::Copy(
message.c_str(),
message.size());
498 engine->DispatchSemanticsAction(42, kFlutterSemanticsActionDismiss,
505 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
506 THREAD_PRIORITY_BELOW_NORMAL);
509 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
510 THREAD_PRIORITY_ABOVE_NORMAL);
513 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
514 THREAD_PRIORITY_ABOVE_NORMAL);
518 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
521 EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
525 FlutterWindowsEngineBuilder builder{GetContext()};
526 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
527 EngineModifier modifier(engine.get());
529 MockEmbedderApiForKeyboard(modifier,
530 std::make_shared<MockKeyResponseController>());
537 engine->AddPluginRegistrarDestructionCallback(
539 auto result =
reinterpret_cast<int*
>(ref);
543 engine->AddPluginRegistrarDestructionCallback(
545 auto result =
reinterpret_cast<int*
>(ref);
551 EXPECT_EQ(result1, 1);
552 EXPECT_EQ(result2, 2);
556 FlutterWindowsEngineBuilder builder{GetContext()};
557 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
558 EngineModifier modifier(engine.get());
561 modifier.embedder_api().ScheduleFrame =
562 MOCK_ENGINE_PROC(ScheduleFrame, ([&called](
auto engine) {
567 engine->ScheduleFrame();
572 FlutterWindowsEngineBuilder builder{GetContext()};
573 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
574 EngineModifier modifier(engine.get());
577 modifier.embedder_api().SetNextFrameCallback = MOCK_ENGINE_PROC(
578 SetNextFrameCallback, ([&called](
auto engine,
auto callback,
auto data) {
583 engine->SetNextFrameCallback([]() {});
588 FlutterWindowsEngineBuilder builder{GetContext()};
589 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
590 EXPECT_EQ(engine->GetExecutableName(),
"flutter_windows_unittests.exe");
596 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
597 EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
598 .WillOnce(Return(
true))
599 .WillOnce(Return(
false));
601 FlutterWindowsEngineBuilder builder{GetContext()};
602 builder.SetWindowsProcTable(windows_proc_table);
603 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
604 EngineModifier modifier(engine.get());
606 std::optional<FlutterAccessibilityFeature> engine_flags;
607 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
608 UpdateAccessibilityFeatures, ([&engine_flags](
auto engine,
auto flags) {
609 engine_flags = flags;
612 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
614 [](
auto engine,
const auto message) {
return kSuccess; });
617 engine->UpdateHighContrastMode();
619 EXPECT_TRUE(engine->high_contrast_enabled());
620 EXPECT_TRUE(engine_flags.has_value());
622 engine_flags.value() &
623 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
626 engine_flags.reset();
627 engine->UpdateHighContrastMode();
629 EXPECT_FALSE(engine->high_contrast_enabled());
630 EXPECT_TRUE(engine_flags.has_value());
632 engine_flags.value() &
633 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
637 FlutterWindowsEngineBuilder builder{GetContext()};
638 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
639 EngineModifier modifier(engine.get());
641 modifier.embedder_api().PostRenderThreadTask = MOCK_ENGINE_PROC(
642 PostRenderThreadTask, ([](
auto engine,
auto callback,
auto context) {
648 engine->PostRasterThreadTask([&called]() { called =
true; });
656 std::unique_ptr<WindowBindingHandler> wbh)
661 NotifyWinEventWrapper,
662 (ui::AXPlatformNodeWin*, ax::mojom::Event),
664 MOCK_METHOD(HWND, GetWindowHandle, (), (
const,
override));
665 MOCK_METHOD(
bool, Focus, (), (
override));
668 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
673 auto& context = GetContext();
674 WindowsConfigBuilder builder{context};
675 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
679 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
680 context.AddNativeFunction(
"Signal", native_entry);
682 EnginePtr engine{builder.RunHeadless()};
683 ASSERT_NE(engine,
nullptr);
685 ui::AXPlatformNodeDelegateBase parent_delegate;
688 auto window_binding_handler =
689 std::make_unique<NiceMock<MockWindowBindingHandler>>();
690 EXPECT_CALL(*window_binding_handler, GetAlertDelegate)
691 .WillOnce(Return(&delegate));
694 MockFlutterWindowsView view{windows_engine,
695 std::move(window_binding_handler)};
696 EngineModifier modifier{windows_engine};
697 modifier.SetImplicitView(&view);
701 EXPECT_CALL(view, NotifyWinEventWrapper).Times(1);
705 windows_engine->task_runner()->ProcessTasks();
711 auto& context = GetContext();
712 WindowsConfigBuilder builder{context};
713 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
717 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
718 context.AddNativeFunction(
"Signal", native_entry);
720 EnginePtr engine{builder.RunHeadless()};
721 ASSERT_NE(engine,
nullptr);
728 windows_engine->task_runner()->ProcessTasks();
735 fml::testing::LogCapture log_capture;
737 auto& context = GetContext();
738 WindowsConfigBuilder builder{context};
739 builder.SetDartEntrypoint(
"sendAccessibilityTooltipEvent");
743 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
744 context.AddNativeFunction(
"Signal", native_entry);
746 ViewControllerPtr controller{builder.Run()};
747 ASSERT_NE(controller,
nullptr);
755 windows_engine->task_runner()->ProcessTasks();
761 EXPECT_EQ(log_capture.str().find(
"tooltip"), std::string::npos);
773 (std::optional<HWND>, std::optional<WPARAM>, std::optional<LPARAM>, UINT),
790 FlutterWindowsEngineBuilder builder{GetContext()};
791 builder.SetDartEntrypoint(
"exitTestExit");
792 bool finished =
false;
794 auto engine = builder.Build();
795 auto window_binding_handler =
796 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
797 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
799 EngineModifier modifier(engine.get());
800 modifier.SetImplicitView(&view);
801 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
802 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
804 EXPECT_CALL(*handler, Quit)
805 .WillOnce([&finished](std::optional<HWND> hwnd,
806 std::optional<WPARAM> wparam,
807 std::optional<LPARAM> lparam,
808 UINT exit_code) { finished = exit_code == 0; });
809 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
810 modifier.SetLifecycleManager(std::move(handler));
812 engine->lifecycle_manager()->BeginProcessingExit();
816 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
822 engine->task_runner()->ProcessTasks();
827 FlutterWindowsEngineBuilder builder{GetContext()};
828 builder.SetDartEntrypoint(
"exitTestCancel");
829 bool did_call =
false;
831 auto engine = builder.Build();
832 auto window_binding_handler =
833 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
834 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
836 EngineModifier modifier(engine.get());
837 modifier.SetImplicitView(&view);
838 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
839 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
841 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
842 EXPECT_CALL(*handler, Quit).Times(0);
843 modifier.SetLifecycleManager(std::move(handler));
844 engine->lifecycle_manager()->BeginProcessingExit();
846 auto binary_messenger =
847 std::make_unique<BinaryMessengerImpl>(engine->messenger());
848 binary_messenger->SetMessageHandler(
849 "flutter/platform", [&did_call](
const uint8_t*
message,
852 EXPECT_NE(contents.find(
"\"method\":\"System.exitApplication\""),
854 EXPECT_NE(contents.find(
"\"type\":\"required\""), std::string::npos);
855 EXPECT_NE(contents.find(
"\"exitCode\":0"), std::string::npos);
857 char response[] =
"";
858 reply(
reinterpret_cast<uint8_t*
>(response), 0);
863 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
867 engine->task_runner()->ProcessTasks();
875 FlutterWindowsEngineBuilder builder{GetContext()};
876 builder.SetDartEntrypoint(
"exitTestExit");
877 bool second_close =
false;
879 auto engine = builder.Build();
880 auto window_binding_handler =
881 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
882 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
884 EngineModifier modifier(engine.get());
885 modifier.SetImplicitView(&view);
886 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
887 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
889 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
true));
890 EXPECT_CALL(*handler, Quit)
891 .WillOnce([handler_ptr = handler.get()](
892 std::optional<HWND> hwnd, std::optional<WPARAM> wparam,
893 std::optional<LPARAM> lparam, UINT exit_code) {
894 handler_ptr->WindowsLifecycleManager::Quit(hwnd, wparam, lparam,
897 EXPECT_CALL(*handler, DispatchMessage)
899 [&engine](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
900 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
901 hwnd, msg, wparam, lparam);
903 modifier.SetLifecycleManager(std::move(handler));
904 engine->lifecycle_manager()->BeginProcessingExit();
912 engine->window_proc_delegate_manager()->RegisterTopLevelWindowProcDelegate(
917 bool* called =
reinterpret_cast<bool*
>(
user_data);
924 reinterpret_cast<void*
>(&second_close));
926 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
929 while (!second_close) {
930 engine->task_runner()->ProcessTasks();
935 FlutterWindowsEngineBuilder builder{GetContext()};
936 builder.SetDartEntrypoint(
"exitTestExit");
937 bool finished =
false;
939 auto engine = builder.Build();
940 auto window_binding_handler =
941 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
942 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
944 EngineModifier modifier(engine.get());
945 modifier.SetImplicitView(&view);
946 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
947 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
949 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce([&finished]() {
954 EXPECT_CALL(*handler, Quit).Times(0);
955 modifier.SetLifecycleManager(std::move(handler));
956 engine->lifecycle_manager()->BeginProcessingExit();
960 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
964 engine->task_runner()->ProcessTasks();
969 FlutterWindowsEngineBuilder builder{GetContext()};
971 auto engine = builder.Build();
972 auto window_binding_handler =
973 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
974 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
976 EngineModifier modifier(engine.get());
977 modifier.SetImplicitView(&view);
978 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
979 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
980 EXPECT_CALL(*handler, IsLastWindowOfProcess).Times(0);
981 modifier.SetLifecycleManager(std::move(handler));
983 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
988 FlutterWindowsEngineBuilder builder{GetContext()};
990 auto engine = builder.Build();
991 auto window_binding_handler =
992 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
993 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
995 EngineModifier modifier(engine.get());
996 modifier.SetImplicitView(&view);
997 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
998 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
999 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1000 modifier.SetLifecycleManager(std::move(handler));
1001 engine->lifecycle_manager()->BeginProcessingExit();
1003 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1008 FlutterWindowsEngineBuilder builder{GetContext()};
1010 auto engine = builder.Build();
1011 auto window_binding_handler =
1012 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1013 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1015 EngineModifier modifier(engine.get());
1016 modifier.SetImplicitView(&view);
1017 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1018 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1019 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1020 modifier.SetLifecycleManager(std::move(handler));
1021 engine->lifecycle_manager()->BeginProcessingExit();
1023 engine->lifecycle_manager()->ExternalWindowMessage(0, WM_CLOSE, 0, 0);
1027 FlutterWindowsEngineBuilder builder{GetContext()};
1029 auto engine = builder.Build();
1030 auto window_binding_handler =
1031 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1032 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1034 EngineModifier modifier(engine.get());
1035 modifier.SetImplicitView(&view);
1036 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1037 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1040 modifier.SetLifecycleManager(std::move(handler));
1045 FlutterWindowsEngineBuilder builder{GetContext()};
1047 auto engine = builder.Build();
1048 auto window_binding_handler =
1049 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1050 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1052 EngineModifier modifier(engine.get());
1053 modifier.SetImplicitView(&view);
1054 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1057 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1058 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1059 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1062 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1063 (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0);
1064 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1067 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1068 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1069 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1074 FlutterWindowsEngineBuilder builder{GetContext()};
1076 auto engine = builder.Build();
1077 auto window_binding_handler =
1078 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1079 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1081 EngineModifier modifier(engine.get());
1082 modifier.SetImplicitView(&view);
1083 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1088 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1090 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1093 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1098 FlutterWindowsEngineBuilder builder{GetContext()};
1099 HWND outer =
reinterpret_cast<HWND
>(1);
1100 HWND inner =
reinterpret_cast<HWND
>(2);
1102 auto engine = builder.Build();
1103 auto window_binding_handler =
1104 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1105 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1106 ON_CALL(view, GetWindowHandle).WillByDefault([=]() {
return inner; });
1108 EngineModifier modifier(engine.get());
1109 modifier.SetImplicitView(&view);
1110 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1115 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1116 outer, WM_SHOWWINDOW, TRUE, NULL);
1120 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1127 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1132 FlutterWindowsEngineBuilder builder{GetContext()};
1133 builder.SetDartEntrypoint(
"enableLifecycleTest");
1134 bool finished =
false;
1136 auto engine = builder.Build();
1137 auto window_binding_handler =
1138 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1139 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1141 EngineModifier modifier(engine.get());
1142 modifier.SetImplicitView(&view);
1143 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1144 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1145 EXPECT_CALL(*handler, SetLifecycleState)
1147 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1149 modifier.SetLifecycleManager(std::move(handler));
1151 auto binary_messenger =
1152 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1154 binary_messenger->SetMessageHandler(
1155 "flutter/unittest", [&finished](
const uint8_t*
message,
1158 EXPECT_NE(contents.find(
"AppLifecycleState.inactive"),
1161 char response[] =
"";
1162 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1168 HWND hwnd =
reinterpret_cast<HWND
>(1);
1171 EXPECT_FALSE(finished);
1175 engine->lifecycle_manager()->BeginProcessingLifecycle();
1179 engine->task_runner()->ProcessTasks();
1184 FlutterWindowsEngineBuilder builder{GetContext()};
1185 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1186 bool enabled_lifecycle =
false;
1187 bool dart_responded =
false;
1189 auto engine = builder.Build();
1190 auto window_binding_handler =
1191 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1192 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1194 EngineModifier modifier(engine.get());
1195 modifier.SetImplicitView(&view);
1196 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1197 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1198 EXPECT_CALL(*handler, SetLifecycleState)
1200 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1202 handler->begin_processing_callback = [&]() { enabled_lifecycle =
true; };
1203 modifier.SetLifecycleManager(std::move(handler));
1205 auto binary_messenger =
1206 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1207 binary_messenger->SetMessageHandler(
1211 EXPECT_NE(contents.find(
"AppLifecycleState."), std::string::npos);
1212 dart_responded =
true;
1213 char response[] =
"";
1214 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1219 while (!enabled_lifecycle) {
1220 engine->task_runner()->ProcessTasks();
1223 HWND hwnd =
reinterpret_cast<HWND
>(1);
1227 while (!dart_responded) {
1228 engine->task_runner()->ProcessTasks();
1233 FlutterWindowsEngineBuilder builder{GetContext()};
1234 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1236 auto engine = builder.Build();
1237 auto window_binding_handler =
1238 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1239 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1241 EngineModifier modifier(engine.get());
1242 modifier.SetImplicitView(&view);
1243 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1245 bool lifecycle_began =
false;
1246 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1247 EXPECT_CALL(*handler, SetLifecycleState).Times(1);
1248 handler->begin_processing_callback = [&]() { lifecycle_began =
true; };
1249 modifier.SetLifecycleManager(std::move(handler));
1253 while (!lifecycle_began) {
1254 engine->task_runner()->ProcessTasks();
1259 FlutterWindowsEngineBuilder builder{GetContext()};
1260 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1261 auto engine = builder.Build();
1263 EngineModifier modifier{engine.get()};
1264 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1266 bool received_call =
false;
1268 auto manager = std::make_unique<MockPlatformViewManager>(engine.get());
1269 EXPECT_CALL(*manager, AddPlatformView)
1271 received_call =
true;
1274 modifier.SetPlatformViewPlugin(std::move(manager));
1278 while (!received_call) {
1279 engine->task_runner()->ProcessTasks();
1284 FlutterWindowsEngineBuilder builder{GetContext()};
1285 auto engine = builder.Build();
1287 EngineModifier modifier{engine.get()};
1289 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1290 modifier.embedder_api().AddView = MOCK_ENGINE_PROC(
1293 const FlutterAddViewInfo* info) {
return kInternalInconsistency; });
1295 ASSERT_TRUE(engine->
Run());
1299 auto implicit_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1301 std::unique_ptr<FlutterWindowsView> implicit_view =
1302 engine->CreateView(std::move(implicit_window));
1304 EXPECT_TRUE(implicit_view);
1307 auto second_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1309 EXPECT_DEBUG_DEATH(engine->CreateView(std::move(second_window)),
1310 "FlutterEngineAddView returned an unexpected result");
1314 FlutterWindowsEngineBuilder builder{GetContext()};
1315 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1316 auto engine = builder.Build();
1318 EngineModifier modifier{engine.get()};
1320 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1321 modifier.embedder_api().RemoveView = MOCK_ENGINE_PROC(
1324 const FlutterRemoveViewInfo* info) {
return kInternalInconsistency; });
1326 ASSERT_TRUE(engine->
Run());
1327 EXPECT_DEBUG_DEATH(engine->RemoveView(123),
1328 "FlutterEngineRemoveView returned an unexpected result");
1332 auto& context = GetContext();
1333 WindowsConfigBuilder builder{context};
1334 builder.SetDartEntrypoint(
"mergedUIThread");
1337 std::optional<std::thread::id> ui_thread_id;
1339 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
1340 ui_thread_id = std::this_thread::get_id();
1342 context.AddNativeFunction(
"Signal", native_entry);
1344 EnginePtr engine{builder.RunHeadless()};
1345 while (!ui_thread_id) {
1348 ASSERT_EQ(*ui_thread_id, std::this_thread::get_id());
1352 FlutterWindowsEngineBuilder builder{GetContext()};
1353 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1354 auto window_binding_handler =
1355 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1356 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1358 EngineModifier modifier(engine.get());
1359 modifier.SetImplicitView(&view);
1361 FlutterViewFocusChangeRequest request;
1364 EXPECT_CALL(view, Focus()).WillOnce(Return(
true));
1365 modifier.OnViewFocusChangeRequest(&request);