24#include "gmock/gmock.h"
25#include "gtest/gtest.h"
34class HalfBrokenEGLManager :
public egl::Manager {
38 std::unique_ptr<egl::WindowSurface>
39 CreateWindowSurface(HWND hwnd,
size_t width,
size_t height)
override {
44class MockWindowsLifecycleManager :
public WindowsLifecycleManager {
57 ::TranslateMessage(&msg);
66TEST(WindowsNoFixtureTest, GetTextureRegistrar) {
72 ASSERT_NE(
engine,
nullptr);
83 ASSERT_NE(controller,
nullptr);
95 ASSERT_NE(controller,
nullptr);
97 stderr_capture.
Stop();
100 EXPECT_TRUE(stderr_capture.
GetOutput().empty());
109 ASSERT_NE(controller,
nullptr);
121 ASSERT_NE(
engine,
nullptr);
132 ASSERT_NE(
engine,
nullptr);
134 std::string view_ids;
135 bool signaled =
false;
138 auto handle = Dart_GetNativeArgument(
args, 0);
139 ASSERT_FALSE(Dart_IsError(handle));
145 ASSERT_NE(controller,
nullptr);
152 EXPECT_EQ(view_ids,
"View IDs: [0]");
160 ASSERT_NE(
engine,
nullptr);
169 ASSERT_NE(controller,
nullptr);
173 ASSERT_NE(
engine,
nullptr);
176 ASSERT_TRUE(engine_ptr->running());
189 UpdateAccessibilityFeatures, ([&called](
auto engine,
auto flags) {
210 ASSERT_NE(
engine,
nullptr);
221 bool signaled =
false;
224 context.AddNativeFunction(
"Signal", native_entry);
227 ASSERT_NE(controller,
nullptr);
242 bool bool_value =
false;
243 bool signaled =
false;
245 auto handle = Dart_GetNativeBooleanArgument(
args, 0, &bool_value);
246 ASSERT_FALSE(Dart_IsError(handle));
249 context.AddNativeFunction(
"SignalBoolValue", native_entry);
252 ASSERT_NE(controller,
nullptr);
258 EXPECT_TRUE(bool_value);
267 std::string executable_name;
268 bool signaled =
false;
270 auto handle = Dart_GetNativeArgument(
args, 0);
271 ASSERT_FALSE(Dart_IsError(handle));
275 context.AddNativeFunction(
"SignalStringValue", native_entry);
278 ASSERT_NE(controller,
nullptr);
284 EXPECT_EQ(executable_name,
"flutter_windows_unittests.exe");
294 bool bool_value_to_return =
true;
297 Dart_SetBooleanReturnValue(
args, bool_value_to_return);
300 context.AddNativeFunction(
"SignalBoolReturn", bool_return_entry);
302 bool bool_value_passed =
false;
304 auto handle = Dart_GetNativeBooleanArgument(
args, 0, &bool_value_passed);
305 ASSERT_FALSE(Dart_IsError(handle));
308 context.AddNativeFunction(
"SignalBoolValue", bool_pass_entry);
311 ASSERT_NE(controller,
nullptr);
317 EXPECT_TRUE(bool_value_passed);
324 std::thread::id thread_id;
329 auto platform_thread = std::make_unique<fml::Thread>(
"test_platform_thread");
330 platform_thread->GetTaskRunner()->PostTask([&]() {
331 captures.thread_id = std::this_thread::get_id();
338 captures.frame_scheduled_latch.Signal();
340 context.AddNativeFunction(
"NotifyFirstFrameScheduled", native_entry);
343 EXPECT_NE(controller,
nullptr);
350 auto captures =
static_cast<Captures*
>(
user_data);
352 EXPECT_TRUE(captures->frame_scheduled_latch.IsSignaledForTest());
355 EXPECT_EQ(std::this_thread::get_id(), captures->thread_id);
358 captures->done =
true;
363 while (!captures.done) {
369 platform_thread->Join();
380 ASSERT_NE(
engine,
nullptr);
387 auto done = reinterpret_cast<std::atomic<bool>*>(user_data);
402 engine_ptr->SendWindowMetricsEvent(metrics);
416 ASSERT_NE(
engine,
nullptr);
427 ASSERT_NE(
engine,
nullptr);
430 std::thread background(
434 EXPECT_FALSE(result);
444 ASSERT_NE(
engine,
nullptr);
447 std::thread::id thread_id;
454 auto captures = static_cast<Captures*>(user_data);
455 captures->thread_id = std::this_thread::get_id();
456 captures->done = true;
460 while (!captures.done) {
464 EXPECT_EQ(captures.thread_id, std::this_thread::get_id());
474 ASSERT_NE(
engine,
nullptr);
476 std::mutex background_thread_id_mutex;
478 std::thread::id background_thread_id;
479 std::thread::id platform_thread_id;
483 std::thread background([&]() {
485 std::scoped_lock lock{background_thread_id_mutex};
486 captures.background_thread_id = std::this_thread::get_id();
492 auto captures = static_cast<Captures*>(user_data);
493 captures->platform_thread_id = std::this_thread::get_id();
494 captures->done = true;
500 while (!captures.done) {
504 std::scoped_lock lock{background_thread_id_mutex};
505 EXPECT_NE(captures.background_thread_id, std::thread::id{});
506 EXPECT_NE(captures.background_thread_id, captures.platform_thread_id);
507 EXPECT_EQ(captures.platform_thread_id, std::this_thread::get_id());
517 ASSERT_NE(
engine,
nullptr);
520 bool callback_called =
false;
521 bool cancel_called =
false;
527 static_cast<Captures*>(user_data)->callback_called = true;
530 static_cast<Captures*>(user_data)->cancel_called = true;
538 EXPECT_FALSE(captures.callback_called);
539 EXPECT_TRUE(captures.cancel_called);
547 ASSERT_NE(controller,
nullptr);
558 ASSERT_NE(controller,
nullptr);
561 Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
563 ASSERT_NE(dxgi_adapter,
nullptr);
564 DXGI_ADAPTER_DESC desc{};
565 ASSERT_TRUE(
SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
572 ASSERT_NE(controller,
nullptr);
576 IDXGIAdapter* dxgi_adapter;
578 ASSERT_NE(dxgi_adapter,
nullptr);
579 DXGI_ADAPTER_DESC desc{};
580 ASSERT_TRUE(
SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
586 GTEST_SKIP() <<
"Not able to find low power GPU, nothing to check.";
593 ASSERT_NE(controller,
nullptr);
596 Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
598 ASSERT_NE(dxgi_adapter,
nullptr);
599 DXGI_ADAPTER_DESC desc{};
600 ASSERT_TRUE(
SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
601 ASSERT_EQ(desc.AdapterLuid.HighPart, luid->HighPart);
602 ASSERT_EQ(desc.AdapterLuid.LowPart, luid->LowPart);
608 GTEST_SKIP() <<
"Not able to find high performance GPU, nothing to check.";
616 ASSERT_NE(controller,
nullptr);
619 Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
621 ASSERT_NE(dxgi_adapter,
nullptr);
622 DXGI_ADAPTER_DESC desc{};
623 ASSERT_TRUE(
SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
624 ASSERT_EQ(desc.AdapterLuid.HighPart, luid->HighPart);
625 ASSERT_EQ(desc.AdapterLuid.LowPart, luid->LowPart);
631 GTEST_SKIP() <<
"Not able to find low power GPU, nothing to check.";
638 ASSERT_NE(controller,
nullptr);
642 IDXGIAdapter* dxgi_adapter;
644 ASSERT_NE(dxgi_adapter,
nullptr);
645 DXGI_ADAPTER_DESC desc{};
646 ASSERT_TRUE(
SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
647 ASSERT_EQ(desc.AdapterLuid.HighPart, luid->HighPart);
648 ASSERT_EQ(desc.AdapterLuid.LowPart, luid->LowPart);
654 GTEST_SKIP() <<
"Not able to find high performance GPU, nothing to check.";
662 ASSERT_NE(controller,
nullptr);
666 IDXGIAdapter* dxgi_adapter;
668 ASSERT_NE(dxgi_adapter,
nullptr);
669 DXGI_ADAPTER_DESC desc{};
670 ASSERT_TRUE(
SUCCEEDED(dxgi_adapter->GetDesc(&desc)));
671 ASSERT_EQ(desc.AdapterLuid.HighPart, luid->HighPart);
672 ASSERT_EQ(desc.AdapterLuid.LowPart, luid->LowPart);
680 ASSERT_NE(controller,
nullptr);
689 ASSERT_NE(implicit_view,
nullptr);
696 ASSERT_NE(controller,
nullptr);
711 ASSERT_NE(
view,
nullptr);
712 ASSERT_EQ(view_123,
nullptr);
719 ASSERT_NE(
engine,
nullptr);
729 ASSERT_EQ(implicit_view,
nullptr);
730 ASSERT_EQ(view_123,
nullptr);
742 auto egl_manager = std::make_unique<HalfBrokenEGLManager>();
743 ASSERT_TRUE(egl_manager->IsValid());
744 modifier.SetEGLManager(std::move(egl_manager));
749 ASSERT_NE(controller,
nullptr);
760 auto lifecycle_manager =
761 std::make_unique<MockWindowsLifecycleManager>(windows_engine);
762 auto lifecycle_manager_ptr = lifecycle_manager.get();
763 modifier.SetLifecycleManager(std::move(lifecycle_manager));
765 EXPECT_CALL(*lifecycle_manager_ptr,
768 lifecycle_manager_ptr->WindowsLifecycleManager::SetLifecycleState(
772 EXPECT_CALL(*lifecycle_manager_ptr,
775 lifecycle_manager_ptr->WindowsLifecycleManager::SetLifecycleState(
788 ASSERT_NE(
view,
nullptr);
791 ASSERT_NE(hwnd,
nullptr);
796 ::MoveWindow(hwnd, 0, 0, 100, 100,
799 while (lifecycle_manager_ptr->IsUpdateStateScheduled()) {
806 while (lifecycle_manager_ptr->IsUpdateStateScheduled()) {
816 std::atomic<bool> done =
false;
819 auto handle = Dart_GetNativeArgument(
args, 0);
820 ASSERT_FALSE(Dart_IsError(handle));
822 EXPECT_EQ(
value,
"Success");
827 ASSERT_NE(controller,
nullptr);
839 std::string view_ids;
852 auto handle = Dart_GetNativeArgument(
args, 0);
853 ASSERT_FALSE(Dart_IsError(handle));
855 std::scoped_lock lock{mutex};
861 ASSERT_NE(first_controller,
nullptr);
871 properties.
width = 100;
875 ASSERT_NE(second_controller,
nullptr);
880 std::scoped_lock lock{mutex};
881 if (view_ids ==
"View IDs: [0, 1]") {
888 second_controller.reset();
891 std::scoped_lock lock{mutex};
892 if (view_ids ==
"View IDs: [0]") {
903 std::optional<int64_t> engineId;
906 const auto argument = Dart_GetNativeArgument(
args, 0);
907 if (!Dart_IsNull(argument)) {
914 ASSERT_NE(first_controller,
nullptr);
916 while (!engineId.has_value()) {
935 context.AddNativeFunction(
"Signal", native_entry);
939 ASSERT_NE(controller,
nullptr);
942 ASSERT_NE(
view,
nullptr);
954 ASSERT_NE(hwnd,
nullptr);
962 HRESULT hr = ObjectFromLresult(lres, IID_IAccessible, 0, (
void**)&
accessible);
967 hr = ObjectFromLresult(lres, IID_IAccessibleEx, 0, (
void**)&accessible_ex);
969 ASSERT_EQ(accessible_ex,
nullptr);
983 context.AddNativeFunction(
"Signal", native_entry);
987 ASSERT_NE(controller,
nullptr);
990 ASSERT_NE(
view,
nullptr);
1002 ASSERT_NE(hwnd,
nullptr);
1011 ObjectFromLresult(lres, IID_IAccessibleEx, 0, (
void**)&accessible_ex);
1013 ASSERT_NE(accessible_ex,
nullptr);
1014 accessible_ex->Release();
void UpdateAccessibilityFeatures()
virtual void OnUpdateSemanticsEnabled(bool enabled) override
WindowsLifecycleManager(FlutterWindowsEngine *engine)
virtual void SetLifecycleState(AppLifecycleState state)
static std::optional< LUID > GetLowPowerGpuLuid()
static std::optional< LUID > GetHighPerformanceGpuLuid()
MOCK_METHOD(void, Quit,(std::optional< HWND >, std::optional< WPARAM >, std::optional< LPARAM >, UINT),(override))
MockWindowsLifecycleManager(FlutterWindowsEngine *engine)
std::string GetOutput() const
EnginePtr InitializeEngine() const
void SetAccessibilityMode(FlutterDesktopAccessibilityMode accessibility_mode)
void SetDartEntrypoint(std::string_view entrypoint)
EnginePtr RunHeadless() const
void SetGpuPreference(FlutterDesktopGpuPreference gpu_preference)
ViewControllerPtr Run() const
FlViewAccessible * accessible
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopEngineForId(int64_t engine_id)
FlutterDesktopViewControllerRef FlutterDesktopEngineCreateViewController(FlutterDesktopEngineRef engine, const FlutterDesktopViewControllerProperties *properties)
int64_t FlutterDesktopViewId
struct FlutterDesktopView * FlutterDesktopViewRef
@ HighPerformancePreference
G_BEGIN_DECLS FlTextureRegistrar * texture_registrar
TEST_F(DisplayListTest, Defaults)
std::unique_ptr< FlutterDesktopEngine, EngineDeleter > EnginePtr
std::unique_ptr< FlutterDesktopViewController, ViewControllerDeleter > ViewControllerPtr
TEST(NativeAssetsManagerTest, NoAvailableAssets)
constexpr int64_t kImplicitViewId
#define MOCK_ENGINE_PROC(proc, mock_impl)
std::shared_ptr< ContextGLES > context
const char * icu_data_path
FlutterDesktopImpellerSwitch impeller_switch
size_t struct_size
The size of this struct. Must be sizeof(FlutterWindowMetricsEvent).
size_t height
Physical height of the window.
int64_t view_id
The view that this event is describing.
double pixel_ratio
Scale factor for the physical screen.
size_t width
Physical width of the window.
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef controller)
bool FlutterDesktopEngineGetGraphicsAdapter(FlutterDesktopEngineRef engine, IDXGIAdapter **adapter_out)
FlutterDesktopEngineRef FlutterDesktopEngineCreate(const FlutterDesktopEngineProperties *engine_properties)
FlutterDesktopViewId FlutterDesktopViewControllerGetViewId(FlutterDesktopViewControllerRef controller)
FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char *plugin_name)
bool FlutterDesktopEngineIsPlatformThread(FlutterDesktopEngineRef engine)
FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width, int height, FlutterDesktopEngineRef engine)
bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref)
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef controller)
void FlutterDesktopEnginePostPlatformThreadTask(FlutterDesktopEngineRef engine, VoidCallback callback, VoidCallback on_cancel, void *user_data)
FlutterDesktopViewRef FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef controller)
FlutterDesktopTextureRegistrarRef FlutterDesktopEngineGetTextureRegistrar(FlutterDesktopEngineRef engine)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(FlutterDesktopPluginRegistrarRef controller)
IDXGIAdapter * FlutterDesktopViewGetGraphicsAdapter(FlutterDesktopViewRef view)
void FlutterDesktopEngineSetNextFrameCallback(FlutterDesktopEngineRef engine, VoidCallback callback, void *user_data)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetViewById(FlutterDesktopPluginRegistrarRef controller, FlutterDesktopViewId view_id)
bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine, const char *entry_point)
#define CREATE_NATIVE_ENTRY(native_entry)