Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,7 @@ FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle_unittests.c
FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine_unittests.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.h
FILE: ../../../flutter/shell/platform/windows/key_event_handler.cc
Expand Down
6 changes: 6 additions & 0 deletions shell/platform/windows/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ source_set("flutter_windows_source") {

public_configs = [ ":relative_angle_headers" ]

defines = [ "FLUTTER_ENGINE_NO_PROTOTYPES" ]

deps = [
":flutter_windows_headers",
"//flutter/shell/platform/common/cpp:common_cpp",
Expand Down Expand Up @@ -123,8 +125,10 @@ executable("flutter_windows_unittests") {

sources = [
"flutter_project_bundle_unittests.cc",
"flutter_windows_engine_unittests.cc",
"string_conversion_unittests.cc",
"system_utils_unittests.cc",
"testing/engine_embedder_api_modifier.h",
"testing/mock_win32_window.cc",
"testing/mock_win32_window.h",
"testing/win32_flutter_window_test.cc",
Expand All @@ -141,6 +145,8 @@ executable("flutter_windows_unittests") {
":flutter_windows_fixtures",
":flutter_windows_headers",
":flutter_windows_source",
"//flutter/shell/platform/embedder:embedder_as_internal_library",
"//flutter/shell/platform/embedder:embedder_test_utils",
"//flutter/testing",
"//third_party/rapidjson",
]
Expand Down
13 changes: 7 additions & 6 deletions shell/platform/windows/flutter_project_bundle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,30 @@ bool FlutterProjectBundle::HasValidPaths() {

// Attempts to load AOT data from the given path, which must be absolute and
// non-empty. Logs and returns nullptr on failure.
UniqueAotDataPtr FlutterProjectBundle::LoadAotData() {
UniqueAotDataPtr FlutterProjectBundle::LoadAotData(
const FlutterEngineProcTable& engine_procs) {
if (aot_library_path_.empty()) {
std::cerr
<< "Attempted to load AOT data, but no aot_library_path was provided."
<< std::endl;
return nullptr;
return UniqueAotDataPtr(nullptr, nullptr);
}
if (!std::filesystem::exists(aot_library_path_)) {
std::cerr << "Can't load AOT data from " << aot_library_path_.u8string()
<< "; no such file." << std::endl;
return nullptr;
return UniqueAotDataPtr(nullptr, nullptr);
}
std::string path_string = aot_library_path_.u8string();
FlutterEngineAOTDataSource source = {};
source.type = kFlutterEngineAOTDataSourceTypeElfPath;
source.elf_path = path_string.c_str();
FlutterEngineAOTData data = nullptr;
auto result = FlutterEngineCreateAOTData(&source, &data);
auto result = engine_procs.CreateAOTData(&source, &data);
if (result != kSuccess) {
std::cerr << "Failed to load AOT data from: " << path_string << std::endl;
return nullptr;
return UniqueAotDataPtr(nullptr, nullptr);
}
return UniqueAotDataPtr(data);
return UniqueAotDataPtr(data, engine_procs.CollectAOTData);
}

FlutterProjectBundle::~FlutterProjectBundle() {}
Expand Down
10 changes: 3 additions & 7 deletions shell/platform/windows/flutter_project_bundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@

namespace flutter {

struct AotDataDeleter {
void operator()(FlutterEngineAOTData aot_data) {
FlutterEngineCollectAOTData(aot_data);
}
};
using UniqueAotDataPtr = std::unique_ptr<_FlutterEngineAOTData, AotDataDeleter>;
using UniqueAotDataPtr =
std::unique_ptr<_FlutterEngineAOTData, FlutterEngineCollectAOTDataFnPtr>;

// The data associated with a Flutter project needed to run it in an engine.
class FlutterProjectBundle {
Expand Down Expand Up @@ -49,7 +45,7 @@ class FlutterProjectBundle {
// retained until any engine instance it is passed to has been shut down.
//
// Logs and returns nullptr on failure.
UniqueAotDataPtr LoadAotData();
UniqueAotDataPtr LoadAotData(const FlutterEngineProcTable& engine_procs);

// Returns the command line arguments to be passed through to the Dart
// entrypoint.
Expand Down
34 changes: 4 additions & 30 deletions shell/platform/windows/flutter_windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine) {
}

void FlutterDesktopEngineReloadSystemFonts(FlutterDesktopEngineRef engine) {
FlutterEngineReloadSystemFonts(EngineFromHandle(engine)->engine());
EngineFromHandle(engine)->ReloadSystemFonts();
}

FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(
Expand Down Expand Up @@ -217,33 +217,8 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
const size_t message_size,
const FlutterDesktopBinaryReply reply,
void* user_data) {
FlutterPlatformMessageResponseHandle* response_handle = nullptr;
if (reply != nullptr && user_data != nullptr) {
FlutterEngineResult result = FlutterPlatformMessageCreateResponseHandle(
messenger->engine->engine(), reply, user_data, &response_handle);
if (result != kSuccess) {
std::cout << "Failed to create response handle\n";
return false;
}
}

FlutterPlatformMessage platform_message = {
sizeof(FlutterPlatformMessage),
channel,
message,
message_size,
response_handle,
};

FlutterEngineResult message_result = FlutterEngineSendPlatformMessage(
messenger->engine->engine(), &platform_message);

if (response_handle != nullptr) {
FlutterPlatformMessageReleaseResponseHandle(messenger->engine->engine(),
response_handle);
}

return message_result == kSuccess;
return messenger->engine->SendPlatformMessage(channel, message, message_size,
reply, user_data);
}

bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger,
Expand All @@ -259,8 +234,7 @@ void FlutterDesktopMessengerSendResponse(
const FlutterDesktopMessageResponseHandle* handle,
const uint8_t* data,
size_t data_length) {
FlutterEngineSendPlatformMessageResponse(messenger->engine->engine(), handle,
data, data_length);
messenger->engine->SendPlatformMessageResponse(handle, data, data_length);
}

void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
Expand Down
83 changes: 73 additions & 10 deletions shell/platform/windows/flutter_windows_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,20 @@ FlutterLocale CovertToFlutterLocale(const LanguageInfo& info) {
} // namespace

FlutterWindowsEngine::FlutterWindowsEngine(const FlutterProjectBundle& project)
: project_(std::make_unique<FlutterProjectBundle>(project)) {
: project_(std::make_unique<FlutterProjectBundle>(project)),
aot_data_(nullptr, nullptr) {
embedder_api_.struct_size = sizeof(FlutterEngineProcTable);
FlutterEngineGetProcAddresses(&embedder_api_);

task_runner_ = std::make_unique<Win32TaskRunner>(
GetCurrentThreadId(), [this](const auto* task) {
GetCurrentThreadId(), embedder_api_.GetCurrentTime,
[this](const auto* task) {
if (!engine_) {
std::cerr << "Cannot post an engine task when engine is not running."
<< std::endl;
return;
}
if (FlutterEngineRunTask(engine_, task) != kSuccess) {
if (embedder_api_.RunTask(engine_, task) != kSuccess) {
std::cerr << "Failed to post an engine task." << std::endl;
}
});
Expand Down Expand Up @@ -126,8 +131,8 @@ bool FlutterWindowsEngine::RunWithEntrypoint(const char* entrypoint) {
}
std::string assets_path_string = project_->assets_path().u8string();
std::string icu_path_string = project_->icu_path().u8string();
if (FlutterEngineRunsAOTCompiledDartCode()) {
aot_data_ = project_->LoadAotData();
if (embedder_api_.RunsAOTCompiledDartCode()) {
aot_data_ = project_->LoadAotData(embedder_api_);
if (!aot_data_) {
std::cerr << "Unable to start engine without AOT data." << std::endl;
return false;
Expand Down Expand Up @@ -193,8 +198,8 @@ bool FlutterWindowsEngine::RunWithEntrypoint(const char* entrypoint) {

FlutterRendererConfig renderer_config = GetRendererConfig();

auto result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &renderer_config,
&args, this, &engine_);
auto result = embedder_api_.Run(FLUTTER_ENGINE_VERSION, &renderer_config,
&args, this, &engine_);
if (result != kSuccess || engine_ == nullptr) {
std::cerr << "Failed to start Flutter engine: error " << result
<< std::endl;
Expand All @@ -211,7 +216,7 @@ bool FlutterWindowsEngine::Stop() {
if (plugin_registrar_destruction_callback_) {
plugin_registrar_destruction_callback_(plugin_registrar_.get());
}
FlutterEngineResult result = FlutterEngineShutdown(engine_);
FlutterEngineResult result = embedder_api_.Shutdown(engine_);
engine_ = nullptr;
return (result == kSuccess);
}
Expand All @@ -232,6 +237,60 @@ void FlutterWindowsEngine::SetPluginRegistrarDestructionCallback(
plugin_registrar_destruction_callback_ = callback;
}

void FlutterWindowsEngine::SendWindowMetricsEvent(
const FlutterWindowMetricsEvent& event) {
if (engine_) {
embedder_api_.SendWindowMetricsEvent(engine_, &event);
}
}

void FlutterWindowsEngine::SendPointerEvent(const FlutterPointerEvent& event) {
if (engine_) {
embedder_api_.SendPointerEvent(engine_, &event, 1);
}
}

bool FlutterWindowsEngine::SendPlatformMessage(
const char* channel,
const uint8_t* message,
const size_t message_size,
const FlutterDesktopBinaryReply reply,
void* user_data) {
FlutterPlatformMessageResponseHandle* response_handle = nullptr;
if (reply != nullptr && user_data != nullptr) {
FlutterEngineResult result =
embedder_api_.PlatformMessageCreateResponseHandle(
engine_, reply, user_data, &response_handle);
if (result != kSuccess) {
std::cout << "Failed to create response handle\n";
return false;
}
}

FlutterPlatformMessage platform_message = {
sizeof(FlutterPlatformMessage),
channel,
message,
message_size,
response_handle,
};

FlutterEngineResult message_result =
embedder_api_.SendPlatformMessage(engine_, &platform_message);
if (response_handle != nullptr) {
embedder_api_.PlatformMessageReleaseResponseHandle(engine_,
response_handle);
}
return message_result == kSuccess;
}

void FlutterWindowsEngine::SendPlatformMessageResponse(
const FlutterDesktopMessageResponseHandle* handle,
const uint8_t* data,
size_t data_length) {
embedder_api_.SendPlatformMessageResponse(engine_, handle, data, data_length);
}

void FlutterWindowsEngine::HandlePlatformMessage(
const FlutterPlatformMessage* engine_message) {
if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) {
Expand All @@ -247,6 +306,10 @@ void FlutterWindowsEngine::HandlePlatformMessage(
message, [this] {}, [this] {});
}

void FlutterWindowsEngine::ReloadSystemFonts() {
embedder_api_.ReloadSystemFonts(engine_);
}

void FlutterWindowsEngine::SendSystemSettings() {
std::vector<LanguageInfo> languages = GetPreferredLanguageInfo();
std::vector<FlutterLocale> flutter_locales;
Expand All @@ -261,8 +324,8 @@ void FlutterWindowsEngine::SendSystemSettings() {
flutter_locales.begin(), flutter_locales.end(),
std::back_inserter(flutter_locale_list),
[](const auto& arg) -> const auto* { return &arg; });
FlutterEngineUpdateLocales(engine_, flutter_locale_list.data(),
flutter_locale_list.size());
embedder_api_.UpdateLocales(engine_, flutter_locale_list.data(),
flutter_locale_list.size());

// TODO: Send 'flutter/settings' channel settings here as well.
}
Expand Down
31 changes: 29 additions & 2 deletions shell/platform/windows/flutter_windows_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>

#include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/windows/flutter_project_bundle.h"
#include "flutter/shell/platform/windows/public/flutter_windows.h"
#include "flutter/shell/platform/windows/win32_task_runner.h"
Expand Down Expand Up @@ -65,8 +66,6 @@ class FlutterWindowsEngine {
void SetPluginRegistrarDestructionCallback(
FlutterDesktopOnPluginRegistrarDestroyed callback);

FLUTTER_API_SYMBOL(FlutterEngine) engine() { return engine_; }

FlutterDesktopMessengerRef messenger() { return messenger_.get(); }

IncomingMessageDispatcher* message_dispatcher() {
Expand All @@ -79,11 +78,37 @@ class FlutterWindowsEngine {
return window_proc_delegate_manager_.get();
}

// Informs the engine that the window metrics have changed.
void SendWindowMetricsEvent(const FlutterWindowMetricsEvent& event);

// Informs the engine of an incoming pointer event.
void SendPointerEvent(const FlutterPointerEvent& event);

// Sends the given message to the engine, calling |reply| with |user_data|
// when a reponse is received from the engine if they are non-null.
bool SendPlatformMessage(const char* channel,
const uint8_t* message,
const size_t message_size,
const FlutterDesktopBinaryReply reply,
void* user_data);

// Sends the given data as the response to an earlier platform message.
void SendPlatformMessageResponse(
const FlutterDesktopMessageResponseHandle* handle,
const uint8_t* data,
size_t data_length);

// Callback passed to Flutter engine for notifying window of platform
// messages.
void HandlePlatformMessage(const FlutterPlatformMessage*);

// Informs the engine that the system font list has changed.
void ReloadSystemFonts();

private:
// Allows swapping out embedder_api_ calls in tests.
friend class EngineEmbedderApiModifier;

// Sends system settings (e.g., locale) to the engine.
//
// Should be called just after the engine is run, and after any relevant
Expand All @@ -93,6 +118,8 @@ class FlutterWindowsEngine {
// The handle to the embedder.h engine instance.
FLUTTER_API_SYMBOL(FlutterEngine) engine_ = nullptr;

FlutterEngineProcTable embedder_api_ = {};

std::unique_ptr<FlutterProjectBundle> project_;

// AOT data, if any.
Expand Down
Loading