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
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,7 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/component_v1.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/component_v1_unittest.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/component_v2.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/component_v2.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/component_v2_unittest.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/engine.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/engine.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/file_in_namespace_buffer.cc
Expand Down Expand Up @@ -1497,6 +1498,7 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/platform_view_unittest.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/pointer_delegate.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/pointer_delegate.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/pointer_delegate_unittests.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/program_metadata.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_tzdata_unittest.cc
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/fuchsia/flutter/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ template("runner_sources") {
"platform_view.h",
"pointer_delegate.cc",
"pointer_delegate.h",
"program_metadata.h",
"runner.cc",
"runner.h",
"surface.cc",
Expand Down Expand Up @@ -459,6 +460,7 @@ if (enable_unittests) {
sources = [
"accessibility_bridge_unittest.cc",
"component_v1_unittest.cc",
"component_v2_unittest.cc",
"flutter_runner_fakes.h",
"focus_delegate_unittests.cc",
"fuchsia_intl_unittest.cc",
Expand Down
46 changes: 30 additions & 16 deletions shell/platform/fuchsia/flutter/component_v1.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ namespace {

constexpr char kDataKey[] = "data";
constexpr char kAssetsKey[] = "assets";
constexpr char kOldGenHeapSizeKey[] = "old_gen_heap_size";

constexpr char kTmpPath[] = "/tmp";
constexpr char kServiceRootPath[] = "/svc";
constexpr char kRunnerConfigPath[] = "/config/data/flutter_runner_config";
Expand All @@ -59,25 +61,35 @@ std::string DebugLabelForUrl(const std::string& url) {

} // namespace

void ComponentV1::ParseProgramMetadata(
const fidl::VectorPtr<fuchsia::sys::ProgramMetadata>& program_metadata,
std::string* data_path,
std::string* assets_path) {
ProgramMetadata ComponentV1::ParseProgramMetadata(
const fidl::VectorPtr<fuchsia::sys::ProgramMetadata>& program_metadata) {
ProgramMetadata result;
if (!program_metadata.has_value()) {
return;
return result;
}

for (const auto& pg : *program_metadata) {
if (pg.key.compare(kDataKey) == 0) {
*data_path = "pkg/" + pg.value;
result.data_path = "pkg/" + pg.value;
} else if (pg.key.compare(kAssetsKey) == 0) {
*assets_path = "pkg/" + pg.value;
result.assets_path = "pkg/" + pg.value;
} else if (pg.key.compare(kOldGenHeapSizeKey) == 0) {
int64_t specified_old_gen_heap_size =
strtol(pg.value.c_str(), nullptr /* endptr */, 10 /* base */);
if (specified_old_gen_heap_size != 0) {
result.old_gen_heap_size = specified_old_gen_heap_size;
} else {
FML_LOG(ERROR) << "Invalid old_gen_heap_size: " << pg.value;
}
}
}

// assets_path defaults to the same as data_path if omitted.
if (assets_path->empty()) {
*assets_path = *data_path;
if (result.assets_path.empty()) {
result.assets_path = result.data_path;
}

return result;
}

ActiveComponentV1 ComponentV1::Create(
Expand Down Expand Up @@ -128,12 +140,10 @@ ComponentV1::ComponentV1(
settings_.dart_entrypoint_args = arguments.value();
}

// Determine where data and assets are stored within /pkg.
std::string data_path;
std::string assets_path;
ParseProgramMetadata(startup_info.program_metadata, &data_path, &assets_path);
const ProgramMetadata metadata =
ParseProgramMetadata(startup_info.program_metadata);

if (data_path.empty()) {
if (metadata.data_path.empty()) {
FML_DLOG(ERROR) << "Could not find a /pkg/data directory for "
<< package.resolved_url;
return;
Expand Down Expand Up @@ -172,11 +182,11 @@ ComponentV1::ComponentV1(
constexpr mode_t mode = O_RDONLY | O_DIRECTORY;

component_assets_directory_.reset(
openat(ns_fd.get(), assets_path.c_str(), mode));
openat(ns_fd.get(), metadata.assets_path.c_str(), mode));
FML_DCHECK(component_assets_directory_.is_valid());

component_data_directory_.reset(
openat(ns_fd.get(), data_path.c_str(), mode));
openat(ns_fd.get(), metadata.data_path.c_str(), mode));
FML_DCHECK(component_data_directory_.is_valid());
}

Expand Down Expand Up @@ -380,6 +390,10 @@ ComponentV1::ComponentV1(

settings_.log_tag = debug_label_ + std::string{"(flutter)"};

if (metadata.old_gen_heap_size.has_value()) {
settings_.old_gen_heap_size = *metadata.old_gen_heap_size;
}

// No asserts in debug or release product.
// No asserts in release with flutter_profile=true (non-product)
// Yes asserts in non-product debug.
Expand Down
7 changes: 3 additions & 4 deletions shell/platform/fuchsia/flutter/component_v1.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "engine.h"
#include "flutter_runner_product_configuration.h"
#include "program_metadata.h"
#include "unique_fdio_ns.h"

namespace flutter_runner {
Expand Down Expand Up @@ -69,10 +70,8 @@ class ComponentV1 final : public Engine::Delegate,
// may be collected after.
~ComponentV1();

static void ParseProgramMetadata(
const fidl::VectorPtr<fuchsia::sys::ProgramMetadata>& program_metadata,
std::string* data_path,
std::string* assets_path);
static ProgramMetadata ParseProgramMetadata(
const fidl::VectorPtr<fuchsia::sys::ProgramMetadata>& program_metadata);

const std::string& GetDebugLabel() const;

Expand Down
53 changes: 33 additions & 20 deletions shell/platform/fuchsia/flutter/component_v1_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,59 @@
#include "component_v1.h"

#include <gtest/gtest.h>
#include <optional>

namespace flutter_runner {
namespace {

TEST(ComponentV1, ParseProgramMetadata) {
std::string data_path;
std::string assets_path;

// The ProgramMetadata field may be null. We should parse this as if no
// fields were specified.
ComponentV1::ParseProgramMetadata(nullptr, &data_path, &assets_path);
ProgramMetadata result = ComponentV1::ParseProgramMetadata(nullptr);

EXPECT_EQ(data_path, "");
EXPECT_EQ(assets_path, "");
EXPECT_EQ(result.data_path, "");
EXPECT_EQ(result.assets_path, "");
EXPECT_EQ(result.old_gen_heap_size, std::nullopt);

// The ProgramMetadata field may be empty. Treat this the same as null.
fidl::VectorPtr<fuchsia::sys::ProgramMetadata> program_metadata(size_t{0});
result = ComponentV1::ParseProgramMetadata(program_metadata);

ComponentV1::ParseProgramMetadata(program_metadata, &data_path, &assets_path);

EXPECT_EQ(data_path, "");
EXPECT_EQ(assets_path, "");
EXPECT_EQ(result.data_path, "");
EXPECT_EQ(result.assets_path, "");
EXPECT_EQ(result.old_gen_heap_size, std::nullopt);

// The assets_path defaults to the "data" value if unspecified
// The assets_path defaults to the "data" value if unspecified.
program_metadata = {{"data", "foobar"}};
result = ComponentV1::ParseProgramMetadata(program_metadata);

ComponentV1::ParseProgramMetadata(program_metadata, &data_path, &assets_path);
EXPECT_EQ(result.data_path, "pkg/foobar");
EXPECT_EQ(result.assets_path, "pkg/foobar");
EXPECT_EQ(result.old_gen_heap_size, std::nullopt);

EXPECT_EQ(data_path, "pkg/foobar");
EXPECT_EQ(assets_path, "pkg/foobar");
// Invalid keys are ignored.
program_metadata = {{"not_data", "foo"}, {"data", "bar"}, {"assets", "baz"}};
result = ComponentV1::ParseProgramMetadata(program_metadata);

data_path = "";
assets_path = "";
EXPECT_EQ(result.data_path, "pkg/bar");
EXPECT_EQ(result.assets_path, "pkg/baz");
EXPECT_EQ(result.old_gen_heap_size, std::nullopt);

program_metadata = {{"not_data", "foo"}, {"data", "bar"}, {"assets", "baz"}};
// The old_gen_heap_size can be specified.
program_metadata = {{"old_gen_heap_size", "100"}};
result = ComponentV1::ParseProgramMetadata(program_metadata);

EXPECT_EQ(result.data_path, "");
EXPECT_EQ(result.assets_path, "");
EXPECT_EQ(result.old_gen_heap_size, 100);

ComponentV1::ParseProgramMetadata(program_metadata, &data_path, &assets_path);
// Invalid old_gen_heap_sizes should be ignored.
program_metadata = {{"old_gen_heap_size", "asdf100"}};
result = ComponentV1::ParseProgramMetadata(program_metadata);

EXPECT_EQ(data_path, "pkg/bar");
EXPECT_EQ(assets_path, "pkg/baz");
EXPECT_EQ(result.data_path, "");
EXPECT_EQ(result.assets_path, "");
EXPECT_EQ(result.old_gen_heap_size, std::nullopt);
}

} // anonymous namespace
Expand Down
68 changes: 53 additions & 15 deletions shell/platform/fuchsia/flutter/component_v2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <sstream>

#include "file_in_namespace_buffer.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/platform/fuchsia/task_observers.h"
#include "flutter/fml/synchronization/waitable_event.h"
Expand All @@ -42,8 +43,15 @@
namespace flutter_runner {
namespace {

// "data" and "assets" are arguments that are specific to the Flutter runner.
// They will likely go away if we migrate to the ELF runner.
constexpr char kDataKey[] = "data";
constexpr char kAssetsKey[] = "assets";

// "args" are how the component specifies arguments to the runner.
constexpr char kArgsKey[] = "args";
constexpr char kOldGenHeapSizeKey[] = "old_gen_heap_size";

constexpr char kTmpPath[] = "/tmp";
constexpr char kServiceRootPath[] = "/svc";
constexpr char kRunnerConfigPath[] = "/config/data/flutter_runner_config";
Expand All @@ -57,24 +65,53 @@ std::string DebugLabelForUrl(const std::string& url) {
}
}

/// Parses the |args| field from the "program" field into
/// |metadata|.
void ParseArgs(std::vector<std::string>& args, ProgramMetadata* metadata) {
// fml::CommandLine expects the first argument to be the name of the program,
// so we prepend a dummy argument so we can use fml::CommandLine to parse the
// arguments for us.
std::vector<std::string> command_line_args = {""};
command_line_args.insert(command_line_args.end(), args.begin(), args.end());
fml::CommandLine parsed_args = fml::CommandLineFromIterators(
command_line_args.begin(), command_line_args.end());

std::string old_gen_heap_size_option;
if (parsed_args.GetOptionValue(kOldGenHeapSizeKey,
&old_gen_heap_size_option)) {
int64_t specified_old_gen_heap_size = strtol(
old_gen_heap_size_option.c_str(), nullptr /* endptr */, 10 /* base */);
if (specified_old_gen_heap_size != 0) {
metadata->old_gen_heap_size = specified_old_gen_heap_size;
} else {
FML_LOG(ERROR) << "Invalid old_gen_heap_size: "
<< old_gen_heap_size_option;
}
}
}

} // namespace

void ComponentV2::ParseProgramMetadata(
const fuchsia::data::Dictionary& program_metadata,
std::string* data_path,
std::string* assets_path) {
ProgramMetadata ComponentV2::ParseProgramMetadata(
const fuchsia::data::Dictionary& program_metadata) {
ProgramMetadata result;

for (const auto& entry : program_metadata.entries()) {
if (entry.key.compare(kDataKey) == 0 && entry.value != nullptr) {
*data_path = "pkg/" + entry.value->str();
result.data_path = "pkg/" + entry.value->str();
} else if (entry.key.compare(kAssetsKey) == 0 && entry.value != nullptr) {
*assets_path = "pkg/" + entry.value->str();
result.assets_path = "pkg/" + entry.value->str();
} else if (entry.key.compare(kArgsKey) == 0 && entry.value != nullptr) {
ParseArgs(entry.value->str_vec(), &result);
}
}

// assets_path defaults to the same as data_path if omitted.
if (assets_path->empty()) {
*assets_path = *data_path;
if (result.assets_path.empty()) {
result.assets_path = result.data_path;
}

return result;
}

ActiveComponentV2 ComponentV2::Create(
Expand Down Expand Up @@ -124,12 +161,9 @@ ComponentV2::ComponentV2(
// TODO(fxb/50694): Dart launch arguments.
FML_LOG(WARNING) << "program() arguments are currently ignored (fxb/50694).";

// Determine where data and assets are stored within /pkg.
std::string data_path;
std::string assets_path;
ParseProgramMetadata(start_info.program(), &data_path, &assets_path);
ProgramMetadata metadata = ParseProgramMetadata(start_info.program());

if (data_path.empty()) {
if (metadata.data_path.empty()) {
FML_DLOG(ERROR) << "Could not find a /pkg/data directory for "
<< start_info.resolved_url();
return;
Expand Down Expand Up @@ -181,11 +215,11 @@ ComponentV2::ComponentV2(
constexpr mode_t mode = O_RDONLY | O_DIRECTORY;

component_assets_directory_.reset(
openat(ns_fd.get(), assets_path.c_str(), mode));
openat(ns_fd.get(), metadata.assets_path.c_str(), mode));
FML_DCHECK(component_assets_directory_.is_valid());

component_data_directory_.reset(
openat(ns_fd.get(), data_path.c_str(), mode));
openat(ns_fd.get(), metadata.data_path.c_str(), mode));
FML_DCHECK(component_data_directory_.is_valid());
}

Expand Down Expand Up @@ -398,6 +432,10 @@ ComponentV2::ComponentV2(

settings_.log_tag = debug_label_ + std::string{"(flutter)"};

if (metadata.old_gen_heap_size.has_value()) {
settings_.old_gen_heap_size = *metadata.old_gen_heap_size;
}

// No asserts in debug or release product.
// No asserts in release with flutter_profile=true (non-product)
// Yes asserts in non-product debug.
Expand Down
10 changes: 6 additions & 4 deletions shell/platform/fuchsia/flutter/component_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "engine.h"
#include "flutter_runner_product_configuration.h"
#include "program_metadata.h"
#include "unique_fdio_ns.h"

namespace flutter_runner {
Expand Down Expand Up @@ -74,10 +75,11 @@ class ComponentV2 final
// may be collected after.
~ComponentV2();

static void ParseProgramMetadata(
const fuchsia::data::Dictionary& program_metadata,
std::string* data_path,
std::string* assets_path);
/// Parses the program metadata that was provided for the component.
///
/// |old_gen_heap_size| will be set to -1 if no value was specified.
static ProgramMetadata ParseProgramMetadata(
const fuchsia::data::Dictionary& program_metadata);

const std::string& GetDebugLabel() const;

Expand Down
Loading