7 #include "flutter/fml/logging.h"
8 #include "flutter/fml/macros.h"
9 #include "flutter/shell/platform/embedder/embedder.h"
10 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
13 #include "flutter/shell/platform/windows/testing/egl/mock_manager.h"
14 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
15 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
16 #include "flutter/shell/platform/windows/testing/mock_platform_view_manager.h"
17 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
18 #include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
19 #include "flutter/shell/platform/windows/testing/test_keyboard.h"
20 #include "flutter/shell/platform/windows/testing/windows_test.h"
21 #include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
22 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h"
23 #include "fml/synchronization/waitable_event.h"
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
33 using ::testing::NiceMock;
34 using ::testing::Return;
40 FlutterWindowsEngineBuilder builder{GetContext()};
41 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
43 EngineModifier modifier(engine.get());
44 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
46 ASSERT_TRUE(engine->Run());
48 ASSERT_EQ(engine->view(123),
nullptr);
52 FlutterWindowsEngineBuilder builder{GetContext()};
53 builder.AddDartEntrypointArgument(
"arg1");
54 builder.AddDartEntrypointArgument(
"arg2");
56 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
57 EngineModifier modifier(engine.get());
60 bool run_called =
false;
61 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
62 Run, ([&run_called, engine_instance = engine.get()](
63 size_t version,
const FlutterRendererConfig* config,
64 const FlutterProjectArgs* args,
void*
user_data,
67 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
69 EXPECT_EQ(version, FLUTTER_ENGINE_VERSION);
70 EXPECT_NE(config,
nullptr);
72 EXPECT_EQ(config->type, kOpenGL);
75 EXPECT_NE(args->assets_path,
nullptr);
76 EXPECT_NE(args->icu_data_path,
nullptr);
77 EXPECT_EQ(args->dart_entrypoint_argc, 2U);
78 EXPECT_EQ(strcmp(args->dart_entrypoint_argv[0],
"arg1"), 0);
79 EXPECT_EQ(strcmp(args->dart_entrypoint_argv[1],
"arg2"), 0);
80 EXPECT_NE(args->platform_message_callback,
nullptr);
81 EXPECT_NE(args->custom_task_runners,
nullptr);
82 EXPECT_NE(args->custom_task_runners->thread_priority_setter,
nullptr);
83 EXPECT_EQ(args->custom_dart_entrypoint,
nullptr);
84 EXPECT_NE(args->vsync_callback,
nullptr);
85 EXPECT_EQ(args->update_semantics_callback,
nullptr);
86 EXPECT_NE(args->update_semantics_callback2,
nullptr);
87 EXPECT_EQ(args->update_semantics_node_callback,
nullptr);
88 EXPECT_EQ(args->update_semantics_custom_action_callback,
nullptr);
90 args->custom_task_runners->thread_priority_setter(
91 FlutterThreadPriority::kRaster);
92 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
93 THREAD_PRIORITY_ABOVE_NORMAL);
97 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
98 UpdateAccessibilityFeatures,
100 FlutterAccessibilityFeature flags) {
return kSuccess; });
103 bool update_locales_called =
false;
104 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
106 ([&update_locales_called](
auto engine,
const FlutterLocale** locales,
107 size_t locales_count) {
108 update_locales_called =
true;
110 EXPECT_GT(locales_count, 0);
111 EXPECT_NE(locales,
nullptr);
117 bool settings_message_sent =
false;
118 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
120 ([&settings_message_sent](
auto engine,
auto message) {
121 if (std::string(
message->channel) == std::string(
"flutter/settings")) {
122 settings_message_sent = true;
129 bool notify_display_update_called =
false;
130 modifier.SetFrameInterval(16600000);
131 modifier.embedder_api().NotifyDisplayUpdate = MOCK_ENGINE_PROC(
133 ([¬ify_display_update_called, engine_instance = engine.get()](
135 const FlutterEngineDisplaysUpdateType update_type,
136 const FlutterEngineDisplay* embedder_displays,
137 size_t display_count) {
138 EXPECT_EQ(update_type, kFlutterEngineDisplaysUpdateTypeStartup);
139 EXPECT_EQ(display_count, 1);
141 FlutterEngineDisplay display = embedder_displays[0];
143 EXPECT_EQ(display.display_id, 0);
144 EXPECT_EQ(display.single_display,
true);
145 EXPECT_EQ(std::floor(display.refresh_rate), 60.0);
147 notify_display_update_called =
true;
152 modifier.SetEGLManager(std::make_unique<egl::MockManager>());
156 EXPECT_TRUE(run_called);
157 EXPECT_TRUE(update_locales_called);
158 EXPECT_TRUE(settings_message_sent);
159 EXPECT_TRUE(notify_display_update_called);
163 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
164 modifier.ReleaseEGLManager();
168 FlutterWindowsEngineBuilder builder{GetContext()};
169 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
170 EngineModifier modifier(engine.get());
171 bool on_vsync_called =
false;
173 modifier.embedder_api().GetCurrentTime =
174 MOCK_ENGINE_PROC(GetCurrentTime, ([]() -> uint64_t {
return 1; }));
175 modifier.embedder_api().OnVsync = MOCK_ENGINE_PROC(
177 ([&on_vsync_called, engine_instance = engine.get()](
179 uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos) {
181 EXPECT_EQ(frame_start_time_nanos, 16600000);
182 EXPECT_EQ(frame_target_time_nanos, 33200000);
183 on_vsync_called =
true;
186 modifier.SetStartTime(0);
187 modifier.SetFrameInterval(16600000);
191 EXPECT_TRUE(on_vsync_called);
195 FlutterWindowsEngineBuilder builder{GetContext()};
196 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
197 EngineModifier modifier(engine.get());
199 modifier.embedder_api().NotifyDisplayUpdate =
200 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
201 ([engine_instance = engine.get()](
203 const FlutterEngineDisplaysUpdateType update_type,
204 const FlutterEngineDisplay* embedder_displays,
205 size_t display_count) {
return kSuccess; }));
208 bool run_called =
false;
209 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
210 Run, ([&run_called, engine_instance = engine.get()](
211 size_t version,
const FlutterRendererConfig* config,
212 const FlutterProjectArgs* args,
void*
user_data,
215 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
217 EXPECT_EQ(config->type, kSoftware);
221 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
222 UpdateAccessibilityFeatures,
224 FlutterAccessibilityFeature flags) {
return kSuccess; });
228 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
229 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
230 size_t locales_count) {
return kSuccess; }));
231 modifier.embedder_api().SendPlatformMessage =
232 MOCK_ENGINE_PROC(SendPlatformMessage,
233 ([](
auto engine,
auto message) {
return kSuccess; }));
236 modifier.SetEGLManager(
nullptr);
240 EXPECT_TRUE(run_called);
244 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
248 FlutterWindowsEngineBuilder builder{GetContext()};
249 builder.SetSwitches({
"--enable-impeller=true"});
250 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
251 EngineModifier modifier(engine.get());
253 modifier.embedder_api().NotifyDisplayUpdate =
254 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
255 ([engine_instance = engine.get()](
257 const FlutterEngineDisplaysUpdateType update_type,
258 const FlutterEngineDisplay* embedder_displays,
259 size_t display_count) {
return kSuccess; }));
262 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
263 UpdateAccessibilityFeatures,
265 FlutterAccessibilityFeature flags) {
return kSuccess; });
269 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
270 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
271 size_t locales_count) {
return kSuccess; }));
272 modifier.embedder_api().SendPlatformMessage =
273 MOCK_ENGINE_PROC(SendPlatformMessage,
274 ([](
auto engine,
auto message) {
return kSuccess; }));
277 modifier.SetEGLManager(
nullptr);
279 EXPECT_FALSE(engine->
Run());
283 FlutterWindowsEngineBuilder builder{GetContext()};
284 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
285 EngineModifier modifier(engine.get());
287 const char* channel =
"test";
288 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
292 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
293 SendPlatformMessage, ([&called, test_message](
auto engine,
auto message) {
295 EXPECT_STREQ(
message->channel,
"test");
296 EXPECT_EQ(
message->message_size, test_message.size());
297 EXPECT_EQ(memcmp(
message->message, test_message.data(),
300 EXPECT_EQ(
message->response_handle,
nullptr);
304 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
310 FlutterWindowsEngineBuilder builder{GetContext()};
311 builder.SetDartEntrypoint(
"hiPlatformChannels");
313 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
314 EngineModifier modifier(engine.get());
315 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
317 auto binary_messenger =
318 std::make_unique<BinaryMessengerImpl>(engine->messenger());
321 bool did_call_callback =
false;
322 bool did_call_reply =
false;
323 bool did_call_dart_reply =
false;
324 std::string channel =
"hi";
325 binary_messenger->SetMessageHandler(
327 [&did_call_callback, &did_call_dart_reply](
329 if (message_size == 5) {
330 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
331 char response[] = {
'b',
'y',
'e'};
332 reply(
reinterpret_cast<uint8_t*
>(response), 3);
333 did_call_callback =
true;
335 EXPECT_EQ(message_size, 3);
336 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
337 did_call_dart_reply =
true;
340 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
341 binary_messenger->Send(
342 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
343 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
344 EXPECT_EQ(reply_size, 5);
345 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
346 did_call_reply =
true;
349 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
350 engine->task_runner()->ProcessTasks();
355 FlutterWindowsEngineBuilder builder{GetContext()};
356 builder.SetDartEntrypoint(
"hiPlatformChannels");
358 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
360 EngineModifier modifier(engine.get());
361 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
363 auto binary_messenger =
364 std::make_unique<BinaryMessengerImpl>(engine->messenger());
367 bool did_call_callback =
false;
368 bool did_call_reply =
false;
369 bool did_call_dart_reply =
false;
370 std::string channel =
"hi";
371 std::unique_ptr<std::thread> reply_thread;
372 binary_messenger->SetMessageHandler(
374 [&did_call_callback, &did_call_dart_reply, &reply_thread](
376 if (message_size == 5) {
377 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
378 reply_thread.reset(
new std::thread([reply = std::move(reply)]() {
379 char response[] = {
'b',
'y',
'e'};
380 reply(
reinterpret_cast<uint8_t*
>(response), 3);
382 did_call_callback =
true;
384 EXPECT_EQ(message_size, 3);
385 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
386 did_call_dart_reply =
true;
389 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
390 binary_messenger->Send(
391 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
392 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
393 EXPECT_EQ(reply_size, 5);
394 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
395 did_call_reply =
true;
398 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
399 engine->task_runner()->ProcessTasks();
401 ASSERT_TRUE(reply_thread);
402 reply_thread->join();
406 FlutterWindowsEngineBuilder builder{GetContext()};
407 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
408 EngineModifier modifier(engine.get());
410 const char* channel =
"test";
411 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
412 auto* dummy_response_handle =
413 reinterpret_cast<FlutterPlatformMessageResponseHandle*
>(5);
415 void* reply_user_data =
reinterpret_cast<void*
>(6);
419 bool create_response_handle_called =
false;
420 modifier.embedder_api().PlatformMessageCreateResponseHandle =
422 PlatformMessageCreateResponseHandle,
423 ([&create_response_handle_called, &reply_handler, reply_user_data,
424 dummy_response_handle](
auto engine,
auto reply,
auto user_data,
425 auto response_handle) {
426 create_response_handle_called =
true;
427 EXPECT_EQ(reply, reply_handler);
429 EXPECT_NE(response_handle,
nullptr);
430 *response_handle = dummy_response_handle;
433 bool release_response_handle_called =
false;
434 modifier.embedder_api().PlatformMessageReleaseResponseHandle =
436 PlatformMessageReleaseResponseHandle,
437 ([&release_response_handle_called, dummy_response_handle](
438 auto engine,
auto response_handle) {
439 release_response_handle_called =
true;
440 EXPECT_EQ(response_handle, dummy_response_handle);
443 bool send_message_called =
false;
444 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
445 SendPlatformMessage, ([&send_message_called, test_message,
446 dummy_response_handle](
auto engine,
auto message) {
447 send_message_called =
true;
448 EXPECT_STREQ(
message->channel,
"test");
449 EXPECT_EQ(
message->message_size, test_message.size());
450 EXPECT_EQ(memcmp(
message->message, test_message.data(),
453 EXPECT_EQ(
message->response_handle, dummy_response_handle);
457 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
458 reply_handler, reply_user_data);
459 EXPECT_TRUE(create_response_handle_called);
460 EXPECT_TRUE(release_response_handle_called);
461 EXPECT_TRUE(send_message_called);
465 FlutterWindowsEngineBuilder builder{GetContext()};
466 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
467 EngineModifier modifier(engine.get());
471 modifier.embedder_api().DispatchSemanticsAction = MOCK_ENGINE_PROC(
472 DispatchSemanticsAction,
473 ([&called, &
message](
auto engine,
auto target,
auto action,
auto data,
476 EXPECT_EQ(target, 42);
477 EXPECT_EQ(
action, kFlutterSemanticsActionDismiss);
479 EXPECT_EQ(data_length,
message.size());
483 auto data = fml::MallocMapping::Copy(
message.c_str(),
message.size());
484 engine->DispatchSemanticsAction(42, kFlutterSemanticsActionDismiss,
491 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
492 THREAD_PRIORITY_BELOW_NORMAL);
495 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
496 THREAD_PRIORITY_ABOVE_NORMAL);
499 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
500 THREAD_PRIORITY_ABOVE_NORMAL);
504 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
507 EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
511 FlutterWindowsEngineBuilder builder{GetContext()};
512 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
513 EngineModifier modifier(engine.get());
515 MockEmbedderApiForKeyboard(modifier,
516 std::make_shared<MockKeyResponseController>());
523 engine->AddPluginRegistrarDestructionCallback(
525 auto result =
reinterpret_cast<int*
>(ref);
529 engine->AddPluginRegistrarDestructionCallback(
531 auto result =
reinterpret_cast<int*
>(ref);
537 EXPECT_EQ(result1, 1);
538 EXPECT_EQ(result2, 2);
542 FlutterWindowsEngineBuilder builder{GetContext()};
543 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
544 EngineModifier modifier(engine.get());
547 modifier.embedder_api().ScheduleFrame =
548 MOCK_ENGINE_PROC(ScheduleFrame, ([&called](
auto engine) {
553 engine->ScheduleFrame();
558 FlutterWindowsEngineBuilder builder{GetContext()};
559 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
560 EngineModifier modifier(engine.get());
563 modifier.embedder_api().SetNextFrameCallback = MOCK_ENGINE_PROC(
564 SetNextFrameCallback, ([&called](
auto engine,
auto callback,
auto data) {
569 engine->SetNextFrameCallback([]() {});
574 FlutterWindowsEngineBuilder builder{GetContext()};
575 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
576 EXPECT_EQ(engine->GetExecutableName(),
"flutter_windows_unittests.exe");
582 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
583 EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
584 .WillOnce(Return(
true))
585 .WillOnce(Return(
false));
587 FlutterWindowsEngineBuilder builder{GetContext()};
588 builder.SetWindowsProcTable(windows_proc_table);
589 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
590 EngineModifier modifier(engine.get());
592 std::optional<FlutterAccessibilityFeature> engine_flags;
593 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
594 UpdateAccessibilityFeatures, ([&engine_flags](
auto engine,
auto flags) {
595 engine_flags = flags;
598 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
600 [](
auto engine,
const auto message) {
return kSuccess; });
603 engine->UpdateHighContrastMode();
605 EXPECT_TRUE(engine->high_contrast_enabled());
606 EXPECT_TRUE(engine_flags.has_value());
608 engine_flags.value() &
609 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
612 engine_flags.reset();
613 engine->UpdateHighContrastMode();
615 EXPECT_FALSE(engine->high_contrast_enabled());
616 EXPECT_TRUE(engine_flags.has_value());
618 engine_flags.value() &
619 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
623 FlutterWindowsEngineBuilder builder{GetContext()};
624 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
625 EngineModifier modifier(engine.get());
627 modifier.embedder_api().PostRenderThreadTask = MOCK_ENGINE_PROC(
628 PostRenderThreadTask, ([](
auto engine,
auto callback,
auto context) {
634 engine->PostRasterThreadTask([&called]() { called =
true; });
642 std::unique_ptr<WindowBindingHandler> wbh)
647 NotifyWinEventWrapper,
648 (ui::AXPlatformNodeWin*, ax::mojom::Event),
650 MOCK_METHOD(HWND, GetWindowHandle, (), (
const,
override));
653 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
658 auto& context = GetContext();
659 WindowsConfigBuilder builder{context};
660 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
664 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
665 context.AddNativeFunction(
"Signal", native_entry);
667 EnginePtr engine{builder.RunHeadless()};
668 ASSERT_NE(engine,
nullptr);
670 ui::AXPlatformNodeDelegateBase parent_delegate;
673 auto window_binding_handler =
674 std::make_unique<NiceMock<MockWindowBindingHandler>>();
675 EXPECT_CALL(*window_binding_handler, GetAlertDelegate)
676 .WillOnce(Return(&delegate));
679 MockFlutterWindowsView view{windows_engine,
680 std::move(window_binding_handler)};
681 EngineModifier modifier{windows_engine};
682 modifier.SetImplicitView(&view);
686 EXPECT_CALL(view, NotifyWinEventWrapper).Times(1);
690 windows_engine->task_runner()->ProcessTasks();
696 auto& context = GetContext();
697 WindowsConfigBuilder builder{context};
698 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
702 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
703 context.AddNativeFunction(
"Signal", native_entry);
705 EnginePtr engine{builder.RunHeadless()};
706 ASSERT_NE(engine,
nullptr);
713 windows_engine->task_runner()->ProcessTasks();
720 fml::testing::LogCapture log_capture;
722 auto& context = GetContext();
723 WindowsConfigBuilder builder{context};
724 builder.SetDartEntrypoint(
"sendAccessibilityTooltipEvent");
728 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
729 context.AddNativeFunction(
"Signal", native_entry);
731 ViewControllerPtr controller{builder.Run()};
732 ASSERT_NE(controller,
nullptr);
740 windows_engine->task_runner()->ProcessTasks();
746 EXPECT_EQ(log_capture.str().find(
"tooltip"), std::string::npos);
758 (std::optional<HWND>, std::optional<WPARAM>, std::optional<LPARAM>, UINT),
775 FlutterWindowsEngineBuilder builder{GetContext()};
776 builder.SetDartEntrypoint(
"exitTestExit");
777 bool finished =
false;
779 auto engine = builder.Build();
780 auto window_binding_handler =
781 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
782 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
784 EngineModifier modifier(engine.get());
785 modifier.SetImplicitView(&view);
786 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
787 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
789 EXPECT_CALL(*handler, Quit)
790 .WillOnce([&finished](std::optional<HWND> hwnd,
791 std::optional<WPARAM> wparam,
792 std::optional<LPARAM> lparam,
793 UINT exit_code) { finished = exit_code == 0; });
794 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
795 modifier.SetLifecycleManager(std::move(handler));
797 engine->lifecycle_manager()->BeginProcessingExit();
801 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
807 engine->task_runner()->ProcessTasks();
812 FlutterWindowsEngineBuilder builder{GetContext()};
813 builder.SetDartEntrypoint(
"exitTestCancel");
814 bool did_call =
false;
816 auto engine = builder.Build();
817 auto window_binding_handler =
818 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
819 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
821 EngineModifier modifier(engine.get());
822 modifier.SetImplicitView(&view);
823 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
824 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
826 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
827 EXPECT_CALL(*handler, Quit).Times(0);
828 modifier.SetLifecycleManager(std::move(handler));
829 engine->lifecycle_manager()->BeginProcessingExit();
831 auto binary_messenger =
832 std::make_unique<BinaryMessengerImpl>(engine->messenger());
833 binary_messenger->SetMessageHandler(
834 "flutter/platform", [&did_call](
const uint8_t*
message,
837 EXPECT_NE(contents.find(
"\"method\":\"System.exitApplication\""),
839 EXPECT_NE(contents.find(
"\"type\":\"required\""), std::string::npos);
840 EXPECT_NE(contents.find(
"\"exitCode\":0"), std::string::npos);
842 char response[] =
"";
843 reply(
reinterpret_cast<uint8_t*
>(response), 0);
848 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
852 engine->task_runner()->ProcessTasks();
860 FlutterWindowsEngineBuilder builder{GetContext()};
861 builder.SetDartEntrypoint(
"exitTestExit");
862 bool second_close =
false;
864 auto engine = builder.Build();
865 auto window_binding_handler =
866 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
867 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
869 EngineModifier modifier(engine.get());
870 modifier.SetImplicitView(&view);
871 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
872 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
874 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
true));
875 EXPECT_CALL(*handler, Quit)
876 .WillOnce([handler_ptr = handler.get()](
877 std::optional<HWND> hwnd, std::optional<WPARAM> wparam,
878 std::optional<LPARAM> lparam, UINT exit_code) {
879 handler_ptr->WindowsLifecycleManager::Quit(hwnd, wparam, lparam,
882 EXPECT_CALL(*handler, DispatchMessage)
884 [&engine](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
885 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
886 hwnd, msg, wparam, lparam);
888 modifier.SetLifecycleManager(std::move(handler));
889 engine->lifecycle_manager()->BeginProcessingExit();
897 engine->window_proc_delegate_manager()->RegisterTopLevelWindowProcDelegate(
902 bool* called =
reinterpret_cast<bool*
>(
user_data);
909 reinterpret_cast<void*
>(&second_close));
911 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
914 while (!second_close) {
915 engine->task_runner()->ProcessTasks();
920 FlutterWindowsEngineBuilder builder{GetContext()};
921 builder.SetDartEntrypoint(
"exitTestExit");
922 bool finished =
false;
924 auto engine = builder.Build();
925 auto window_binding_handler =
926 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
927 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
929 EngineModifier modifier(engine.get());
930 modifier.SetImplicitView(&view);
931 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
932 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
934 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce([&finished]() {
939 EXPECT_CALL(*handler, Quit).Times(0);
940 modifier.SetLifecycleManager(std::move(handler));
941 engine->lifecycle_manager()->BeginProcessingExit();
945 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
949 engine->task_runner()->ProcessTasks();
954 FlutterWindowsEngineBuilder builder{GetContext()};
956 auto engine = builder.Build();
957 auto window_binding_handler =
958 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
959 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
961 EngineModifier modifier(engine.get());
962 modifier.SetImplicitView(&view);
963 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
964 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
965 EXPECT_CALL(*handler, IsLastWindowOfProcess).Times(0);
966 modifier.SetLifecycleManager(std::move(handler));
968 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
973 FlutterWindowsEngineBuilder builder{GetContext()};
975 auto engine = builder.Build();
976 auto window_binding_handler =
977 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
978 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
980 EngineModifier modifier(engine.get());
981 modifier.SetImplicitView(&view);
982 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
983 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
984 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
985 modifier.SetLifecycleManager(std::move(handler));
986 engine->lifecycle_manager()->BeginProcessingExit();
988 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
993 FlutterWindowsEngineBuilder builder{GetContext()};
995 auto engine = builder.Build();
996 auto window_binding_handler =
997 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
998 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1000 EngineModifier modifier(engine.get());
1001 modifier.SetImplicitView(&view);
1002 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1003 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1004 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1005 modifier.SetLifecycleManager(std::move(handler));
1006 engine->lifecycle_manager()->BeginProcessingExit();
1008 engine->lifecycle_manager()->ExternalWindowMessage(0, WM_CLOSE, 0, 0);
1012 FlutterWindowsEngineBuilder builder{GetContext()};
1014 auto engine = builder.Build();
1015 auto window_binding_handler =
1016 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1017 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1019 EngineModifier modifier(engine.get());
1020 modifier.SetImplicitView(&view);
1021 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1022 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1025 modifier.SetLifecycleManager(std::move(handler));
1030 FlutterWindowsEngineBuilder builder{GetContext()};
1032 auto engine = builder.Build();
1033 auto window_binding_handler =
1034 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1035 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1037 EngineModifier modifier(engine.get());
1038 modifier.SetImplicitView(&view);
1039 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1042 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1043 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1044 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1047 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1048 (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0);
1049 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1052 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1053 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1054 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1059 FlutterWindowsEngineBuilder builder{GetContext()};
1061 auto engine = builder.Build();
1062 auto window_binding_handler =
1063 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1064 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1066 EngineModifier modifier(engine.get());
1067 modifier.SetImplicitView(&view);
1068 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1073 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1075 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1078 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1083 FlutterWindowsEngineBuilder builder{GetContext()};
1084 HWND outer =
reinterpret_cast<HWND
>(1);
1085 HWND inner =
reinterpret_cast<HWND
>(2);
1087 auto engine = builder.Build();
1088 auto window_binding_handler =
1089 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1090 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1091 ON_CALL(view, GetWindowHandle).WillByDefault([=]() {
return inner; });
1093 EngineModifier modifier(engine.get());
1094 modifier.SetImplicitView(&view);
1095 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1100 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1101 outer, WM_SHOWWINDOW, TRUE, NULL);
1105 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1112 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1117 FlutterWindowsEngineBuilder builder{GetContext()};
1118 builder.SetDartEntrypoint(
"enableLifecycleTest");
1119 bool finished =
false;
1121 auto engine = builder.Build();
1122 auto window_binding_handler =
1123 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1124 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1126 EngineModifier modifier(engine.get());
1127 modifier.SetImplicitView(&view);
1128 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1129 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1130 EXPECT_CALL(*handler, SetLifecycleState)
1132 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1134 modifier.SetLifecycleManager(std::move(handler));
1136 auto binary_messenger =
1137 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1139 binary_messenger->SetMessageHandler(
1140 "flutter/unittest", [&finished](
const uint8_t*
message,
1143 EXPECT_NE(contents.find(
"AppLifecycleState.inactive"),
1146 char response[] =
"";
1147 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1153 HWND hwnd =
reinterpret_cast<HWND
>(1);
1156 EXPECT_FALSE(finished);
1160 engine->lifecycle_manager()->BeginProcessingLifecycle();
1164 engine->task_runner()->ProcessTasks();
1169 FlutterWindowsEngineBuilder builder{GetContext()};
1170 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1171 bool enabled_lifecycle =
false;
1172 bool dart_responded =
false;
1174 auto engine = builder.Build();
1175 auto window_binding_handler =
1176 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1177 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1179 EngineModifier modifier(engine.get());
1180 modifier.SetImplicitView(&view);
1181 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1182 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1183 EXPECT_CALL(*handler, SetLifecycleState)
1185 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1187 handler->begin_processing_callback = [&]() { enabled_lifecycle =
true; };
1188 modifier.SetLifecycleManager(std::move(handler));
1190 auto binary_messenger =
1191 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1192 binary_messenger->SetMessageHandler(
1196 EXPECT_NE(contents.find(
"AppLifecycleState."), std::string::npos);
1197 dart_responded =
true;
1198 char response[] =
"";
1199 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1204 while (!enabled_lifecycle) {
1205 engine->task_runner()->ProcessTasks();
1208 HWND hwnd =
reinterpret_cast<HWND
>(1);
1212 while (!dart_responded) {
1213 engine->task_runner()->ProcessTasks();
1218 FlutterWindowsEngineBuilder builder{GetContext()};
1219 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1221 auto engine = builder.Build();
1222 auto window_binding_handler =
1223 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1224 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1226 EngineModifier modifier(engine.get());
1227 modifier.SetImplicitView(&view);
1228 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1230 bool lifecycle_began =
false;
1231 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1232 EXPECT_CALL(*handler, SetLifecycleState).Times(1);
1233 handler->begin_processing_callback = [&]() { lifecycle_began =
true; };
1234 modifier.SetLifecycleManager(std::move(handler));
1238 while (!lifecycle_began) {
1239 engine->task_runner()->ProcessTasks();
1244 FlutterWindowsEngineBuilder builder{GetContext()};
1245 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1246 auto engine = builder.Build();
1248 EngineModifier modifier{engine.get()};
1249 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1251 bool received_call =
false;
1253 auto manager = std::make_unique<MockPlatformViewManager>(engine.get());
1254 EXPECT_CALL(*manager, AddPlatformView)
1256 received_call =
true;
1259 modifier.SetPlatformViewPlugin(std::move(manager));
1263 while (!received_call) {
1264 engine->task_runner()->ProcessTasks();
1269 FlutterWindowsEngineBuilder builder{GetContext()};
1270 auto engine = builder.Build();
1272 EngineModifier modifier{engine.get()};
1274 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1275 modifier.embedder_api().AddView = MOCK_ENGINE_PROC(
1278 const FlutterAddViewInfo* info) {
return kInternalInconsistency; });
1280 ASSERT_TRUE(engine->
Run());
1284 auto implicit_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1286 std::unique_ptr<FlutterWindowsView> implicit_view =
1287 engine->CreateView(std::move(implicit_window));
1289 EXPECT_TRUE(implicit_view);
1292 auto second_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1294 EXPECT_DEBUG_DEATH(engine->CreateView(std::move(second_window)),
1295 "FlutterEngineAddView returned an unexpected result");
1299 FlutterWindowsEngineBuilder builder{GetContext()};
1300 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1301 auto engine = builder.Build();
1303 EngineModifier modifier{engine.get()};
1305 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1306 modifier.embedder_api().RemoveView = MOCK_ENGINE_PROC(
1309 const FlutterRemoveViewInfo* info) {
return kInternalInconsistency; });
1311 ASSERT_TRUE(engine->
Run());
1312 EXPECT_DEBUG_DEATH(engine->RemoveView(123),
1313 "FlutterEngineRemoveView returned an unexpected result");