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().SendSemanticsAction = MOCK_ENGINE_PROC(
486 SendSemanticsAction, ([&called, &
message](
auto engine,
auto info) {
488 EXPECT_EQ(info->view_id, 456);
489 EXPECT_EQ(info->node_id, 42);
490 EXPECT_EQ(info->action, kFlutterSemanticsActionDismiss);
491 EXPECT_EQ(memcmp(info->data,
message.c_str(),
message.size()), 0);
492 EXPECT_EQ(info->data_length,
message.size());
496 auto data = fml::MallocMapping::Copy(
message.c_str(),
message.size());
497 engine->DispatchSemanticsAction(456, 42, kFlutterSemanticsActionDismiss,
504 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
505 THREAD_PRIORITY_BELOW_NORMAL);
508 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
509 THREAD_PRIORITY_ABOVE_NORMAL);
512 EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
513 THREAD_PRIORITY_ABOVE_NORMAL);
517 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
520 EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
524 FlutterWindowsEngineBuilder builder{GetContext()};
525 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
526 EngineModifier modifier(engine.get());
528 MockEmbedderApiForKeyboard(modifier,
529 std::make_shared<MockKeyResponseController>());
536 engine->AddPluginRegistrarDestructionCallback(
538 auto result =
reinterpret_cast<int*
>(ref);
542 engine->AddPluginRegistrarDestructionCallback(
544 auto result =
reinterpret_cast<int*
>(ref);
550 EXPECT_EQ(result1, 1);
551 EXPECT_EQ(result2, 2);
555 FlutterWindowsEngineBuilder builder{GetContext()};
556 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
557 EngineModifier modifier(engine.get());
560 modifier.embedder_api().ScheduleFrame =
561 MOCK_ENGINE_PROC(ScheduleFrame, ([&called](
auto engine) {
566 engine->ScheduleFrame();
571 FlutterWindowsEngineBuilder builder{GetContext()};
572 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
573 EngineModifier modifier(engine.get());
576 modifier.embedder_api().SetNextFrameCallback = MOCK_ENGINE_PROC(
577 SetNextFrameCallback, ([&called](
auto engine,
auto callback,
auto data) {
582 engine->SetNextFrameCallback([]() {});
587 FlutterWindowsEngineBuilder builder{GetContext()};
588 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
589 EXPECT_EQ(engine->GetExecutableName(),
"flutter_windows_unittests.exe");
595 auto windows_proc_table = std::make_shared<MockWindowsProcTable>();
596 EXPECT_CALL(*windows_proc_table, GetHighContrastEnabled)
597 .WillOnce(Return(
true))
598 .WillOnce(Return(
false));
600 FlutterWindowsEngineBuilder builder{GetContext()};
601 builder.SetWindowsProcTable(windows_proc_table);
602 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
603 EngineModifier modifier(engine.get());
605 std::optional<FlutterAccessibilityFeature> engine_flags;
606 modifier.embedder_api().UpdateAccessibilityFeatures = MOCK_ENGINE_PROC(
607 UpdateAccessibilityFeatures, ([&engine_flags](
auto engine,
auto flags) {
608 engine_flags = flags;
611 modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC(
613 [](
auto engine,
const auto message) {
return kSuccess; });
616 engine->UpdateHighContrastMode();
618 EXPECT_TRUE(engine->high_contrast_enabled());
619 EXPECT_TRUE(engine_flags.has_value());
621 engine_flags.value() &
622 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
625 engine_flags.reset();
626 engine->UpdateHighContrastMode();
628 EXPECT_FALSE(engine->high_contrast_enabled());
629 EXPECT_TRUE(engine_flags.has_value());
631 engine_flags.value() &
632 FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast);
636 FlutterWindowsEngineBuilder builder{GetContext()};
637 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
638 EngineModifier modifier(engine.get());
640 modifier.embedder_api().PostRenderThreadTask = MOCK_ENGINE_PROC(
641 PostRenderThreadTask, ([](
auto engine,
auto callback,
auto context) {
647 engine->PostRasterThreadTask([&called]() { called =
true; });
655 std::unique_ptr<WindowBindingHandler> wbh)
660 NotifyWinEventWrapper,
661 (ui::AXPlatformNodeWin*, ax::mojom::Event),
667 FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
672 auto& context = GetContext();
673 WindowsConfigBuilder builder{context};
674 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
678 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
679 context.AddNativeFunction(
"Signal", native_entry);
681 EnginePtr engine{builder.RunHeadless()};
682 ASSERT_NE(engine,
nullptr);
684 ui::AXPlatformNodeDelegateBase parent_delegate;
687 auto window_binding_handler =
688 std::make_unique<NiceMock<MockWindowBindingHandler>>();
689 EXPECT_CALL(*window_binding_handler, GetAlertDelegate)
690 .WillOnce(Return(&delegate));
693 MockFlutterWindowsView view{windows_engine,
694 std::move(window_binding_handler)};
695 EngineModifier modifier{windows_engine};
696 modifier.SetImplicitView(&view);
700 EXPECT_CALL(view, NotifyWinEventWrapper).Times(1);
704 windows_engine->task_runner()->ProcessTasks();
710 auto& context = GetContext();
711 WindowsConfigBuilder builder{context};
712 builder.SetDartEntrypoint(
"sendAccessibilityAnnouncement");
716 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
717 context.AddNativeFunction(
"Signal", native_entry);
719 EnginePtr engine{builder.RunHeadless()};
720 ASSERT_NE(engine,
nullptr);
727 windows_engine->task_runner()->ProcessTasks();
734 fml::testing::LogCapture log_capture;
736 auto& context = GetContext();
737 WindowsConfigBuilder builder{context};
738 builder.SetDartEntrypoint(
"sendAccessibilityTooltipEvent");
742 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
743 context.AddNativeFunction(
"Signal", native_entry);
745 ViewControllerPtr controller{builder.Run()};
746 ASSERT_NE(controller,
nullptr);
754 windows_engine->task_runner()->ProcessTasks();
760 EXPECT_EQ(log_capture.str().find(
"tooltip"), std::string::npos);
772 (std::optional<HWND>, std::optional<WPARAM>, std::optional<LPARAM>, UINT),
789 FlutterWindowsEngineBuilder builder{GetContext()};
790 builder.SetDartEntrypoint(
"exitTestExit");
791 bool finished =
false;
793 auto engine = builder.Build();
794 auto window_binding_handler =
795 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
796 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
798 EngineModifier modifier(engine.get());
799 modifier.SetImplicitView(&view);
800 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
801 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
802 EXPECT_CALL(*handler, Quit)
803 .WillOnce([&finished](std::optional<HWND> hwnd,
804 std::optional<WPARAM> wparam,
805 std::optional<LPARAM> lparam,
806 UINT exit_code) { finished = exit_code == 0; });
807 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
808 modifier.SetLifecycleManager(std::move(handler));
810 engine->lifecycle_manager()->BeginProcessingExit();
814 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
820 engine->task_runner()->ProcessTasks();
825 FlutterWindowsEngineBuilder builder{GetContext()};
826 builder.SetDartEntrypoint(
"exitTestCancel");
827 bool did_call =
false;
829 auto engine = builder.Build();
830 auto window_binding_handler =
831 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
832 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
834 EngineModifier modifier(engine.get());
835 modifier.SetImplicitView(&view);
836 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
837 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
838 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillRepeatedly(Return(
true));
839 EXPECT_CALL(*handler, Quit).Times(0);
840 modifier.SetLifecycleManager(std::move(handler));
841 engine->lifecycle_manager()->BeginProcessingExit();
843 auto binary_messenger =
844 std::make_unique<BinaryMessengerImpl>(engine->messenger());
845 binary_messenger->SetMessageHandler(
846 "flutter/platform", [&did_call](
const uint8_t*
message,
849 EXPECT_NE(contents.find(
"\"method\":\"System.exitApplication\""),
851 EXPECT_NE(contents.find(
"\"type\":\"required\""), std::string::npos);
852 EXPECT_NE(contents.find(
"\"exitCode\":0"), std::string::npos);
854 char response[] =
"";
855 reply(
reinterpret_cast<uint8_t*
>(response), 0);
860 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
864 engine->task_runner()->ProcessTasks();
872 FlutterWindowsEngineBuilder builder{GetContext()};
873 builder.SetDartEntrypoint(
"exitTestExit");
874 bool second_close =
false;
876 auto engine = builder.Build();
877 auto window_binding_handler =
878 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
879 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
881 EngineModifier modifier(engine.get());
882 modifier.SetImplicitView(&view);
883 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
884 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
885 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
true));
886 EXPECT_CALL(*handler, Quit)
887 .WillOnce([handler_ptr = handler.get()](
888 std::optional<HWND> hwnd, std::optional<WPARAM> wparam,
889 std::optional<LPARAM> lparam, UINT exit_code) {
890 handler_ptr->WindowsLifecycleManager::Quit(hwnd, wparam, lparam,
893 EXPECT_CALL(*handler, DispatchMessage)
895 [&engine](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
896 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
897 hwnd, msg, wparam, lparam);
899 modifier.SetLifecycleManager(std::move(handler));
900 engine->lifecycle_manager()->BeginProcessingExit();
908 engine->window_proc_delegate_manager()->RegisterTopLevelWindowProcDelegate(
913 bool* called =
reinterpret_cast<bool*
>(
user_data);
920 reinterpret_cast<void*
>(&second_close));
922 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
925 while (!second_close) {
926 engine->task_runner()->ProcessTasks();
931 FlutterWindowsEngineBuilder builder{GetContext()};
932 builder.SetDartEntrypoint(
"exitTestExit");
933 bool finished =
false;
935 auto engine = builder.Build();
936 auto window_binding_handler =
937 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
938 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
940 EngineModifier modifier(engine.get());
941 modifier.SetImplicitView(&view);
942 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
943 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
944 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce([&finished]() {
949 EXPECT_CALL(*handler, Quit).Times(0);
950 modifier.SetLifecycleManager(std::move(handler));
951 engine->lifecycle_manager()->BeginProcessingExit();
955 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
959 engine->task_runner()->ProcessTasks();
964 FlutterWindowsEngineBuilder builder{GetContext()};
966 auto engine = builder.Build();
967 auto window_binding_handler =
968 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
969 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
971 EngineModifier modifier(engine.get());
972 modifier.SetImplicitView(&view);
973 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
974 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
975 EXPECT_CALL(*handler, IsLastWindowOfProcess).Times(0);
976 modifier.SetLifecycleManager(std::move(handler));
978 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
983 FlutterWindowsEngineBuilder builder{GetContext()};
985 auto engine = builder.Build();
986 auto window_binding_handler =
987 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
988 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
990 EngineModifier modifier(engine.get());
991 modifier.SetImplicitView(&view);
992 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
993 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
994 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
995 modifier.SetLifecycleManager(std::move(handler));
996 engine->lifecycle_manager()->BeginProcessingExit();
998 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(0, WM_CLOSE, 0,
1003 FlutterWindowsEngineBuilder builder{GetContext()};
1005 auto engine = builder.Build();
1006 auto window_binding_handler =
1007 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1008 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1010 EngineModifier modifier(engine.get());
1011 modifier.SetImplicitView(&view);
1012 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1013 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1014 EXPECT_CALL(*handler, IsLastWindowOfProcess).WillOnce(Return(
false));
1015 modifier.SetLifecycleManager(std::move(handler));
1016 engine->lifecycle_manager()->BeginProcessingExit();
1018 engine->lifecycle_manager()->ExternalWindowMessage(0, WM_CLOSE, 0, 0);
1022 FlutterWindowsEngineBuilder builder{GetContext()};
1024 auto engine = builder.Build();
1025 auto window_binding_handler =
1026 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1027 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1029 EngineModifier modifier(engine.get());
1030 modifier.SetImplicitView(&view);
1031 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1034 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1035 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1037 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1041 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1044 engine->lifecycle_manager()->OnWindowStateEvent((HWND)1,
1047 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1051 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1054 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1055 (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0);
1057 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1061 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1064 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1065 (HWND)1, WM_SIZE, SIZE_RESTORED, 0);
1067 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1071 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1076 FlutterWindowsEngineBuilder builder{GetContext()};
1078 auto engine = builder.Build();
1079 auto window_binding_handler =
1080 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1081 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1083 EngineModifier modifier(engine.get());
1084 modifier.SetImplicitView(&view);
1085 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1090 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1092 engine->ProcessExternalWindowMessage(
reinterpret_cast<HWND
>(1), WM_SHOWWINDOW,
1095 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1099 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1104 FlutterWindowsEngineBuilder builder{GetContext()};
1105 HWND outer =
reinterpret_cast<HWND
>(1);
1106 HWND inner =
reinterpret_cast<HWND
>(2);
1108 auto engine = builder.Build();
1109 auto window_binding_handler =
1110 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1111 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1112 ON_CALL(view, GetWindowHandle).WillByDefault([=]() {
return inner; });
1114 EngineModifier modifier(engine.get());
1115 modifier.SetImplicitView(&view);
1116 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1121 engine->window_proc_delegate_manager()->OnTopLevelWindowProc(
1122 outer, WM_SHOWWINDOW, TRUE, NULL);
1126 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1130 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1136 while (engine->lifecycle_manager()->IsUpdateStateScheduled()) {
1141 EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(),
1146 FlutterWindowsEngineBuilder builder{GetContext()};
1147 builder.SetDartEntrypoint(
"enableLifecycleTest");
1148 bool finished =
false;
1150 auto engine = builder.Build();
1151 auto window_binding_handler =
1152 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1153 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1155 EngineModifier modifier(engine.get());
1156 modifier.SetImplicitView(&view);
1157 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1158 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1159 EXPECT_CALL(*handler, SetLifecycleState)
1161 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1163 modifier.SetLifecycleManager(std::move(handler));
1165 auto binary_messenger =
1166 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1168 binary_messenger->SetMessageHandler(
1169 "flutter/unittest", [&finished](
const uint8_t*
message,
1172 EXPECT_NE(contents.find(
"AppLifecycleState.inactive"),
1175 char response[] =
"";
1176 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1182 HWND hwnd =
reinterpret_cast<HWND
>(1);
1185 EXPECT_FALSE(finished);
1189 engine->lifecycle_manager()->BeginProcessingLifecycle();
1193 engine->task_runner()->ProcessTasks();
1198 FlutterWindowsEngineBuilder builder{GetContext()};
1199 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1200 bool enabled_lifecycle =
false;
1201 bool dart_responded =
false;
1203 auto engine = builder.Build();
1204 auto window_binding_handler =
1205 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1206 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1208 EngineModifier modifier(engine.get());
1209 modifier.SetImplicitView(&view);
1210 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1211 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1212 EXPECT_CALL(*handler, SetLifecycleState)
1214 handler_ptr->WindowsLifecycleManager::SetLifecycleState(state);
1216 handler->begin_processing_callback = [&]() { enabled_lifecycle =
true; };
1217 modifier.SetLifecycleManager(std::move(handler));
1219 auto binary_messenger =
1220 std::make_unique<BinaryMessengerImpl>(engine->messenger());
1221 binary_messenger->SetMessageHandler(
1225 EXPECT_NE(contents.find(
"AppLifecycleState."), std::string::npos);
1226 dart_responded =
true;
1227 char response[] =
"";
1228 reply(
reinterpret_cast<uint8_t*
>(response), 0);
1233 while (!enabled_lifecycle) {
1234 engine->task_runner()->ProcessTasks();
1237 HWND hwnd =
reinterpret_cast<HWND
>(1);
1241 while (!dart_responded) {
1242 engine->task_runner()->ProcessTasks();
1247 FlutterWindowsEngineBuilder builder{GetContext()};
1248 builder.SetDartEntrypoint(
"enableLifecycleToFrom");
1250 auto engine = builder.Build();
1251 auto window_binding_handler =
1252 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1253 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1255 EngineModifier modifier(engine.get());
1256 modifier.SetImplicitView(&view);
1257 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1259 bool lifecycle_began =
false;
1260 auto handler = std::make_unique<MockWindowsLifecycleManager>(engine.get());
1261 handler->begin_processing_callback = [&]() { lifecycle_began =
true; };
1262 modifier.SetLifecycleManager(std::move(handler));
1266 while (!lifecycle_began) {
1267 engine->task_runner()->ProcessTasks();
1272 FlutterWindowsEngineBuilder builder{GetContext()};
1273 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1274 auto engine = builder.Build();
1276 EngineModifier modifier{engine.get()};
1277 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1279 bool received_call =
false;
1281 auto manager = std::make_unique<MockPlatformViewManager>(engine.get());
1282 EXPECT_CALL(*manager, AddPlatformView)
1284 received_call =
true;
1287 modifier.SetPlatformViewPlugin(std::move(manager));
1291 while (!received_call) {
1292 engine->task_runner()->ProcessTasks();
1297 FlutterWindowsEngineBuilder builder{GetContext()};
1298 auto engine = builder.Build();
1300 EngineModifier modifier{engine.get()};
1302 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1303 modifier.embedder_api().AddView = MOCK_ENGINE_PROC(
1306 const FlutterAddViewInfo* info) {
return kInternalInconsistency; });
1308 ASSERT_TRUE(engine->
Run());
1312 auto implicit_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1314 std::unique_ptr<FlutterWindowsView> implicit_view =
1315 engine->CreateView(std::move(implicit_window));
1317 EXPECT_TRUE(implicit_view);
1320 auto second_window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
1322 EXPECT_DEBUG_DEATH(engine->CreateView(std::move(second_window)),
1323 "FlutterEngineAddView returned an unexpected result");
1327 FlutterWindowsEngineBuilder builder{GetContext()};
1328 builder.SetDartEntrypoint(
"sendCreatePlatformViewMethod");
1329 auto engine = builder.Build();
1331 EngineModifier modifier{engine.get()};
1333 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1334 modifier.embedder_api().RemoveView = MOCK_ENGINE_PROC(
1337 const FlutterRemoveViewInfo* info) {
return kInternalInconsistency; });
1339 ASSERT_TRUE(engine->
Run());
1340 EXPECT_DEBUG_DEATH(engine->RemoveView(123),
1341 "FlutterEngineRemoveView returned an unexpected result");
1345 auto& context = GetContext();
1346 WindowsConfigBuilder builder{context};
1347 builder.SetDartEntrypoint(
"mergedUIThread");
1350 std::optional<std::thread::id> ui_thread_id;
1352 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
1353 ui_thread_id = std::this_thread::get_id();
1355 context.AddNativeFunction(
"Signal", native_entry);
1357 EnginePtr engine{builder.RunHeadless()};
1358 while (!ui_thread_id) {
1361 ASSERT_EQ(*ui_thread_id, std::this_thread::get_id());
1365 FlutterWindowsEngineBuilder builder{GetContext()};
1366 std::unique_ptr<FlutterWindowsEngine> engine = builder.Build();
1367 auto window_binding_handler =
1368 std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
1369 MockFlutterWindowsView view(engine.get(), std::move(window_binding_handler));
1371 EngineModifier modifier(engine.get());
1372 modifier.SetImplicitView(&view);
1374 FlutterViewFocusChangeRequest request;
1377 EXPECT_CALL(view, Focus()).WillOnce(Return(
true));
1378 modifier.OnViewFocusChangeRequest(&request);
1382 auto& context = GetContext();
1383 WindowsConfigBuilder builder{context};
1384 builder.SetDartEntrypoint(
"sendSemanticsTreeInfo");
1389 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { done =
true; });
1390 context.AddNativeFunction(
"Signal", native_entry);
1393 EnginePtr engine{builder.RunHeadless()};
1394 ASSERT_NE(engine,
nullptr);
1396 auto window_binding_handler1 =
1397 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1398 auto window_binding_handler2 =
1399 std::make_unique<NiceMock<MockWindowBindingHandler>>();
1404 EXPECT_CALL(*window_binding_handler1, GetPhysicalWindowBounds)
1406 EXPECT_CALL(*window_binding_handler1, GetDpiScale)
1407 .WillRepeatedly(testing::Return(96.0));
1408 EXPECT_CALL(*window_binding_handler2, GetPhysicalWindowBounds)
1410 EXPECT_CALL(*window_binding_handler2, GetDpiScale)
1411 .WillRepeatedly(testing::Return(96.0));
1414 EngineModifier modifier{windows_engine};
1415 modifier.embedder_api().RunsAOTCompiledDartCode = []() {
return false; };
1420 auto view1 = windows_engine->
CreateView(std::move(window_binding_handler1));
1421 auto view2 = windows_engine->CreateView(std::move(window_binding_handler2));
1425 windows_engine->UpdateSemanticsEnabled(
true);
1428 windows_engine->task_runner()->ProcessTasks();
1431 auto accessibility_bridge1 = view1->accessibility_bridge().lock();
1432 auto accessibility_bridge2 = view2->accessibility_bridge().lock();
1437 !accessibility_bridge1->GetPlatformNodeFromTree(view1->view_id() + 1)) {
1438 windows_engine->task_runner()->ProcessTasks();
1442 !accessibility_bridge2->GetPlatformNodeFromTree(view2->view_id() + 1)) {
1443 windows_engine->task_runner()->ProcessTasks();
1447 auto tree1 = accessibility_bridge1->GetTree();
1448 auto tree2 = accessibility_bridge2->GetTree();
1449 EXPECT_NE(tree1->GetFromId(view1->view_id() + 1),
nullptr);
1450 EXPECT_NE(tree2->GetFromId(view2->view_id() + 1),
nullptr);
void UpdateSemanticsEnabled(bool enabled)
std::unique_ptr< FlutterWindowsView > CreateView(std::unique_ptr< WindowBindingHandler > window)
virtual void Quit(std::optional< HWND > window, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
virtual void BeginProcessingLifecycle()
virtual void DispatchMessage(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
virtual bool IsLastWindowOfProcess()
virtual void SetLifecycleState(AppLifecycleState state)
~MockFlutterWindowsView()
MOCK_METHOD(bool, Focus,(),(override))
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
MOCK_METHOD(HWND, GetWindowHandle,(),(const, override))
virtual ~MockWindowsLifecycleManager()
std::function< void()> begin_processing_callback
MOCK_METHOD(void, DispatchMessage,(HWND, UINT, WPARAM, LPARAM),(override))
MOCK_METHOD(void, Quit,(std::optional< HWND >, std::optional< WPARAM >, std::optional< LPARAM >, UINT),(override))
MOCK_METHOD(void, SetLifecycleState,(AppLifecycleState),(override))
void BeginProcessingLifecycle() override
MOCK_METHOD(bool, IsLastWindowOfProcess,(),(override))
MockWindowsLifecycleManager(FlutterWindowsEngine *engine)
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef ref)
FlutterDesktopBinaryReply callback
TEST_F(CompositorOpenGLTest, CreateBackingStore)
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
static void WindowsPlatformThreadPrioritySetter(FlutterThreadPriority priority)
constexpr FlutterViewId kImplicitViewId