8 #include <wrl/client.h>
11 #include "flutter/fml/synchronization/count_down_latch.h"
12 #include "flutter/fml/synchronization/waitable_event.h"
13 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
14 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
15 #include "flutter/shell/platform/windows/testing/windows_test.h"
16 #include "flutter/shell/platform/windows/testing/windows_test_config_builder.h"
17 #include "flutter/shell/platform/windows/testing/windows_test_context.h"
18 #include "flutter/testing/stream_capture.h"
19 #include "gtest/gtest.h"
20 #include "third_party/tonic/converter/dart_converter.h"
27 TEST(WindowsNoFixtureTest, GetTextureRegistrar) {
32 ASSERT_NE(engine,
nullptr);
34 EXPECT_NE(texture_registrar,
nullptr);
40 auto& context = GetContext();
41 WindowsConfigBuilder builder(context);
42 ViewControllerPtr controller{builder.Run()};
43 ASSERT_NE(controller,
nullptr);
47 TEST_F(WindowsTest, LaunchMainHasNoOutput) {
49 StreamCapture stdout_capture(&std::cout);
50 StreamCapture stderr_capture(&std::cerr);
52 auto& context = GetContext();
53 WindowsConfigBuilder builder(context);
54 ViewControllerPtr controller{builder.Run()};
55 ASSERT_NE(controller,
nullptr);
57 stdout_capture.Stop();
58 stderr_capture.Stop();
61 EXPECT_TRUE(stdout_capture.GetOutput().empty());
62 EXPECT_TRUE(stderr_capture.GetOutput().empty());
66 TEST_F(WindowsTest, LaunchCustomEntrypoint) {
67 auto& context = GetContext();
68 WindowsConfigBuilder builder(context);
69 builder.SetDartEntrypoint(
"customEntrypoint");
70 ViewControllerPtr controller{builder.Run()};
71 ASSERT_NE(controller,
nullptr);
79 TEST_F(WindowsTest, LaunchCustomEntrypointInEngineRunInvocation) {
80 auto& context = GetContext();
81 WindowsConfigBuilder builder(context);
82 EnginePtr engine{builder.InitializeEngine()};
83 ASSERT_NE(engine,
nullptr);
89 TEST_F(WindowsTest, LaunchHeadlessEngine) {
90 auto& context = GetContext();
91 WindowsConfigBuilder builder(context);
92 EnginePtr engine{builder.InitializeEngine()};
93 ASSERT_NE(engine,
nullptr);
99 TEST_F(WindowsTest, LaunchRefreshesAccessibility) {
100 auto& context = GetContext();
101 WindowsConfigBuilder builder(context);
102 EnginePtr engine{builder.InitializeEngine()};
103 EngineModifier modifier{
108 UpdateAccessibilityFeatures, ([&called](
auto engine,
auto flags) {
113 ViewControllerPtr controller{
124 TEST_F(WindowsTest, LaunchConflictingCustomEntrypoints) {
125 auto& context = GetContext();
126 WindowsConfigBuilder builder(context);
127 builder.SetDartEntrypoint(
"customEntrypoint");
128 EnginePtr engine{builder.InitializeEngine()};
129 ASSERT_NE(engine,
nullptr);
135 TEST_F(WindowsTest, VerifyNativeFunction) {
136 auto& context = GetContext();
137 WindowsConfigBuilder builder(context);
138 builder.SetDartEntrypoint(
"verifyNativeFunction");
140 fml::AutoResetWaitableEvent latch;
142 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch.Signal(); });
143 context.AddNativeFunction(
"Signal", native_entry);
145 ViewControllerPtr controller{builder.Run()};
146 ASSERT_NE(controller,
nullptr);
154 TEST_F(WindowsTest, VerifyNativeFunctionWithParameters) {
155 auto& context = GetContext();
156 WindowsConfigBuilder builder(context);
157 builder.SetDartEntrypoint(
"verifyNativeFunctionWithParameters");
159 bool bool_value =
false;
160 fml::AutoResetWaitableEvent latch;
161 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
162 auto handle = Dart_GetNativeBooleanArgument(args, 0, &bool_value);
163 ASSERT_FALSE(Dart_IsError(handle));
166 context.AddNativeFunction(
"SignalBoolValue", native_entry);
168 ViewControllerPtr controller{builder.Run()};
169 ASSERT_NE(controller,
nullptr);
173 EXPECT_TRUE(bool_value);
177 TEST_F(WindowsTest, PlatformExecutable) {
178 auto& context = GetContext();
179 WindowsConfigBuilder builder(context);
180 builder.SetDartEntrypoint(
"readPlatformExecutable");
182 std::string executable_name;
183 fml::AutoResetWaitableEvent latch;
184 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
185 auto handle = Dart_GetNativeArgument(args, 0);
186 ASSERT_FALSE(Dart_IsError(handle));
187 executable_name = tonic::DartConverter<std::string>::FromDart(handle);
190 context.AddNativeFunction(
"SignalStringValue", native_entry);
192 ViewControllerPtr controller{builder.Run()};
193 ASSERT_NE(controller,
nullptr);
197 EXPECT_EQ(executable_name,
"flutter_windows_unittests.exe");
202 TEST_F(WindowsTest, VerifyNativeFunctionWithReturn) {
203 auto& context = GetContext();
204 WindowsConfigBuilder builder(context);
205 builder.SetDartEntrypoint(
"verifyNativeFunctionWithReturn");
207 bool bool_value_to_return =
true;
208 fml::CountDownLatch latch(2);
209 auto bool_return_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
210 Dart_SetBooleanReturnValue(args, bool_value_to_return);
213 context.AddNativeFunction(
"SignalBoolReturn", bool_return_entry);
215 bool bool_value_passed =
false;
216 auto bool_pass_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
217 auto handle = Dart_GetNativeBooleanArgument(args, 0, &bool_value_passed);
218 ASSERT_FALSE(Dart_IsError(handle));
221 context.AddNativeFunction(
"SignalBoolValue", bool_pass_entry);
223 ViewControllerPtr controller{builder.Run()};
224 ASSERT_NE(controller,
nullptr);
228 EXPECT_TRUE(bool_value_passed);
234 fml::AutoResetWaitableEvent frame_scheduled_latch;
235 fml::AutoResetWaitableEvent frame_drawn_latch;
236 std::thread::id thread_id;
240 CreateNewThread(
"test_platform_thread")->PostTask([&]() {
241 captures.thread_id = std::this_thread::get_id();
243 auto& context = GetContext();
244 WindowsConfigBuilder builder(context);
245 builder.SetDartEntrypoint(
"drawHelloWorld");
247 auto native_entry = CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
248 ASSERT_FALSE(captures.frame_drawn_latch.IsSignaledForTest());
249 captures.frame_scheduled_latch.Signal();
251 context.AddNativeFunction(
"NotifyFirstFrameScheduled", native_entry);
253 ViewControllerPtr controller{builder.Run()};
254 ASSERT_NE(controller,
nullptr);
261 auto captures =
static_cast<Captures*
>(
user_data);
263 ASSERT_TRUE(captures->frame_scheduled_latch.IsSignaledForTest());
266 ASSERT_EQ(std::this_thread::get_id(), captures->thread_id);
269 captures->frame_drawn_latch.Signal();
270 ::PostQuitMessage(0);
276 while (::GetMessage(&msg,
nullptr, 0, 0)) {
277 ::TranslateMessage(&msg);
278 ::DispatchMessage(&msg);
282 captures.frame_drawn_latch.Wait();
285 TEST_F(WindowsTest, GetGraphicsAdapter) {
286 auto& context = GetContext();
287 WindowsConfigBuilder builder(context);
288 ViewControllerPtr controller{builder.Run()};
289 ASSERT_NE(controller,
nullptr);
292 Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
294 ASSERT_NE(dxgi_adapter,
nullptr);
295 DXGI_ADAPTER_DESC desc{};
296 ASSERT_TRUE(SUCCEEDED(dxgi_adapter->GetDesc(&desc)));