blob: c0fa9e66822df2ae8b9d74367c47b5f6b6f94c9b [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 "runner.h"
#include <lib/async/default.h>
#include <lib/fsl/io/fd.h>
#include <lib/fxl/files/unique_fd.h>
#include <lib/fxl/logging.h>
#include <lib/pkg_url/fuchsia_pkg_url.h>
#include "garnet/lib/cmx/cmx.h"
namespace netemul {
using component::StartupContext;
static const char* kSandbox =
"fuchsia-pkg://fuchsia.com/netemul_sandbox#meta/netemul_sandbox.cmx";
Runner::Runner(async_dispatcher_t* dispatcher) {
if (dispatcher == nullptr) {
dispatcher = async_get_default_dispatcher();
}
dispatcher_ = dispatcher;
startup_context_ = StartupContext::CreateFromStartupInfo();
startup_context_->ConnectToEnvironmentService(
launcher_.NewRequest(dispatcher_));
startup_context_->ConnectToEnvironmentService(
loader_.NewRequest(dispatcher_));
startup_context_->outgoing().AddPublicService(
bindings_.GetHandler(this, dispatcher_));
}
struct RunnerArgs {
fuchsia::sys::StartupInfo startup_info;
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller;
};
void Runner::StartComponent(
fuchsia::sys::Package package, fuchsia::sys::StartupInfo startup_info,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
FXL_LOG(INFO) << "resolved URL: " << package.resolved_url;
// args needs to be shared ptr 'cause Loader fidl
// uses std::function and not fit::function (i.e. legacy callbacks)
std::shared_ptr<RunnerArgs> args = std::make_shared<RunnerArgs>();
args->startup_info = std::move(startup_info);
args->controller = std::move(controller);
// go through loader to get information, 'cause info is not complete
// from caller (missing directory and other stuff)
loader_->LoadUrl(
package.resolved_url, [this, args](fuchsia::sys::PackagePtr package) {
RunComponent(std::move(package), std::move(args->startup_info),
std::move(args->controller));
});
}
void Runner::RunComponent(
fuchsia::sys::PackagePtr package, fuchsia::sys::StartupInfo startup_info,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
if (!package) {
// TODO(brunodalbo) expose errors correctly through interface request
FXL_LOG(ERROR) << "Can't load package";
return;
}
// extract and parse cmx:
component::FuchsiaPkgUrl fp;
if (!fp.Parse(package->resolved_url)) {
FXL_LOG(ERROR) << "can't parse fuchsia URL " << package->resolved_url;
// TODO(brunodalbo) expose errors correctly through interface request
return;
}
if (!package->directory.is_valid()) {
FXL_LOG(ERROR) << "Package directory not provided";
return;
}
component::CmxMetadata cmx;
fxl::UniqueFD fd =
fsl::OpenChannelAsFileDescriptor(std::move(package->directory));
json::JSONParser json_parser;
if (!cmx.ParseFromFileAt(fd.get(), fp.resource_path(), &json_parser)) {
FXL_LOG(ERROR) << "cmx file failed to parse: " << json_parser.error_str();
// TODO(brunodalbo) expose errors correctly through interface request
return;
}
std::stringstream launchpkg;
launchpkg << "fuchsia-pkg://fuchsia.com/" << fp.package_name() << "#"
<< cmx.program_meta().data();
auto sandbox_arg = launchpkg.str();
auto linfo = std::move(startup_info.launch_info);
linfo.url = kSandbox;
linfo.arguments->push_back(sandbox_arg);
linfo.arguments->insert(linfo.arguments->end(),
startup_info.launch_info.arguments->begin(),
startup_info.launch_info.arguments->end());
launcher_->CreateComponent(std::move(linfo), std::move(controller));
}
} // namespace netemul