Skip to content
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
2 changes: 1 addition & 1 deletion common/config.gni
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ if (slimpeller) {
feature_defines_list += [ "SLIMPELLER=1" ]
}

if (is_ios || is_mac || is_android || is_win) {
if (is_android || is_ios || is_linux || is_mac || is_win) {
feature_defines_list += [ "SHOREBIRD_PLATFORM_SUPPORTED=1" ]
}

Expand Down
6 changes: 6 additions & 0 deletions shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ source_set("common") {
]
}
}

if (host_os == "linux" && target_os == "linux") {
if (target_cpu == "x64") {
libs = [ "//third_party/updater/target/x86_64-unknown-linux-gnu/release/libupdater.a" ]
}
}
}

# These are in their own source_set to avoid a dependency cycle with //common/graphics
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,13 @@ source_set("flutter_linux_sources") {

deps = [
"//flutter/fml",
"//flutter/shell/common/shorebird",
"//flutter/shell/platform/common:common_cpp_enums",
"//flutter/shell/platform/common:common_cpp_input",
"//flutter/shell/platform/common:common_cpp_switches",
"//flutter/shell/platform/embedder:embedder_headers",
"//flutter/third_party/rapidjson",
"//flutter/third_party/tonic",
]
}

Expand Down
80 changes: 77 additions & 3 deletions shell/platform/linux/fl_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@

#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"

#include <glib.h>
#include <gmodule.h>

#include <cstring>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "flutter/common/constants.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/paths.h"
#include "flutter/shell/common/shorebird/shorebird.h"
#include "flutter/shell/platform/common/engine_switches.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
Expand All @@ -25,6 +31,8 @@
#include "flutter/shell/platform/linux/fl_texture_gl_private.h"
#include "flutter/shell/platform/linux/fl_texture_registrar_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h"
#include "rapidjson/document.h"
#include "third_party/tonic/filesystem/filesystem/file.h"

// Unique number associated with platform tasks.
static constexpr size_t kPlatformTaskRunnerIdentifier = 1;
Expand Down Expand Up @@ -506,6 +514,59 @@ FlRenderer* fl_engine_get_renderer(FlEngine* self) {
return self->renderer;
}

gboolean fl_set_up_shorebird(const char* assets_path, std::string& patch_path) {
auto shorebird_yaml_path =
fml::paths::JoinPaths({assets_path, "shorebird.yaml"});
std::string shorebird_yaml_contents("");
if (!filesystem::ReadFileToString(shorebird_yaml_path,
&shorebird_yaml_contents)) {
FML_LOG(ERROR) << "Failed to read shorebird.yaml.";
return false;
}

// Read appid from shorebird.yaml
std::string appid = "";
std::stringstream ss(shorebird_yaml_contents);
std::string line;
std::string appid_prefix = "appid:";
while (std::getline(ss, line, '\n')) {
if (line.find(appid_prefix) != std::string::npos) {
appid = line.substr(line.find(appid_prefix) + appid_prefix.size());
break;
}
}

std::string code_cache_path =
fml::paths::JoinPaths({g_get_home_dir(), ".shorebird_cache", appid});
auto executable_location = fml::paths::GetExecutableDirectoryPath().second;
auto app_path =
fml::paths::JoinPaths({executable_location, "lib", "libapp.so"});
auto version_json_path = fml::paths::JoinPaths({assets_path, "version.json"});
std::ifstream input(version_json_path);
if (!input) {
return false;
}
std::string json_contents{std::istreambuf_iterator<char>(input),
std::istreambuf_iterator<char>()};

rapidjson::Document json_doc;
json_doc.Parse(json_contents.c_str());
if (json_doc.HasParseError()) {
// Could not parse version file, aborting.
return false;
}

const auto version_map = json_doc.GetObject();
flutter::ReleaseVersion release_version{
version_map["version"].GetString(),
version_map["build_number"].GetString()};

flutter::ShorebirdConfigArgs shorebird_args(code_cache_path, code_cache_path,
app_path, shorebird_yaml_contents,
release_version);
return ConfigureShorebird(shorebird_args, patch_path);
}

gboolean fl_engine_start(FlEngine* self, GError** error) {
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);

Expand Down Expand Up @@ -538,8 +599,8 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {

g_autoptr(GPtrArray) command_line_args = fl_engine_get_switches(self);
// FlutterProjectArgs expects 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 switches are used.
// the first item is treated as the executable and ignored. Add a dummy
// value so that all switches are used.
g_ptr_array_insert(command_line_args, 0, g_strdup("flutter"));

gchar** dart_entrypoint_args =
Expand Down Expand Up @@ -573,9 +634,22 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
args.compositor = &compositor;

if (self->embedder_api.RunsAOTCompiledDartCode()) {
// This struct contains raw C strings and needs to have its lifetime scoped
// to this block.
FlutterEngineAOTDataSource source = {};
source.type = kFlutterEngineAOTDataSourceTypeElfPath;
source.elf_path = fl_dart_project_get_aot_library_path(self->project);
std::string patch_path;
auto setup_shorebird_result =
fl_set_up_shorebird(args.assets_path, patch_path);
if (setup_shorebird_result) {
// If we have a patch installed, we replace the default AOT library path
// with the patch path here.
source.elf_path = patch_path.c_str();
} else {
FML_LOG(ERROR) << "Failed to configure Shorebird.";
source.elf_path = fl_dart_project_get_aot_library_path(self->project);
}

if (self->embedder_api.CreateAOTData(&source, &self->aot_data) !=
kSuccess) {
g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
Expand Down