Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FlutterDesktopWindowProperties to the public API #133

Merged
Merged
Show file tree
Hide file tree
Changes from 7 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
2 changes: 2 additions & 0 deletions shell/platform/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ _flutter_tizen_source = [
"channels/navigation_channel.cc",
"channels/platform_view_channel.cc",
"channels/text_input_channel.cc",
"flutter_project_bundle.cc",
"flutter_tizen.cc",
"flutter_tizen_engine.cc",
"flutter_tizen_texture_registrar.cc",
Expand Down Expand Up @@ -139,6 +140,7 @@ template("embedder_for_profile") {
libs += [
"base-utils-i18n",
"capi-appfw-application",
"capi-appfw-app-common",
"capi-base-common",
"capi-system-info",
"capi-system-system-settings",
Expand Down
1 change: 1 addition & 0 deletions shell/platform/tizen/external_texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <atomic>
#include <memory>

#include "flutter/shell/platform/common/public/flutter_texture_registrar.h"
#include "flutter/shell/platform/embedder/embedder.h"

Expand Down
101 changes: 101 additions & 0 deletions shell/platform/tizen/flutter_project_bundle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved.
// 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_project_bundle.h"

#ifdef __X64_SHELL__
#include "flutter/shell/platform/common/path_utils.h"
#else
#include <app_common.h>
#endif

#include <filesystem>

#include "flutter/shell/platform/tizen/tizen_log.h"

namespace flutter {

#ifndef __X64_SHELL__
namespace {

// Returns the path of the directory containing the app binary, or an empty
// string if the directory cannot be found.
std::filesystem::path GetExecutableDirectory() {
auto res_path = app_get_resource_path();
if (res_path == nullptr) {
return std::filesystem::path();
}
auto bin_path = std::filesystem::path(res_path) / ".." / "bin";
free(res_path);
return bin_path.lexically_normal();
}

} // namespace
#endif

FlutterProjectBundle::FlutterProjectBundle(
const FlutterDesktopEngineProperties& properties)
: assets_path_(properties.assets_path),
icu_path_(properties.icu_data_path) {
if (properties.aot_library_path != nullptr) {
aot_library_path_ = std::filesystem::path(properties.aot_library_path);
}

// Resolve any relative paths.
if (assets_path_.is_relative() || icu_path_.is_relative() ||
(!aot_library_path_.empty() && aot_library_path_.is_relative())) {
std::filesystem::path executable_location = GetExecutableDirectory();
if (executable_location.empty()) {
FT_LOGE("Unable to find executable location to resolve resource paths.");
assets_path_ = std::filesystem::path();
icu_path_ = std::filesystem::path();
} else {
assets_path_ = std::filesystem::path(executable_location) / assets_path_;
icu_path_ = std::filesystem::path(executable_location) / icu_path_;
if (!aot_library_path_.empty()) {
aot_library_path_ =
std::filesystem::path(executable_location) / aot_library_path_;
}
}
}

switches_.insert(switches_.end(), properties.switches,
properties.switches + properties.switches_count);
}

bool FlutterProjectBundle::HasValidPaths() {
return !assets_path_.empty() && !icu_path_.empty();
}

// 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(
const FlutterEngineProcTable& engine_procs) {
if (aot_library_path_.empty()) {
FT_LOGE(
"Attempted to load AOT data, but no aot_library_path was provided.");
return UniqueAotDataPtr(nullptr, nullptr);
}
if (!std::filesystem::exists(aot_library_path_)) {
FT_LOGE("Can't load AOT data from %s; no such file.",
aot_library_path_.u8string().c_str());
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 = engine_procs.CreateAOTData(&source, &data);
if (result != kSuccess) {
FT_LOGE("Failed to load AOT data from: %s", path_string.c_str());
return UniqueAotDataPtr(nullptr, nullptr);
}
return UniqueAotDataPtr(data, engine_procs.CollectAOTData);
}

FlutterProjectBundle::~FlutterProjectBundle() {}

} // namespace flutter
62 changes: 62 additions & 0 deletions shell/platform/tizen/flutter_project_bundle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved.
// 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.

#ifndef EMBEDDER_FLUTTER_PROJECT_BUNDLE_H_
#define EMBEDDER_FLUTTER_PROJECT_BUNDLE_H_

#include <filesystem>
#include <string>
#include <vector>

#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/tizen/public/flutter_tizen.h"

namespace flutter {

using UniqueAotDataPtr =
std::unique_ptr<_FlutterEngineAOTData, FlutterEngineCollectAOTDataFnPtr>;

// The data associated with a Flutter project needed to run it in an engine.
class FlutterProjectBundle {
public:
// Creates a new project bundle from the given properties.
//
// Treats any relative paths as relative to the directory of the app binary.
explicit FlutterProjectBundle(
const FlutterDesktopEngineProperties& properties);

~FlutterProjectBundle();

// Whether or not the bundle is valid. This does not check that the paths
// exist, or contain valid data, just that paths were able to be constructed.
bool HasValidPaths();

// Returns the path to the assets directory.
const std::filesystem::path& assets_path() { return assets_path_; }

// Returns the path to the ICU data file.
const std::filesystem::path& icu_path() { return icu_path_; }

// Returns any switches that should be passed to the engine.
const std::vector<std::string> switches() { return switches_; }

// Attempts to load AOT data for this bundle. The returned data must be
// retained until any engine instance it is passed to has been shut down.
//
// Logs and returns nullptr on failure.
UniqueAotDataPtr LoadAotData(const FlutterEngineProcTable& engine_procs);

private:
std::filesystem::path assets_path_;
std::filesystem::path icu_path_;
std::vector<std::string> switches_ = {};

// Path to the AOT library file, if any.
std::filesystem::path aot_library_path_;
};

} // namespace flutter

#endif // EMBEDDER_FLUTTER_PROJECT_BUNDLE_H_
15 changes: 11 additions & 4 deletions shell/platform/tizen/flutter_tizen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h"
#include "flutter/shell/platform/common/incoming_message_dispatcher.h"
#include "flutter/shell/platform/tizen/flutter_project_bundle.h"
#include "flutter/shell/platform/tizen/flutter_tizen_engine.h"
#include "flutter/shell/platform/tizen/public/flutter_platform_view.h"
#include "flutter/shell/platform/tizen/tizen_log.h"
Expand All @@ -25,12 +26,18 @@ static FlutterDesktopEngineRef HandleForEngine(
}

FlutterDesktopEngineRef FlutterDesktopRunEngine(
const FlutterDesktopEngineProperties& engine_properties,
bool headed) {
const FlutterDesktopWindowProperties& window_properties,
const FlutterDesktopEngineProperties& engine_properties) {
flutter::StartLogging();

auto engine = std::make_unique<flutter::FlutterTizenEngine>(headed);
if (!engine->RunEngine(engine_properties)) {
flutter::FlutterProjectBundle project(engine_properties);
auto engine = std::make_unique<flutter::FlutterTizenEngine>(project);
if (window_properties.headed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this part! ❤️ It's much more intuitive. Thanks

engine->InitializeRenderer(window_properties.x, window_properties.y,
window_properties.width,
window_properties.height);
}
if (!engine->RunEngine()) {
FT_LOGE("Failed to run the Flutter engine.");
return nullptr;
}
Expand Down
97 changes: 42 additions & 55 deletions shell/platform/tizen/flutter_tizen_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "flutter_tizen_engine.h"

#include <filesystem>
#include <algorithm>
#include <string>
#include <vector>

Expand Down Expand Up @@ -33,7 +33,9 @@ constexpr double kProfileFactor = 1.0;

} // namespace

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

Expand All @@ -55,19 +57,20 @@ FlutterTizenEngine::FlutterTizenEngine(bool headed) {

plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
plugin_registrar_->engine = this;

if (headed) {
InitializeRenderer();
}
}

FlutterTizenEngine::~FlutterTizenEngine() {
renderer = nullptr;
}

void FlutterTizenEngine::InitializeRenderer() {
void FlutterTizenEngine::InitializeRenderer(int32_t x,
int32_t y,
int32_t width,
int32_t height) {
TizenRenderer::WindowGeometry geometry = {x, y, width, height};

#ifdef TIZEN_RENDERER_EVAS_GL
renderer = std::make_unique<TizenRendererEvasGL>(*this);
renderer = std::make_unique<TizenRendererEvasGL>(geometry, *this);

render_loop_ = std::make_unique<TizenRenderEventLoop>(
std::this_thread::get_id(), // main thread
Expand All @@ -78,7 +81,7 @@ void FlutterTizenEngine::InitializeRenderer() {
},
renderer.get());
#else
renderer = std::make_unique<TizenRendererEcoreWl2>(*this);
renderer = std::make_unique<TizenRendererEcoreWl2>(geometry, *this);

tizen_vsync_waiter_ = std::make_unique<TizenVsyncWaiter>(this);
#endif
Expand All @@ -88,52 +91,42 @@ void FlutterTizenEngine::NotifyLowMemoryWarning() {
embedder_api_.NotifyLowMemoryWarning(engine_);
}

// Attempts to load AOT data from the given path, which must be absolute and
// non-empty. Logs and returns nullptr on failure.
UniqueAotDataPtr FlutterTizenEngine::LoadAotData(std::string aot_data_path) {
if (aot_data_path.empty()) {
FT_LOGE(
"Attempted to load AOT data, but no aot_library_path was provided.");
return nullptr;
}
if (!std::filesystem::exists(aot_data_path)) {
FT_LOGE("Can't load AOT data from %s; no such file.",
aot_data_path.c_str());
return nullptr;
}
FlutterEngineAOTDataSource source = {};
source.type = kFlutterEngineAOTDataSourceTypeElfPath;
source.elf_path = aot_data_path.c_str();
FlutterEngineAOTData data = nullptr;
auto result = embedder_api_.CreateAOTData(&source, &data);
if (result != kSuccess) {
FT_LOGE("Failed to load AOT data from: %s", aot_data_path.c_str());
return nullptr;
bool FlutterTizenEngine::RunEngine() {
if (engine_ != nullptr) {
FT_LOGE("The engine has already started.");
return false;
}
return UniqueAotDataPtr(data);
}

bool FlutterTizenEngine::RunEngine(
const FlutterDesktopEngineProperties& engine_properties) {
if (IsHeaded() && !renderer->IsValid()) {
FT_LOGE("The display was not valid.");
return false;
}

if (!project_->HasValidPaths()) {
FT_LOGE("Missing or unresolvable paths to assets.");
return false;
}
std::string assets_path_string = project_->assets_path().u8string();
std::string icu_path_string = project_->icu_path().u8string();
if (embedder_api_.RunsAOTCompiledDartCode()) {
aot_data_ = project_->LoadAotData(embedder_api_);
if (!aot_data_) {
FT_LOGE("Unable to start engine without AOT data.");
return false;
}
}

// FlutterProjectArgs is expecting a full argv, so when processing it for
// flags the first item is treated as the executable and ignored. Add a dummy
// value so that all provided arguments are used.
std::vector<std::string> switches = project_->switches();
std::vector<const char*> argv = {"placeholder"};
if (engine_properties.switches_count > 0) {
argv.insert(argv.end(), &engine_properties.switches[0],
&engine_properties.switches[engine_properties.switches_count]);
}
std::transform(
switches.begin(), switches.end(), std::back_inserter(argv),
[](const std::string& arg) -> const char* { return arg.c_str(); });

for (size_t i = 0; i < engine_properties.switches_count; ++i) {
auto str = std::string{engine_properties.switches[i]};
if (str.find("verbose-logging") != std::string::npos) {
SetMinLoggingLevel(DLOG_INFO);
}
if (std::find(switches.begin(), switches.end(), "verbose-logging") !=
switches.end()) {
SetMinLoggingLevel(DLOG_INFO);
}

// Configure task runners.
Expand Down Expand Up @@ -173,10 +166,10 @@ bool FlutterTizenEngine::RunEngine(

FlutterProjectArgs args = {};
args.struct_size = sizeof(FlutterProjectArgs);
args.assets_path = engine_properties.assets_path;
args.icu_data_path = engine_properties.icu_data_path;
args.assets_path = assets_path_string.c_str();
args.icu_data_path = icu_path_string.c_str();
args.command_line_argc = static_cast<int>(argv.size());
args.command_line_argv = &argv[0];
args.command_line_argv = argv.size() > 0 ? argv.data() : nullptr;
args.platform_message_callback =
[](const FlutterPlatformMessage* engine_message, void* user_data) {
if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) {
Expand All @@ -198,13 +191,7 @@ bool FlutterTizenEngine::RunEngine(
};
}
#endif

if (embedder_api_.RunsAOTCompiledDartCode()) {
aot_data_ = LoadAotData(engine_properties.aot_library_path);
if (!aot_data_) {
FT_LOGE("Unable to start engine without AOT data.");
return false;
}
if (aot_data_) {
args.aot_data = aot_data_.get();
}

Expand Down Expand Up @@ -357,7 +344,7 @@ void FlutterTizenEngine::SetWindowOrientation(int32_t degree) {
renderer->SetRotate(degree);
// Compute renderer transformation based on the angle of rotation.
double rad = (360 - degree) * M_PI / 180;
auto geometry = renderer->GetGeometry();
auto geometry = renderer->GetCurrentGeometry();
double width = geometry.w;
double height = geometry.h;

Expand Down
Loading