diff --git a/shell/platform/fuchsia/flutter/component_v2.cc b/shell/platform/fuchsia/flutter/component_v2.cc index e3f6da8a51761..b0683699a0dfc 100644 --- a/shell/platform/fuchsia/flutter/component_v2.cc +++ b/shell/platform/fuchsia/flutter/component_v2.cc @@ -51,6 +51,7 @@ 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 kExposeDirsKey[] = "expose_dirs"; constexpr char kTmpPath[] = "/tmp"; constexpr char kServiceRootPath[] = "/svc"; @@ -88,6 +89,18 @@ void ParseArgs(std::vector& args, ProgramMetadata* metadata) { << old_gen_heap_size_option; } } + + std::string expose_dirs_option; + if (parsed_args.GetOptionValue(kExposeDirsKey, &expose_dirs_option)) { + // Parse the comma delimited string + std::vector expose_dirs; + std::stringstream s(expose_dirs_option); + while (s.good()) { + std::string dir; + getline(s, dir, ','); // get first string delimited by comma + metadata->expose_dirs.push_back(dir); + } + } } } // namespace @@ -258,32 +271,41 @@ ComponentV2::ComponentV2( fuchsia::io::OPEN_RIGHT_WRITABLE, cloned_directory_ptr_.NewRequest()); - cloned_directory_ptr_.events().OnOpen = - [this](zx_status_t status, std::unique_ptr info) { - cloned_directory_ptr_.Unbind(); - if (status != ZX_OK) { - FML_LOG(ERROR) - << "could not bind out directory for flutter component(" - << debug_label_ << "): " << zx_status_get_string(status); - return; - } - const char* other_dirs[] = {"debug", "ctrl", "diagnostics"}; - // add other directories as RemoteDirs. - for (auto& dir_str : other_dirs) { - fuchsia::io::DirectoryHandle dir; - auto request = dir.NewRequest().TakeChannel(); - auto status = fdio_service_connect_at(directory_ptr_.channel().get(), - dir_str, request.release()); - if (status == ZX_OK) { - outgoing_dir_->AddEntry( - dir_str, std::make_unique(dir.TakeChannel())); - } else { - FML_LOG(ERROR) << "could not add out directory entry(" << dir_str - << ") for flutter component(" << debug_label_ - << "): " << zx_status_get_string(status); - } - } - }; + // Collect our standard set of directories along with directories that are + // included in the cml file to expose. + std::vector other_dirs = {"debug", "ctrl", "diagnostics"}; + for (auto dir : metadata.expose_dirs) { + other_dirs.push_back(dir); + } + + cloned_directory_ptr_.events() + .OnOpen = [this, other_dirs]( + zx_status_t status, + std::unique_ptr info) { + cloned_directory_ptr_.Unbind(); + if (status != ZX_OK) { + FML_LOG(ERROR) << "could not bind out directory for flutter component(" + << debug_label_ << "): " << zx_status_get_string(status); + return; + } + + // add other directories as RemoteDirs. + for (auto& dir_str : other_dirs) { + fuchsia::io::DirectoryHandle dir; + auto request = dir.NewRequest().TakeChannel(); + auto status = fdio_service_connect_at(directory_ptr_.channel().get(), + dir_str.c_str(), request.release()); + if (status == ZX_OK) { + outgoing_dir_->AddEntry( + dir_str.c_str(), + std::make_unique(dir.TakeChannel())); + } else { + FML_LOG(ERROR) << "could not add out directory entry(" << dir_str + << ") for flutter component(" << debug_label_ + << "): " << zx_status_get_string(status); + } + } + }; cloned_directory_ptr_.set_error_handler( [this](zx_status_t status) { cloned_directory_ptr_.Unbind(); }); diff --git a/shell/platform/fuchsia/flutter/component_v2_unittest.cc b/shell/platform/fuchsia/flutter/component_v2_unittest.cc index 88cd784bf315e..34c803e7357fb 100644 --- a/shell/platform/fuchsia/flutter/component_v2_unittest.cc +++ b/shell/platform/fuchsia/flutter/component_v2_unittest.cc @@ -103,5 +103,78 @@ TEST(ComponentV2, ParseProgramMetadataOldGenHeapSizeInvalid) { EXPECT_EQ(result.old_gen_heap_size, std::nullopt); } +TEST(ComponentV2, ParseProgramMetadataNoExposeDirs) { + // Should always have a valid expose_dirs entry + std::vector entries; + + fuchsia::data::Dictionary program_metadata; + program_metadata.set_entries(std::move(entries)); + + ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata); + + EXPECT_EQ(result.expose_dirs.empty(), true); +} + +TEST(ComponentV2, ParseProgramMetadataWithSingleExposeDirs) { + // Can parse a single exposed dir + std::vector entries; + + fuchsia::data::DictionaryEntry args_entry; + args_entry.key = "args"; + args_entry.value = std::make_unique( + fuchsia::data::DictionaryValue::WithStrVec({"--expose_dirs=foo"})); + entries.push_back(std::move(args_entry)); + + fuchsia::data::Dictionary program_metadata; + program_metadata.set_entries(std::move(entries)); + + ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata); + + ASSERT_EQ(result.expose_dirs.size(), 1u); + EXPECT_EQ(result.expose_dirs[0], "foo"); +} + +TEST(ComponentV2, ParseProgramMetadataWithMultipleExposeDirs) { + // Can parse a multiple exposed dirs + std::vector entries; + + fuchsia::data::DictionaryEntry args_entry; + args_entry.key = "args"; + args_entry.value = std::make_unique( + fuchsia::data::DictionaryValue::WithStrVec( + {"--expose_dirs=foo,bar,baz"})); + entries.push_back(std::move(args_entry)); + + fuchsia::data::Dictionary program_metadata; + program_metadata.set_entries(std::move(entries)); + + ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata); + + ASSERT_EQ(result.expose_dirs.size(), 3u); + EXPECT_EQ(result.expose_dirs[0], "foo"); + EXPECT_EQ(result.expose_dirs[1], "bar"); + EXPECT_EQ(result.expose_dirs[2], "baz"); +} + +TEST(ComponentV2, ParseProgramMetadataWithSingleExposeDirsAndOtherArgs) { + // Can parse a single exposed dir when other args are present + std::vector entries; + + fuchsia::data::DictionaryEntry args_entry; + args_entry.key = "args"; + args_entry.value = std::make_unique( + fuchsia::data::DictionaryValue::WithStrVec( + {"--expose_dirs=foo", "--foo=bar"})); + entries.push_back(std::move(args_entry)); + + fuchsia::data::Dictionary program_metadata; + program_metadata.set_entries(std::move(entries)); + + ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata); + + ASSERT_EQ(result.expose_dirs.size(), 1u); + EXPECT_EQ(result.expose_dirs[0], "foo"); +} + } // anonymous namespace } // namespace flutter_runner diff --git a/shell/platform/fuchsia/flutter/program_metadata.h b/shell/platform/fuchsia/flutter/program_metadata.h index f7040a2aacb80..8a57ba1bb73b9 100644 --- a/shell/platform/fuchsia/flutter/program_metadata.h +++ b/shell/platform/fuchsia/flutter/program_metadata.h @@ -26,6 +26,9 @@ struct ProgramMetadata { /// The preferred heap size for the Flutter component in megabytes. std::optional old_gen_heap_size = std::nullopt; + + /// A list of additional directories that we will expose in out/ + std::vector expose_dirs; }; } // namespace flutter_runner diff --git a/tools/fuchsia/devshell/serve.sh b/tools/fuchsia/devshell/serve.sh index 537cb96c3244a..694703669bacb 100755 --- a/tools/fuchsia/devshell/serve.sh +++ b/tools/fuchsia/devshell/serve.sh @@ -247,7 +247,7 @@ while true; do config_url="http://${addr}:${port}/config.json" if [[ ${component_framework_version} == 2 ]]; then - run_ssh_command pkgctl repo add \ + run_ssh_command pkgctl repo add url \ -n "engine" \ "${config_url}" else