7 #include "flutter/fml/macros.h"
8 #include "flutter/shell/platform/embedder/embedder.h"
9 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
12 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
13 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
14 #include "flutter/shell/platform/windows/testing/mock_angle_surface_manager.h"
15 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
16 #include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
17 #include "flutter/shell/platform/windows/testing/test_keyboard.h"
18 #include "flutter/shell/platform/windows/testing/windows_test.h"
19 #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_win.h"
20 #include "fml/synchronization/waitable_event.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
30 using ::testing::Return;
35 FlutterWindowsEngineBuilder builder{GetContext()};
36 builder.AddDartEntrypointArgument(
"arg1");
37 builder.AddDartEntrypointArgument(
"arg2");
39 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
40 EngineModifier modifier(engine.get());
43 bool run_called =
false;
44 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
45 Run, ([&run_called, engine_instance = engine.get()](
46 size_t version,
const FlutterRendererConfig* config,
47 const FlutterProjectArgs* args,
void*
user_data,
50 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
52 EXPECT_EQ(version, FLUTTER_ENGINE_VERSION);
53 EXPECT_NE(config,
nullptr);
55 EXPECT_EQ(config->type, kOpenGL);
58 EXPECT_NE(args->assets_path,
nullptr);
59 EXPECT_NE(args->icu_data_path,
nullptr);
60 EXPECT_EQ(args->dart_entrypoint_argc, 2U);
61 EXPECT_EQ(strcmp(args->dart_entrypoint_argv[0],
"arg1"), 0);
62 EXPECT_EQ(strcmp(args->dart_entrypoint_argv[1],
"arg2"), 0);
63 EXPECT_NE(args->platform_message_callback,
nullptr);
64 EXPECT_NE(args->custom_task_runners,
nullptr);
65 EXPECT_NE(args->custom_task_runners->thread_priority_setter,
nullptr);
66 EXPECT_EQ(args->custom_dart_entrypoint,
nullptr);
67 EXPECT_NE(args->vsync_callback,
nullptr);
68 EXPECT_EQ(args->update_semantics_callback,
nullptr);
69 EXPECT_NE(args->update_semantics_callback2,
nullptr);
70 EXPECT_EQ(args->update_semantics_node_callback,
nullptr);
71 EXPECT_EQ(args->update_semantics_custom_action_callback,
nullptr);
73 args->custom_task_runners->thread_priority_setter(
74 FlutterThreadPriority::kRaster);
75 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
76 THREAD_PRIORITY_ABOVE_NORMAL);
80 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
81 UpdateAccessibilityFeatures,
83 FlutterAccessibilityFeature flags) {
return kSuccess; });
86 bool update_locales_called =
false;
87 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
89 ([&update_locales_called](
auto engine,
const FlutterLocale** locales,
90 size_t locales_count) {
91 update_locales_called =
true;
93 EXPECT_GT(locales_count, 0);
94 EXPECT_NE(locales,
nullptr);
100 bool settings_message_sent =
false;
101 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
103 ([&settings_message_sent](
auto engine,
auto message) {
104 if (std::string(
message->channel) == std::string(
"flutter/settings")) {
105 settings_message_sent = true;
112 bool notify_display_update_called =
false;
113 modifier.SetFrameInterval(16600000);
114 modifier.embedder_api().NotifyDisplayUpdate = MOCK_ENGINE_PROC(
116 ([¬ify_display_update_called, engine_instance = engine.get()](
118 const FlutterEngineDisplaysUpdateType update_type,
119 const FlutterEngineDisplay* embedder_displays,
120 size_t display_count) {
121 EXPECT_EQ(update_type, kFlutterEngineDisplaysUpdateTypeStartup);
122 EXPECT_EQ(display_count, 1);
124 FlutterEngineDisplay display = embedder_displays[0];
126 EXPECT_EQ(display.display_id, 0);
127 EXPECT_EQ(display.single_display,
true);
128 EXPECT_EQ(std::floor(display.refresh_rate), 60.0);
130 notify_display_update_called =
true;
135 modifier.SetSurfaceManager(std::make_unique<MockAngleSurfaceManager>());
139 EXPECT_TRUE(run_called);
140 EXPECT_TRUE(update_locales_called);
141 EXPECT_TRUE(settings_message_sent);
142 EXPECT_TRUE(notify_display_update_called);
146 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
147 modifier.ReleaseSurfaceManager();
151 FlutterWindowsEngineBuilder builder{GetContext()};
152 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
153 EngineModifier modifier(engine.get());
154 bool on_vsync_called =
false;
156 modifier.embedder_api().GetCurrentTime =
157 MOCK_ENGINE_PROC(GetCurrentTime, ([]() -> uint64_t {
return 1; }));
158 modifier.embedder_api().OnVsync = MOCK_ENGINE_PROC(
160 ([&on_vsync_called, engine_instance = engine.get()](
162 uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos) {
164 EXPECT_EQ(frame_start_time_nanos, 16600000);
165 EXPECT_EQ(frame_target_time_nanos, 33200000);
166 on_vsync_called =
true;
169 modifier.SetStartTime(0);
170 modifier.SetFrameInterval(16600000);
174 EXPECT_TRUE(on_vsync_called);
178 FlutterWindowsEngineBuilder builder{GetContext()};
179 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
180 EngineModifier modifier(engine.get());
182 modifier.embedder_api().NotifyDisplayUpdate =
183 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
184 ([engine_instance = engine.get()](
186 const FlutterEngineDisplaysUpdateType update_type,
187 const FlutterEngineDisplay* embedder_displays,
188 size_t display_count) {
return kSuccess; }));
191 bool run_called =
false;
192 modifier.embedder_api().Run = MOCK_ENGINE_PROC(
193 Run, ([&run_called, engine_instance = engine.get()](
194 size_t version,
const FlutterRendererConfig* config,
195 const FlutterProjectArgs* args,
void*
user_data,
198 *engine_out =
reinterpret_cast<FLUTTER_API_SYMBOL(
FlutterEngine)
>(1);
200 EXPECT_EQ(config->type, kSoftware);
204 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
205 UpdateAccessibilityFeatures,
207 FlutterAccessibilityFeature flags) {
return kSuccess; });
211 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
212 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
213 size_t locales_count) {
return kSuccess; }));
214 modifier.embedder_api().SendPlatformMessage =
215 MOCK_ENGINE_PROC(SendPlatformMessage,
216 ([](
auto engine,
auto message) {
return kSuccess; }));
219 modifier.SetSurfaceManager(
nullptr);
223 EXPECT_TRUE(run_called);
227 modifier.embedder_api().Shutdown = [](
auto engine) {
return kSuccess; };
231 FlutterWindowsEngineBuilder builder{GetContext()};
232 builder.SetSwitches({
"--enable-impeller=true"});
233 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
234 EngineModifier modifier(engine.get());
236 modifier.embedder_api().NotifyDisplayUpdate =
237 MOCK_ENGINE_PROC(NotifyDisplayUpdate,
238 ([engine_instance = engine.get()](
240 const FlutterEngineDisplaysUpdateType update_type,
241 const FlutterEngineDisplay* embedder_displays,
242 size_t display_count) {
return kSuccess; }));
245 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
246 UpdateAccessibilityFeatures,
248 FlutterAccessibilityFeature flags) {
return kSuccess; });
252 modifier.embedder_api().UpdateLocales = MOCK_ENGINE_PROC(
253 UpdateLocales, ([](
auto engine,
const FlutterLocale** locales,
254 size_t locales_count) {
return kSuccess; }));
255 modifier.embedder_api().SendPlatformMessage =
256 MOCK_ENGINE_PROC(SendPlatformMessage,
257 ([](
auto engine,
auto message) {
return kSuccess; }));
260 modifier.SetSurfaceManager(
nullptr);
262 EXPECT_FALSE(engine->
Run());
266 FlutterWindowsEngineBuilder builder{GetContext()};
267 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
268 EngineModifier modifier(engine.get());
270 const char* channel =
"test";
271 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
275 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
276 SendPlatformMessage, ([&called, test_message](
auto engine,
auto message) {
278 EXPECT_STREQ(
message->channel,
"test");
279 EXPECT_EQ(
message->message_size, test_message.size());
280 EXPECT_EQ(memcmp(
message->message, test_message.data(),
283 EXPECT_EQ(
message->response_handle,
nullptr);
287 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
293 FlutterWindowsEngineBuilder builder{GetContext()};
294 builder.SetDartEntrypoint(
"hiPlatformChannels");
296 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
297 EngineModifier modifier(engine.get());
298 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
300 auto binary_messenger =
301 std::make_unique<BinaryMessengerImpl>(engine->messenger());
304 bool did_call_callback =
false;
305 bool did_call_reply =
false;
306 bool did_call_dart_reply =
false;
307 std::string channel =
"hi";
308 binary_messenger->SetMessageHandler(
310 [&did_call_callback, &did_call_dart_reply](
312 if (message_size == 5) {
313 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
314 char response[] = {
'b',
'y',
'e'};
315 reply(
reinterpret_cast<uint8_t*
>(response), 3);
316 did_call_callback =
true;
318 EXPECT_EQ(message_size, 3);
319 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
320 did_call_dart_reply =
true;
323 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
324 binary_messenger->Send(
325 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
326 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
327 EXPECT_EQ(reply_size, 5);
328 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
329 did_call_reply =
true;
332 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
333 engine->task_runner()->ProcessTasks();
338 FlutterWindowsEngineBuilder builder{GetContext()};
339 builder.SetDartEntrypoint(
"hiPlatformChannels");
341 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
343 EngineModifier modifier(engine.get());
344 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
346 auto binary_messenger =
347 std::make_unique<BinaryMessengerImpl>(engine->messenger());
350 bool did_call_callback =
false;
351 bool did_call_reply =
false;
352 bool did_call_dart_reply =
false;
353 std::string channel =
"hi";
354 std::unique_ptr<std::thread> reply_thread;
355 binary_messenger->SetMessageHandler(
357 [&did_call_callback, &did_call_dart_reply, &reply_thread](
359 if (message_size == 5) {
360 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'h'));
361 reply_thread.reset(
new std::thread([reply = std::move(reply)]() {
362 char response[] = {
'b',
'y',
'e'};
363 reply(
reinterpret_cast<uint8_t*
>(response), 3);
365 did_call_callback =
true;
367 EXPECT_EQ(message_size, 3);
368 EXPECT_EQ(
message[0],
static_cast<uint8_t
>(
'b'));
369 did_call_dart_reply =
true;
372 char payload[] = {
'h',
'e',
'l',
'l',
'o'};
373 binary_messenger->Send(
374 channel,
reinterpret_cast<uint8_t*
>(payload), 5,
375 [&did_call_reply](
const uint8_t* reply,
size_t reply_size) {
376 EXPECT_EQ(reply_size, 5);
377 EXPECT_EQ(reply[0],
static_cast<uint8_t
>(
'h'));
378 did_call_reply =
true;
381 while (!did_call_callback || !did_call_reply || !did_call_dart_reply) {
382 engine->task_runner()->ProcessTasks();
384 ASSERT_TRUE(reply_thread);
385 reply_thread->join();
389 FlutterWindowsEngineBuilder builder{GetContext()};
390 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
391 EngineModifier modifier(engine.get());
393 const char* channel =
"test";
394 const std::vector<uint8_t> test_message = {1, 2, 3, 4};
395 auto* dummy_response_handle =
396 reinterpret_cast<FlutterPlatformMessageResponseHandle*
>(5);
398 void* reply_user_data =
reinterpret_cast<void*
>(6);
402 bool create_response_handle_called =
false;
403 modifier.embedder_api().PlatformMessageCreateResponseHandle =
405 PlatformMessageCreateResponseHandle,
406 ([&create_response_handle_called, &reply_handler, reply_user_data,
407 dummy_response_handle](
auto engine,
auto reply,
auto user_data,
408 auto response_handle) {
409 create_response_handle_called =
true;
410 EXPECT_EQ(reply, reply_handler);
412 EXPECT_NE(response_handle,
nullptr);
413 *response_handle = dummy_response_handle;
416 bool release_response_handle_called =
false;
417 modifier.embedder_api().PlatformMessageReleaseResponseHandle =
419 PlatformMessageReleaseResponseHandle,
420 ([&release_response_handle_called, dummy_response_handle](
421 auto engine,
auto response_handle) {
422 release_response_handle_called =
true;
423 EXPECT_EQ(response_handle, dummy_response_handle);
426 bool send_message_called =
false;
427 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
428 SendPlatformMessage, ([&send_message_called, test_message,
429 dummy_response_handle](
auto engine,
auto message) {
430 send_message_called =
true;
431 EXPECT_STREQ(
message->channel,
"test");
432 EXPECT_EQ(
message->message_size, test_message.size());
433 EXPECT_EQ(memcmp(
message->message, test_message.data(),
436 EXPECT_EQ(
message->response_handle, dummy_response_handle);
440 engine->SendPlatformMessage(channel, test_message.data(), test_message.size(),
441 reply_handler, reply_user_data);
442 EXPECT_TRUE(create_response_handle_called);
443 EXPECT_TRUE(release_response_handle_called);
444 EXPECT_TRUE(send_message_called);
448 FlutterWindowsEngineBuilder builder{GetContext()};
449 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
450 EngineModifier modifier(engine.get());
454 modifier.embedder_api().DispatchSemanticsAction = MOCK_ENGINE_PROC(
455 DispatchSemanticsAction,
456 ([&called, &
message](
auto engine,
auto target,
auto action,
auto data,
459 EXPECT_EQ(target, 42);
460 EXPECT_EQ(
action, kFlutterSemanticsActionDismiss);
462 EXPECT_EQ(data_length,
message.size());
466 auto data = fml::MallocMapping::Copy(
message.c_str(),
message.size());
467 engine->DispatchSemanticsAction(42, kFlutterSemanticsActionDismiss,
474 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
475 THREAD_PRIORITY_BELOW_NORMAL);
478 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
479 THREAD_PRIORITY_ABOVE_NORMAL);
482 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
483 THREAD_PRIORITY_ABOVE_NORMAL);
487 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
490 EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
494 FlutterWindowsEngineBuilder builder{GetContext()};
495 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
496 EngineModifier modifier(engine.get());
498 MockEmbedderApiForKeyboard(modifier,
499 std::make_shared<MockKeyResponseController>());
506 engine->AddPluginRegistrarDestructionCallback(
508 auto result =
reinterpret_cast<int*
>(ref);
512 engine->AddPluginRegistrarDestructionCallback(
514 auto result =
reinterpret_cast<int*
>(ref);
520 EXPECT_EQ(result1, 1);
521 EXPECT_EQ(result2, 2);
525 FlutterWindowsEngineBuilder builder{GetContext()};
526 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
527 EngineModifier modifier(engine.get());
530 modifier.embedder_api().ScheduleFrame =
531 MOCK_ENGINE_PROC(ScheduleFrame, ([&called](
auto engine) {
536 engine->ScheduleFrame();
541 FlutterWindowsEngineBuilder builder{GetContext()};
542 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
543 EngineModifier modifier(engine.get());
546 modifier.embedder_api().SetNextFrameCallback = MOCK_ENGINE_PROC(
547 SetNextFrameCallback, ([&called](
auto engine,
auto callback,
auto data) {
552 engine->SetNextFrameCallback([]() {});
557 FlutterWindowsEngineBuilder builder{GetContext()};
558 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
559 EXPECT_EQ(engine->GetExecutableName(),
"flutter_windows_unittests.exe");
565 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
566 EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
567 .WillOnce(Return(
true))
568 .WillOnce(Return(
false));
570 FlutterWindowsEngineBuilder builder{GetContext()};
571 builder.SetWindowsProcTable(windows_proc_table);
572 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
573 EngineModifier modifier(engine.get());
575 std::optional<FlutterAccessibilityFeature> engine_flags;
576 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
577 UpdateAccessibilityFeatures, ([&engine_flags](
auto engine,
auto flags) {
578 engine_flags = flags;
583 engine->UpdateHighContrastMode();
585 EXPECT_TRUE(engine->high_contrast_enabled());
586 EXPECT_TRUE(engine_flags.has_value());
588 engine_flags.value() &
589 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
592 engine_flags.reset();
593 engine->UpdateHighContrastMode();
595 EXPECT_FALSE(engine->high_contrast_enabled());
596 EXPECT_TRUE(engine_flags.has_value());
598 engine_flags.value() &
599 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
603 FlutterWindowsEngineBuilder builder{GetContext()};
604 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
605 EngineModifier modifier(engine.get());
607 modifier.embedder_api().PostRenderThreadTask = MOCK_ENGINE_PROC(
608 PostRenderThreadTask, ([](
auto engine,
auto callback,
auto context) {
614 engine->PostRasterThreadTask([&called]() { called =
true; });
626 NotifyWinEventWrapper,
627 (ui::AXPlatformNodeWin*, ax::mojom::Event),
629 MOCK_METHOD(HWND, GetWindowHandle, (), (
const,
override));
632 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
636 FlutterWindowsEngineBuilder builder{GetContext()};
637 builder.SetDartEntrypoint(
"alertPlatformChannel");
639 auto engine = builder.Build();
640 auto window_binding_handler =
641 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
642 ui::AXPlatformNodeDelegateBase parent_delegate;
644 EXPECT_CALL(*window_binding_handler, GetAlertDelegate)
645 .WillRepeatedly(Return(&delegate));
646 MockFlutterWindowsView view(std::move(window_binding_handler));
647 view.SetEngine(engine.get());
649 EngineModifier modifier(engine.get());
650 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
652 auto binary_messenger =
653 std::make_unique<BinaryMessengerImpl>(engine->messenger());
654 binary_messenger->SetMessageHandler(
655 "semantics", [&engine](
const uint8_t*
message,
size_t message_size,
657 engine->UpdateSemanticsEnabled(
true);
658 char response[] =
"";
659 reply(
reinterpret_cast<uint8_t*
>(response), 0);
662 bool did_call =
false;
663 EXPECT_CALL(view, NotifyWinEventWrapper)
664 .WillOnce([&did_call](ui::AXPlatformNodeWin* node,
665 ax::mojom::Event event) { did_call =
true; });
667 engine->UpdateSemanticsEnabled(
true);
672 engine->task_runner()->ProcessTasks();
685 (std::optional<HWND>, std::optional<WPARAM>, std::optional<LPARAM>, UINT),
702 FlutterWindowsEngineBuilder builder{GetContext()};
703 builder.SetDartEntrypoint(
"exitTestExit");
704 bool finished =
false;
706 auto engine = builder.Build();
707 auto window_binding_handler =
708 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
709 MockFlutterWindowsView view(std::move(window_binding_handler));
710 view.SetEngine(engine.get());
712 EngineModifier modifier(engine.get());
713 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
714 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
716 EXPECT_CALL(*handler, Quit)
717 .WillOnce([&finished](std::optional<HWND> hwnd,
718 std::optional<WPARAM> wparam,
719 std::optional<LPARAM> lparam,
720 UINT exit_code) { finished = exit_code == 0; });
721 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
722 modifier.SetLifecycleManager(std::move(handler));
724 engine->lifecycle_manager()->BeginProcessingExit();
728 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
734 engine->task_runner()->ProcessTasks();
739 FlutterWindowsEngineBuilder builder{GetContext()};
740 builder.SetDartEntrypoint(
"exitTestCancel");
741 bool did_call =
false;
743 auto engine = builder.Build();
744 auto window_binding_handler =
745 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
746 MockFlutterWindowsView view(std::move(window_binding_handler));
747 view.SetEngine(engine.get());
749 EngineModifier modifier(engine.get());
750 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
751 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
753 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
754 EXPECT_CALL(*handler, Quit).Times(0);
755 modifier.SetLifecycleManager(std::move(handler));
756 engine->lifecycle_manager()->BeginProcessingExit();
758 auto binary_messenger =
759 std::make_unique<BinaryMessengerImpl>(engine->messenger());
760 binary_messenger->SetMessageHandler(
761 "flutter/platform", [&did_call](
const uint8_t*
message,
764 EXPECT_NE(contents.find(
"\"method\":\"System.exitApplication\""),
766 EXPECT_NE(contents.find(
"\"type\":\"required\""), std::string::npos);
767 EXPECT_NE(contents.find(
"\"exitCode\":0"), std::string::npos);
769 char response[] =
"";
770 reply(
reinterpret_cast<uint8_t*
>(response), 0);
775 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
779 engine->task_runner()->ProcessTasks();
787 FlutterWindowsEngineBuilder builder{GetContext()};
788 builder.SetDartEntrypoint(
"exitTestExit");
789 bool second_close =
false;
791 auto engine = builder.Build();
792 auto window_binding_handler =
793 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
794 MockFlutterWindowsView view(std::move(window_binding_handler));
795 view.SetEngine(engine.get());
797 EngineModifier modifier(engine.get());
798 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
799 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
803 ON_CALL(*handler, IsLastWindowOfProcess).WillByDefault(Return(
true));
804 ON_CALL(*handler, Quit)
805 .WillByDefault([handler_ptr = handler.get()](
806 std::optional<HWND> hwnd, std::optional<WPARAM> wparam,
807 std::optional<LPARAM> lparam, UINT exit_code) {
808 handler_ptr->WindowsLifecycleManager::Quit(hwnd, wparam, lparam,
811 ON_CALL(*handler, DispatchMessage)
813 [&engine](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
814 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
815 hwnd, msg, wparam, lparam);
817 modifier.SetLifecycleManager(std::move(handler));
818 engine->lifecycle_manager()->BeginProcessingExit();
826 engine->window_proc_delegate_manager()->RegisterTopLevelWindowProcDelegate(
831 bool* called =
reinterpret_cast<bool*
>(
user_data);
838 reinterpret_cast<void*
>(&second_close));
840 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
843 while (!second_close) {
844 engine->task_runner()->ProcessTasks();
849 FlutterWindowsEngineBuilder builder{GetContext()};
850 builder.SetDartEntrypoint(
"exitTestExit");
851 bool finished =
false;
853 auto engine = builder.Build();
854 auto window_binding_handler =
855 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
856 MockFlutterWindowsView view(std::move(window_binding_handler));
857 view.SetEngine(engine.get());
859 EngineModifier modifier(engine.get());
860 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
861 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
863 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce([&finished]() {
868 EXPECT_CALL(*handler, Quit).Times(0);
869 modifier.SetLifecycleManager(std::move(handler));
870 engine->lifecycle_manager()->BeginProcessingExit();
874 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
878 engine->task_runner()->ProcessTasks();
883 FlutterWindowsEngineBuilder builder{GetContext()};
885 auto engine = builder.Build();
886 auto window_binding_handler =
887 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
888 MockFlutterWindowsView view(std::move(window_binding_handler));
889 view.SetEngine(engine.get());
891 EngineModifier modifier(engine.get());
892 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
893 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
894 EXPECT_CALL(*handler, IsLastWindowOfProcess).Times(0);
895 modifier.SetLifecycleManager(std::move(handler));
897 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
902 FlutterWindowsEngineBuilder builder{GetContext()};
904 auto engine = builder.Build();
905 auto window_binding_handler =
906 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
907 MockFlutterWindowsView view(std::move(window_binding_handler));
908 view.SetEngine(engine.get());
910 EngineModifier modifier(engine.get());
911 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
912 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
913 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
914 modifier.SetLifecycleManager(std::move(handler));
915 engine->lifecycle_manager()->BeginProcessingExit();
917 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
922 FlutterWindowsEngineBuilder builder{GetContext()};
924 auto engine = builder.Build();
925 auto window_binding_handler =
926 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
927 MockFlutterWindowsView view(std::move(window_binding_handler));
928 view.SetEngine(engine.get());
930 EngineModifier modifier(engine.get());
931 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
932 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
933 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
934 modifier.SetLifecycleManager(std::move(handler));
935 engine->lifecycle_manager()->BeginProcessingExit();
937 engine->lifecycle_manager()->ExternalWindowMessage(0, WM_CLOSE, 0, 0);
941 FlutterWindowsEngineBuilder builder{GetContext()};
943 auto engine = builder.Build();
944 auto window_binding_handler =
945 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
946 MockFlutterWindowsView view(std::move(window_binding_handler));
947 view.SetEngine(engine.get());
949 EngineModifier modifier(engine.get());
950 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
951 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
954 modifier.SetLifecycleManager(std::move(handler));
959 FlutterWindowsEngineBuilder builder{GetContext()};
961 auto engine = builder.Build();
962 auto window_binding_handler =
963 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
964 MockFlutterWindowsView view(std::move(window_binding_handler));
965 view.SetEngine(engine.get());
967 EngineModifier modifier(engine.get());
968 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
971 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
972 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
973 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
976 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
977 (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0);
978 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
981 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
982 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
983 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
988 FlutterWindowsEngineBuilder builder{GetContext()};
990 auto engine = builder.Build();
991 auto window_binding_handler =
992 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
993 MockFlutterWindowsView view(std::move(window_binding_handler));
994 view.SetEngine(engine.get());
996 EngineModifier modifier(engine.get());
997 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1002 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1004 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1007 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1012 FlutterWindowsEngineBuilder builder{GetContext()};
1013 HWND outer =
reinterpret_cast<HWND
>(1);
1014 HWND inner =
reinterpret_cast<HWND
>(2);
1016 auto engine = builder.Build();
1017 auto window_binding_handler =
1018 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1019 MockFlutterWindowsView view(std::move(window_binding_handler));
1020 ON_CALL(view, GetWindowHandle).WillByDefault([=]() {
return inner; });
1021 view.SetEngine(engine.get());
1023 EngineModifier modifier(engine.get());
1024 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1029 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1030 outer, WM_SHOWWINDOW, TRUE, NULL);
1034 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1041 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1046 FlutterWindowsEngineBuilder builder{GetContext()};
1047 builder.SetDartEntrypoint(
"enableLifecycleTest");
1048 bool finished =
false;
1050 auto engine = builder.Build();
1051 auto window_binding_handler =
1052 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1053 MockFlutterWindowsView view(std::move(window_binding_handler));
1054 view.SetEngine(engine.get());
1056 EngineModifier modifier(engine.get());
1057 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1058 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1059 EXPECT_CALL(*handler, SetLifecycleState)
1061 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1063 modifier.SetLifecycleManager(std::move(handler));
1065 auto binary_messenger =
1066 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1068 binary_messenger->SetMessageHandler(
1069 "flutter/unittest", [&finished](
const uint8_t*
message,
1072 EXPECT_NE(contents.find(
"AppLifecycleState.inactive"),
1075 char response[] =
"";
1076 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1082 HWND hwnd =
reinterpret_cast<HWND
>(1);
1085 EXPECT_FALSE(finished);
1089 engine->lifecycle_manager()->BeginProcessingLifecycle();
1093 engine->task_runner()->ProcessTasks();
1098 FlutterWindowsEngineBuilder builder{GetContext()};
1099 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1100 bool enabled_lifecycle =
false;
1101 bool dart_responded =
false;
1103 auto engine = builder.Build();
1104 auto window_binding_handler =
1105 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1106 MockFlutterWindowsView view(std::move(window_binding_handler));
1107 view.SetEngine(engine.get());
1109 EngineModifier modifier(engine.get());
1110 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1111 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1112 EXPECT_CALL(*handler, SetLifecycleState)
1114 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1116 handler->begin_processing_callback = [&]() { enabled_lifecycle =
true; };
1117 modifier.SetLifecycleManager(std::move(handler));
1119 auto binary_messenger =
1120 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1121 binary_messenger->SetMessageHandler(
1125 EXPECT_NE(contents.find(
"AppLifecycleState."), std::string::npos);
1126 dart_responded =
true;
1127 char response[] =
"";
1128 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1133 while (!enabled_lifecycle) {
1134 engine->task_runner()->ProcessTasks();
1137 HWND hwnd =
reinterpret_cast<HWND
>(1);
1141 while (!dart_responded) {
1142 engine->task_runner()->ProcessTasks();
1147 FlutterWindowsEngineBuilder builder{GetContext()};
1148 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1150 auto engine = builder.Build();
1151 auto window_binding_handler =
1152 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1153 MockFlutterWindowsView view(std::move(window_binding_handler));
1154 view.SetEngine(engine.get());
1156 EngineModifier modifier(engine.get());
1157 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1159 bool lifecycle_began =
false;
1160 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1161 EXPECT_CALL(*handler, SetLifecycleState).Times(1);
1162 handler->begin_processing_callback = [&]() { lifecycle_began =
true; };
1163 modifier.SetLifecycleManager(std::move(handler));
1167 while (!lifecycle_began) {
1168 engine->task_runner()->ProcessTasks();