// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/shell/platform/windows/flutter_windows_engine.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h" #include "flutter/shell/platform/windows/testing/engine_embedder_api_modifier.h" #include "gtest/gtest.h" namespace flutter { namespace testing { namespace { // Returns an engine instance configured with dummy project path values. std::unique_ptr GetTestEngine() { FlutterDesktopEngineProperties properties = {}; properties.assets_path = L"C:\\foo\\flutter_assets"; properties.icu_data_path = L"C:\\foo\\icudtl.dat"; properties.aot_library_path = L"C:\\foo\\aot.so"; FlutterProjectBundle project(properties); return std::make_unique(project); } } // namespace TEST(FlutterWindowsEngine, SendPlatformMessageWithoutResponse) { std::unique_ptr engine = GetTestEngine(); EngineEmbedderApiModifier modifier(engine.get()); const char* channel = "test"; const std::vector test_message = {1, 2, 3, 4}; // Without a respones, SendPlatformMessage should be a simple passthrough. bool called = false; modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC( SendPlatformMessage, ([&called, test_message](auto engine, auto message) { called = true; EXPECT_STREQ(message->channel, "test"); EXPECT_EQ(message->message_size, test_message.size()); EXPECT_EQ(memcmp(message->message, test_message.data(), message->message_size), 0); EXPECT_EQ(message->response_handle, nullptr); return kSuccess; })); engine->SendPlatformMessage(channel, test_message.data(), test_message.size(), nullptr, nullptr); EXPECT_TRUE(called); } TEST(FlutterWindowsEngine, SendPlatformMessageWithResponse) { std::unique_ptr engine = GetTestEngine(); EngineEmbedderApiModifier modifier(engine.get()); const char* channel = "test"; const std::vector test_message = {1, 2, 3, 4}; auto* dummy_response_handle = reinterpret_cast(5); const FlutterDesktopBinaryReply reply_handler = [](auto... args) {}; void* reply_user_data = reinterpret_cast(6); // When a response is requested, a handle should be created, passed as part // of the message, and then released. bool create_response_handle_called = false; modifier.embedder_api().PlatformMessageCreateResponseHandle = MOCK_ENGINE_PROC( PlatformMessageCreateResponseHandle, ([&create_response_handle_called, &reply_handler, reply_user_data, dummy_response_handle](auto engine, auto reply, auto user_data, auto response_handle) { create_response_handle_called = true; EXPECT_EQ(reply, reply_handler); EXPECT_EQ(user_data, reply_user_data); EXPECT_NE(response_handle, nullptr); *response_handle = dummy_response_handle; return kSuccess; })); bool release_response_handle_called = false; modifier.embedder_api().PlatformMessageReleaseResponseHandle = MOCK_ENGINE_PROC( PlatformMessageReleaseResponseHandle, ([&release_response_handle_called, dummy_response_handle]( auto engine, auto response_handle) { release_response_handle_called = true; EXPECT_EQ(response_handle, dummy_response_handle); return kSuccess; })); bool send_message_called = false; modifier.embedder_api().SendPlatformMessage = MOCK_ENGINE_PROC( SendPlatformMessage, ([&send_message_called, test_message, dummy_response_handle](auto engine, auto message) { send_message_called = true; EXPECT_STREQ(message->channel, "test"); EXPECT_EQ(message->message_size, test_message.size()); EXPECT_EQ(memcmp(message->message, test_message.data(), message->message_size), 0); EXPECT_EQ(message->response_handle, dummy_response_handle); return kSuccess; })); engine->SendPlatformMessage(channel, test_message.data(), test_message.size(), reply_handler, reply_user_data); EXPECT_TRUE(create_response_handle_called); EXPECT_TRUE(release_response_handle_called); EXPECT_TRUE(send_message_called); } } // namespace testing } // namespace flutter