未验证 提交 8b04b388 编写于 作者: C Chase Latta 提交者: GitHub

[fuchsia] make dart_runner work with cfv2 (#27226)

Adds support for running the dart runner as a CFv2 component.
The runner has been refactored to launch in both a v1 environemnt
as well as a v2 environment.
上级 7556ed4d
......@@ -1348,9 +1348,14 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/logging.h
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/main.cc
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/aot_product_runtime
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/aot_runtime
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/common.shard.cml
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_aot_product_runner.cml
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_aot_product_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_aot_runner.cml
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_aot_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_jit_product_runner.cml
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_jit_product_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_jit_runner.cml
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_jit_runner.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/dart_zircon_test.cmx
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/meta/jit_product_runtime
......
......@@ -117,10 +117,13 @@ void Initialize(fidl::InterfaceHandle<fuchsia::sys::Environment> environment,
dart_state->class_library().add_provider("fuchsia",
std::move(fuchsia_class_provider));
// v2 components do not use the environment
if (environment) {
result = Dart_SetField(
library, ToDart("_environment"),
ToDart(zircon::dart::Handle::Create(environment.TakeChannel())));
FML_CHECK(!tonic::LogIfError(result));
}
if (directory_request) {
result = Dart_SetField(
......
......@@ -58,6 +58,7 @@ template("runner") {
"//flutter/fml",
"//flutter/shell/platform/fuchsia/dart-pkg/fuchsia",
"//flutter/shell/platform/fuchsia/dart-pkg/zircon",
"$fuchsia_sdk_root/fidl:fuchsia.component.runner",
"$fuchsia_sdk_root/pkg:async",
"$fuchsia_sdk_root/pkg:async-cpp",
"$fuchsia_sdk_root/pkg:async-default",
......@@ -209,6 +210,7 @@ template("jit_runner_package") {
binary = "dart_jit${product_suffix}_runner"
cmx_file = rebase_path("meta/dart_jit${product_suffix}_runner.cmx")
cml_file = rebase_path("meta/dart_jit${product_suffix}_runner.cml")
libraries = common_libs
......
......@@ -37,6 +37,7 @@
#include "third_party/tonic/logging/dart_error.h"
#include "builtin_libraries.h"
#include "flutter/fml/logging.h"
#include "logging.h"
using tonic::ToDart;
......@@ -78,63 +79,29 @@ std::string GetLabelFromURL(const std::string& url) {
return url;
}
} // namespace
DartComponentController::DartComponentController(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
: loop_(new async::Loop(&kLoopConfig)),
label_(GetLabelFromURL(package.resolved_url)),
url_(std::move(package.resolved_url)),
package_(std::move(package)),
startup_info_(std::move(startup_info)),
runner_incoming_services_(runner_incoming_services),
binding_(this) {
for (size_t i = 0; i < startup_info_.program_metadata->size(); ++i) {
auto pg = startup_info_.program_metadata->at(i);
if (pg.key.compare(kDataKey) == 0) {
data_path_ = "pkg/" + pg.value;
}
}
if (data_path_.empty()) {
FX_LOGF(ERROR, LOG_TAG, "Could not find a /pkg/data directory for %s",
url_.c_str());
return;
}
if (controller.is_valid()) {
binding_.Bind(std::move(controller));
binding_.set_error_handler([this](zx_status_t status) { Kill(); });
// Find the name of the component.
// fuchsia-pkg://fuchsia.com/hello_dart#meta/hello_dart.cm -> hello_dart
std::string GetComponentNameFromUrl(const std::string& url) {
auto label = GetLabelFromURL(url);
for (size_t i = 0; i < label.length(); ++i) {
if (label[i] == '.') {
return label.substr(0, i);
}
zx_status_t status =
zx::timer::create(ZX_TIMER_SLACK_LATE, ZX_CLOCK_MONOTONIC, &idle_timer_);
if (status != ZX_OK) {
FX_LOGF(INFO, LOG_TAG, "Idle timer creation failed: %s",
zx_status_get_string(status));
} else {
idle_wait_.set_object(idle_timer_.get());
idle_wait_.set_trigger(ZX_TIMER_SIGNALED);
idle_wait_.Begin(async_get_default_dispatcher());
}
return label;
}
DartComponentController::~DartComponentController() {
if (namespace_) {
fdio_ns_destroy(namespace_);
namespace_ = nullptr;
}
close(stdoutfd_);
close(stderrfd_);
}
} // namespace
bool DartComponentController::Setup() {
// Name the thread after the url of the component being launched.
zx::thread::self()->set_property(ZX_PROP_NAME, label_.c_str(), label_.size());
Dart_SetThreadName(label_.c_str());
if (!SetupNamespace()) {
namespace_ = PrepareNamespace();
if (namespace_ == nullptr) {
FX_LOG(ERROR, LOG_TAG, "Failed to create namespace");
return false;
}
......@@ -156,42 +123,33 @@ bool DartComponentController::Setup() {
constexpr char kTmpPath[] = "/tmp";
constexpr char kServiceRootPath[] = "/svc";
bool DartComponentController::SetupNamespace() {
fuchsia::sys::FlatNamespace* flat = &startup_info_.flat_namespace;
zx_status_t status = fdio_ns_create(&namespace_);
DartComponentController::DartComponentController(
std::string resolved_url,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services)
: runner_incoming_services_(runner_incoming_services),
loop_(new async::Loop(&kLoopConfig)),
label_(GetLabelFromURL(resolved_url)),
url_(resolved_url) {
zx_status_t status =
zx::timer::create(ZX_TIMER_SLACK_LATE, ZX_CLOCK_MONOTONIC, &idle_timer_);
if (status != ZX_OK) {
FX_LOG(ERROR, LOG_TAG, "Failed to create namespace");
return false;
}
dart_utils::RunnerTemp::SetupComponent(namespace_);
for (size_t i = 0; i < flat->paths.size(); ++i) {
if (flat->paths.at(i) == kTmpPath) {
// /tmp is covered by the local memfs.
continue;
}
zx::channel dir;
if (flat->paths.at(i) == kServiceRootPath) {
// clone /svc so component_context can still use it below
dir = zx::channel(fdio_service_clone(flat->directories.at(i).get()));
FX_LOGF(INFO, LOG_TAG, "Idle timer creation failed: %s",
zx_status_get_string(status));
} else {
dir = std::move(flat->directories.at(i));
idle_wait_.set_object(idle_timer_.get());
idle_wait_.set_trigger(ZX_TIMER_SIGNALED);
idle_wait_.Begin(async_get_default_dispatcher());
}
}
zx_handle_t dir_handle = dir.release();
const char* path = flat->paths.at(i).data();
status = fdio_ns_bind(namespace_, path, dir_handle);
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to bind %s to namespace: %s",
flat->paths.at(i).c_str(), zx_status_get_string(status));
zx_handle_close(dir_handle);
return false;
}
DartComponentController::~DartComponentController() {
if (namespace_) {
fdio_ns_destroy(namespace_);
namespace_ = nullptr;
}
return true;
close(stdoutfd_);
close(stderrfd_);
}
bool DartComponentController::SetupFromKernel() {
......@@ -200,12 +158,12 @@ bool DartComponentController::SetupFromKernel() {
namespace_, data_path_ + "/app.dilplist", manifest)) {
return false;
}
if (!dart_utils::MappedResource::LoadFromNamespace(
nullptr, "/pkg/data/isolate_core_snapshot_data.bin",
isolate_snapshot_data_)) {
return false;
}
if (!dart_utils::MappedResource::LoadFromNamespace(
nullptr, "/pkg/data/isolate_core_snapshot_instructions.bin",
isolate_snapshot_instructions_, true /* executable */)) {
......@@ -222,6 +180,7 @@ bool DartComponentController::SetupFromKernel() {
std::string str(reinterpret_cast<const char*>(manifest.address()),
manifest.size());
Dart_Handle library = Dart_Null();
for (size_t start = 0; start < manifest.size();) {
size_t end = str.find("\n", start);
if (end == std::string::npos) {
......@@ -250,6 +209,7 @@ bool DartComponentController::SetupFromKernel() {
kernel_peices_.emplace_back(std::move(kernel));
}
Dart_SetRootLibrary(library);
Dart_Handle result = Dart_FinalizeLoading(false);
......@@ -292,22 +252,6 @@ bool DartComponentController::SetupFromAppSnapshot() {
#endif // defined(AOT_RUNTIME)
}
int DartComponentController::SetupFileDescriptor(
fuchsia::sys::FileDescriptorPtr fd) {
if (!fd) {
return -1;
}
// fd->handle1 and fd->handle2 are no longer used.
int outfd = -1;
zx_status_t status = fdio_fd_create(fd->handle0.release(), &outfd);
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to extract output fd: %s",
zx_status_get_string(status));
return -1;
}
return outfd;
}
bool DartComponentController::CreateIsolate(
const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions) {
......@@ -316,6 +260,7 @@ bool DartComponentController::CreateIsolate(
// TODO(dart_runner): Pass if we start using tonic's loader.
intptr_t namespace_fd = -1;
// Freed in IsolateShutdownCallback.
auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
......@@ -323,6 +268,7 @@ bool DartComponentController::CreateIsolate(
isolate_ = Dart_CreateIsolateGroup(
url_.c_str(), label_.c_str(), isolate_snapshot_data,
isolate_snapshot_instructions, nullptr /* flags */, state, state, &error);
if (!isolate_) {
FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
return false;
......@@ -353,41 +299,22 @@ void DartComponentController::Run() {
}
bool DartComponentController::Main() {
FML_CHECK(namespace_ != nullptr);
Dart_EnterScope();
tonic::DartMicrotaskQueue::StartForCurrentThread();
std::vector<std::string> arguments =
startup_info_.launch_info.arguments.value_or(std::vector<std::string>());
std::vector<std::string> arguments = GetArguments();
stdoutfd_ = SetupFileDescriptor(std::move(startup_info_.launch_info.out));
stderrfd_ = SetupFileDescriptor(std::move(startup_info_.launch_info.err));
auto directory_request =
std::move(startup_info_.launch_info.directory_request);
stdoutfd_ = GetStdoutFileDescriptor();
stderrfd_ = GetStderrFileDescriptor();
auto* flat = &startup_info_.flat_namespace;
std::unique_ptr<sys::ServiceDirectory> svc;
for (size_t i = 0; i < flat->paths.size(); ++i) {
zx::channel dir;
if (flat->paths.at(i) == kServiceRootPath) {
svc = std::make_unique<sys::ServiceDirectory>(
std::move(flat->directories.at(i)));
break;
}
}
if (!svc) {
FX_LOG(ERROR, LOG_TAG, "Unable to get /svc for dart component");
if (!PrepareBuiltinLibraries()) {
FX_LOG(ERROR, LOG_TAG,
"Unable to prepare builtin libraries for dart component");
return false;
}
fidl::InterfaceHandle<fuchsia::sys::Environment> environment;
svc->Connect(environment.NewRequest());
InitBuiltinLibrariesForIsolate(
url_, namespace_, stdoutfd_, stderrfd_, std::move(environment),
std::move(directory_request), false /* service_isolate */);
namespace_ = nullptr;
Dart_ExitScope();
Dart_ExitIsolate();
char* error = Dart_IsolateMakeRunnable(isolate_);
......@@ -420,6 +347,7 @@ bool DartComponentController::Main() {
Dart_Handle main_result = Dart_Invoke(Dart_RootLibrary(), ToDart("main"),
dart_utils::ArraySize(argv), argv);
if (Dart_IsError(main_result)) {
auto dart_state = tonic::DartState::Current();
if (!dart_state->has_set_return_code()) {
......@@ -438,34 +366,6 @@ bool DartComponentController::Main() {
return true;
}
void DartComponentController::Kill() {
if (Dart_CurrentIsolate()) {
tonic::DartMicrotaskQueue* queue =
tonic::DartMicrotaskQueue::GetForCurrentThread();
if (queue) {
queue->Destroy();
}
loop_->Quit();
// TODO(rosswang): The docs warn of threading issues if doing this again,
// but without this, attempting to shut down the isolate finalizes app
// contexts that can't tell a shutdown is in progress and so fatal.
Dart_SetMessageNotifyCallback(nullptr);
Dart_ShutdownIsolate();
}
}
void DartComponentController::Detach() {
binding_.set_error_handler([](zx_status_t status) {});
}
void DartComponentController::SendReturnCode() {
binding_.events().OnTerminated(return_code_,
fuchsia::sys::TerminationReason::EXITED);
}
const zx::duration kIdleWaitDuration = zx::sec(2);
const zx::duration kIdleNotifyDuration = zx::msec(500);
const zx::duration kIdleSlack = zx::sec(1);
......@@ -527,4 +427,260 @@ void DartComponentController::OnIdleTimer(async_dispatcher_t* dispatcher,
wait->Begin(dispatcher); // ignore errors
}
void DartComponentController::Shutdown() {
if (Dart_CurrentIsolate()) {
tonic::DartMicrotaskQueue* queue =
tonic::DartMicrotaskQueue::GetForCurrentThread();
if (queue) {
queue->Destroy();
}
loop_->Quit();
// TODO(rosswang): The docs warn of threading issues if doing this again,
// but without this, attempting to shut down the isolate finalizes app
// contexts that can't tell a shutdown is in progress and so fatal.
Dart_SetMessageNotifyCallback(nullptr);
Dart_ShutdownIsolate();
}
}
/// DartComponentController_v1
DartComponentController_v1::DartComponentController_v1(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
: DartComponentController::DartComponentController(
std::move(package.resolved_url),
runner_incoming_services),
package_(std::move(package)),
startup_info_(std::move(startup_info)),
binding_(this) {
for (size_t i = 0; i < startup_info_.program_metadata->size(); ++i) {
auto pg = startup_info_.program_metadata->at(i);
if (pg.key.compare(kDataKey) == 0) {
data_path_ = "pkg/" + pg.value;
}
}
if (data_path_.empty()) {
FX_LOGF(ERROR, LOG_TAG, "Could not find a /pkg/data directory for %s",
url_.c_str());
return;
}
if (controller.is_valid()) {
binding_.Bind(std::move(controller));
binding_.set_error_handler([this](zx_status_t status) { Kill(); });
}
}
DartComponentController_v1::~DartComponentController_v1() {}
void DartComponentController_v1::Kill() {
Shutdown();
}
void DartComponentController_v1::Detach() {
binding_.set_error_handler([](zx_status_t status) {});
}
void DartComponentController_v1::SendReturnCode() {
binding_.events().OnTerminated(return_code_,
fuchsia::sys::TerminationReason::EXITED);
}
fdio_ns_t* DartComponentController_v1::PrepareNamespace() {
fdio_ns_t* ns;
zx_status_t status = fdio_ns_create(&ns);
if (status != ZX_OK) {
return nullptr;
}
fuchsia::sys::FlatNamespace* flat = &startup_info_.flat_namespace;
dart_utils::RunnerTemp::SetupComponent(ns);
for (size_t i = 0; i < flat->paths.size(); ++i) {
if (flat->paths.at(i) == kTmpPath) {
// /tmp is covered by the local memfs.
continue;
}
zx::channel dir;
if (flat->paths.at(i) == kServiceRootPath) {
// clone /svc so component_context can still use it below
dir = zx::channel(fdio_service_clone(flat->directories.at(i).get()));
} else {
dir = std::move(flat->directories.at(i));
}
zx_handle_t dir_handle = dir.release();
const char* path = flat->paths.at(i).data();
zx_status_t status = fdio_ns_bind(ns, path, dir_handle);
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to bind %s to namespace: %s",
flat->paths.at(i).c_str(), zx_status_get_string(status));
zx_handle_close(dir_handle);
return nullptr;
}
}
return ns;
}
int DartComponentController_v1::GetStdoutFileDescriptor() {
return SetupFileDescriptor(std::move(startup_info_.launch_info.out));
}
int DartComponentController_v1::GetStderrFileDescriptor() {
return SetupFileDescriptor(std::move(startup_info_.launch_info.err));
}
int DartComponentController_v1::SetupFileDescriptor(
fuchsia::sys::FileDescriptorPtr fd) {
if (!fd) {
return -1;
}
// fd->handle1 and fd->handle2 are no longer used.
int outfd = -1;
zx_status_t status = fdio_fd_create(fd->handle0.release(), &outfd);
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to extract output fd: %s",
zx_status_get_string(status));
return -1;
}
return outfd;
}
bool DartComponentController_v1::PrepareBuiltinLibraries() {
auto directory_request =
std::move(startup_info_.launch_info.directory_request);
auto* flat = &startup_info_.flat_namespace;
std::unique_ptr<sys::ServiceDirectory> svc;
for (size_t i = 0; i < flat->paths.size(); ++i) {
zx::channel dir;
if (flat->paths.at(i) == kServiceRootPath) {
svc = std::make_unique<sys::ServiceDirectory>(
std::move(flat->directories.at(i)));
break;
}
}
if (!svc) {
return false;
}
fidl::InterfaceHandle<fuchsia::sys::Environment> environment;
svc->Connect(environment.NewRequest());
InitBuiltinLibrariesForIsolate(
url_, namespace_, stdoutfd_, stderrfd_, std::move(environment),
std::move(directory_request), false /* service_isolate */);
return true;
}
std::vector<std::string> DartComponentController_v1::GetArguments() {
return startup_info_.launch_info.arguments.value_or(
std::vector<std::string>());
}
/// DartComponentController_v2
DartComponentController_v2::DartComponentController_v2(
fuchsia::component::runner::ComponentStartInfo start_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
controller)
: DartComponentController::DartComponentController(
std::move(start_info.resolved_url()),
runner_incoming_services),
start_info_(std::move(start_info)),
binding_(this) {
auto name = GetComponentNameFromUrl(url_);
data_path_ = "pkg/data/" + name;
if (controller.is_valid()) {
binding_.Bind(std::move(controller));
binding_.set_error_handler([this](zx_status_t status) { Kill(); });
}
}
DartComponentController_v2::~DartComponentController_v2() {}
void DartComponentController_v2::Kill() {
binding_.set_error_handler([](zx_status_t status) {});
Shutdown();
}
void DartComponentController_v2::Stop() {
Kill();
}
void DartComponentController_v2::SendReturnCode() {
if (binding_.is_bound()) {
binding_.Close(return_code_);
}
}
fdio_ns_t* DartComponentController_v2::PrepareNamespace() {
fdio_ns_t* ns;
zx_status_t status = fdio_ns_create(&ns);
if (status != ZX_OK) {
return nullptr;
}
if (!start_info_.has_ns()) {
return nullptr;
}
dart_utils::RunnerTemp::SetupComponent(ns);
for (auto& ns_entry : *start_info_.mutable_ns()) {
if (!ns_entry.has_path() || !ns_entry.has_directory()) {
continue;
}
if (ns_entry.path() == kTmpPath) {
// /tmp is covered by the local memfs.
continue;
}
auto dir = std::move(*ns_entry.mutable_directory());
auto path = std::move(*ns_entry.mutable_path());
zx_status_t status =
fdio_ns_bind(ns, path.c_str(), dir.TakeChannel().release());
if (status != ZX_OK) {
FX_LOGF(ERROR, LOG_TAG, "Failed to bind %s to namespace: %s",
path.c_str(), zx_status_get_string(status));
return nullptr;
}
}
return ns;
}
int DartComponentController_v2::GetStdoutFileDescriptor() {
return fileno(stdout);
}
int DartComponentController_v2::GetStderrFileDescriptor() {
return fileno(stderr);
}
bool DartComponentController_v2::PrepareBuiltinLibraries() {
auto dir = std::move(*start_info_.mutable_outgoing_dir());
InitBuiltinLibrariesForIsolate(url_, namespace_, stdoutfd_, stderrfd_,
nullptr /* environment */, dir.TakeChannel(),
false /* service_isolate */);
return true;
}
std::vector<std::string> DartComponentController_v2::GetArguments() {
return std::vector<std::string>();
}
} // namespace dart_runner
......@@ -7,6 +7,7 @@
#include <memory>
#include <fuchsia/component/runner/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/wait.h>
......@@ -21,22 +22,35 @@
namespace dart_runner {
class DartComponentController : public fuchsia::sys::ComponentController {
/// The base class for Dart components.
class DartComponentController {
public:
DartComponentController(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller);
~DartComponentController() override;
// Called before the application is run.
bool Setup();
// Calling this method will run the given application
void Run();
bool Main();
void SendReturnCode();
private:
bool SetupNamespace();
bool Main();
// Override this method to send the return code to the caller.
virtual void SendReturnCode() = 0;
// Called when the application is starting up. Subclasses should
// populate the namespace and return the pointer.
virtual fdio_ns_t* PrepareNamespace() = 0;
// Initializes the builtin libraries given the namespace.
virtual bool PrepareBuiltinLibraries() = 0;
// Returns the file descriptors for stdout/stderr
virtual int GetStdoutFileDescriptor() = 0;
virtual int GetStderrFileDescriptor() = 0;
// Called by the main method to pass incoming arguments to the dart
// application.
virtual std::vector<std::string> GetArguments() = 0;
bool SetupFromKernel();
bool SetupFromAppSnapshot();
......@@ -44,12 +58,6 @@ class DartComponentController : public fuchsia::sys::ComponentController {
bool CreateIsolate(const uint8_t* isolate_snapshot_data,
const uint8_t* isolate_snapshot_instructions);
int SetupFileDescriptor(fuchsia::sys::FileDescriptorPtr fd);
// |ComponentController|
void Kill() override;
void Detach() override;
// Idle notification.
void MessageEpilogue(Dart_Handle result);
void OnIdleTimer(async_dispatcher_t* dispatcher,
......@@ -57,28 +65,14 @@ class DartComponentController : public fuchsia::sys::ComponentController {
zx_status_t status,
const zx_packet_signal* signal);
// The loop must be the first declared member so that it gets destroyed after
// binding_ which expects the existence of a loop.
std::unique_ptr<async::Loop> loop_;
std::string label_;
std::string url_;
fuchsia::sys::Package package_;
fuchsia::sys::StartupInfo startup_info_;
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services_;
std::string data_path_;
fidl::Binding<fuchsia::sys::ComponentController> binding_;
std::unique_ptr<sys::ComponentContext> context_;
fdio_ns_t* namespace_ = nullptr;
int stdoutfd_ = -1;
int stderrfd_ = -1;
dart_utils::ElfSnapshot elf_snapshot_; // AOT snapshot
dart_utils::MappedResource isolate_snapshot_data_; // JIT snapshot
dart_utils::MappedResource isolate_snapshot_instructions_; // JIT snapshot
std::vector<dart_utils::MappedResource> kernel_peices_;
Dart_Isolate isolate_;
int32_t return_code_ = 0;
zx::time idle_start_{0};
zx::timer idle_timer_;
......@@ -89,6 +83,99 @@ class DartComponentController : public fuchsia::sys::ComponentController {
// Disallow copy and assignment.
DartComponentController(const DartComponentController&) = delete;
DartComponentController& operator=(const DartComponentController&) = delete;
protected:
DartComponentController(
std::string resolved_url,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services);
~DartComponentController();
void Shutdown();
std::unique_ptr<async::Loop> loop_;
std::string label_;
std::string data_path_;
std::string url_;
int32_t return_code_ = 0;
fdio_ns_t* namespace_ = nullptr;
int stdoutfd_ = -1;
int stderrfd_ = -1;
};
class DartComponentController_v1 : public DartComponentController,
public fuchsia::sys::ComponentController {
public:
DartComponentController_v1(
fuchsia::sys::Package package,
fuchsia::sys::StartupInfo startup_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller);
~DartComponentController_v1() override;
private:
// |ComponentController|
void Kill() override;
void Detach() override;
void SendReturnCode() override;
fdio_ns_t* PrepareNamespace() override;
int GetStdoutFileDescriptor() override;
int GetStderrFileDescriptor() override;
bool PrepareBuiltinLibraries() override;
std::vector<std::string> GetArguments() override;
int SetupFileDescriptor(fuchsia::sys::FileDescriptorPtr fd);
fuchsia::sys::Package package_;
fuchsia::sys::StartupInfo startup_info_;
fidl::Binding<fuchsia::sys::ComponentController> binding_;
// Disallow copy and assignment.
DartComponentController_v1(const DartComponentController_v1&) = delete;
DartComponentController_v1& operator=(const DartComponentController_v1&) =
delete;
};
class DartComponentController_v2
: public DartComponentController,
public fuchsia::component::runner::ComponentController {
public:
DartComponentController_v2(
fuchsia::component::runner::ComponentStartInfo start_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
controller);
~DartComponentController_v2() override;
private:
// |fuchsia::component::runner::ComponentController|
void Kill() override;
void Stop() override;
void SendReturnCode() override;
fdio_ns_t* PrepareNamespace() override;
int GetStdoutFileDescriptor() override;
int GetStderrFileDescriptor() override;
bool PrepareBuiltinLibraries() override;
std::vector<std::string> GetArguments() override;
fuchsia::component::runner::ComponentStartInfo start_info_;
fidl::Binding<fuchsia::component::runner::ComponentController> binding_;
// Disallow copy and assignment.
DartComponentController_v2(const DartComponentController_v2&) = delete;
DartComponentController_v2& operator=(const DartComponentController_v2&) =
delete;
};
} // namespace dart_runner
......
......@@ -17,6 +17,7 @@
#include <utility>
#include "dart_component_controller.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "logging.h"
#include "runtime/dart/utils/inlines.h"
......@@ -100,6 +101,7 @@ void IsolateGroupCleanupCallback(void* isolate_group_data) {
delete static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
}
// RunApplication for a v1 component
void RunApplication(
DartRunner* runner,
fuchsia::sys::Package package,
......@@ -107,8 +109,32 @@ void RunApplication(
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
int64_t start = Dart_TimelineGetMicros();
DartComponentController app(std::move(package), std::move(startup_info),
runner_incoming_services, std::move(controller));
DartComponentController_v1 app(std::move(package), std::move(startup_info),
runner_incoming_services,
std::move(controller));
bool success = app.Setup();
int64_t end = Dart_TimelineGetMicros();
Dart_TimelineEvent("DartComponentController::Setup", start, end,
Dart_Timeline_Event_Duration, 0, NULL, NULL);
if (success) {
app.Run();
}
if (Dart_CurrentIsolate()) {
Dart_ShutdownIsolate();
}
}
// RunApplication for a v2 componeent
void RunApplication2(
DartRunner* runner,
fuchsia::component::runner::ComponentStartInfo start_info,
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
controller) {
int64_t start = Dart_TimelineGetMicros();
DartComponentController_v2 app(
std::move(start_info), runner_incoming_services, std::move(controller));
bool success = app.Setup();
int64_t end = Dart_TimelineGetMicros();
Dart_TimelineEvent("DartComponentController::Setup", start, end,
......@@ -135,6 +161,13 @@ DartRunner::DartRunner(sys::ComponentContext* context) : context_(context) {
bindings_.AddBinding(this, std::move(request));
});
context_->outgoing()
->AddPublicService<fuchsia::component::runner::ComponentRunner>(
[this](fidl::InterfaceRequest<
fuchsia::component::runner::ComponentRunner> request) {
component_runner_bindings_.AddBinding(this, std::move(request));
});
#if !defined(DART_PRODUCT)
// The VM service isolate uses the process-wide namespace. It writes the
// vm service protocol port under /tmp. The VMServiceObject exposes that
......@@ -207,4 +240,15 @@ void DartRunner::StartComponent(
thread.detach();
}
void DartRunner::Start(
fuchsia::component::runner::ComponentStartInfo start_info,
fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
controller) {
std::string url_copy = start_info.resolved_url();
TRACE_EVENT1("dart", "Start", "url", url_copy.c_str());
std::thread thread(RunApplication2, this, std::move(start_info),
context_->svc(), std::move(controller));
thread.detach();
}
} // namespace dart_runner
......@@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_RUNNER_DART_RUNNER_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_RUNNER_DART_RUNNER_H_
#include <fuchsia/component/runner/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/component_context.h>
......@@ -13,7 +14,8 @@
namespace dart_runner {
class DartRunner : public fuchsia::sys::Runner {
class DartRunner : public fuchsia::sys::Runner,
public fuchsia::component::runner::ComponentRunner {
public:
explicit DartRunner(sys::ComponentContext* context);
~DartRunner() override;
......@@ -26,9 +28,17 @@ class DartRunner : public fuchsia::sys::Runner {
::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
override;
// |fuchsia::component::runner::ComponentRunner|
void Start(
fuchsia::component::runner::ComponentStartInfo start_info,
fidl::InterfaceRequest<fuchsia::component::runner::ComponentController>
controller) override;
// Not owned by DartRunner.
sys::ComponentContext* context_;
fidl::BindingSet<fuchsia::sys::Runner> bindings_;
fidl::BindingSet<fuchsia::component::runner::ComponentRunner>
component_runner_bindings_;
#if !defined(AOT_RUNTIME)
dart_utils::MappedResource vm_snapshot_data_;
......
......@@ -39,6 +39,7 @@ int main(int argc, const char** argv) {
// Create our component context which is served later.
auto context = sys::ComponentContext::Create();
dart_utils::RootInspectNode::Initialize(context.get());
auto build_info = dart_utils::RootInspectNode::CreateRootChild("build_info");
dart_utils::BuildInfo::Dump(build_info);
......
// 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.
{
capabilities: [
{
directory: "diagnostics",
rights: [ "connect" ],
path: "/diagnostics",
},
],
use: [
{
directory: "config-data",
rights: [ "r*" ],
path: "/config/data",
},
{
protocol: [
"fuchsia.component.runner.ComponentRunner",
"fuchsia.deprecatedtimezone.Timezone",
"fuchsia.feedback.CrashReporter",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
"fuchsia.net.NameLookup",
"fuchsia.posix.socket.Provider",
"fuchsia.tracing.provider.Registry",
],
from: "parent",
},
],
expose: [
{
directory: "diagnostics",
from: "self",
to: "framework",
},
],
}
// 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: [ "common.shard.cml" ],
program: {
runner: "elf",
binary: "bin/app",
forward_stdout_to: "log",
forward_stderr_to: "log",
},
capabilities: [
{
runner: "dart_aot_product_runner",
path: "/svc/fuchsia.component.runner.ComponentRunner",
},
],
expose: [
{
runner: "dart_aot_product_runner",
from: "self",
},
],
}
// 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: [ "common.shard.cml" ],
program: {
runner: "elf",
binary: "bin/app",
forward_stdout_to: "log",
forward_stderr_to: "log",
},
capabilities: [
{
runner: "dart_aot_runner",
path: "/svc/fuchsia.component.runner.ComponentRunner",
},
],
expose: [
{
runner: "dart_aot_runner",
from: "self",
},
],
}
// 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: [ "common.shard.cml" ],
program: {
runner: "elf",
binary: "bin/app",
forward_stdout_to: "log",
forward_stderr_to: "log",
// needed for JIT builds
job_policy_ambient_mark_vmo_exec: "true",
},
capabilities: [
{
runner: "dart_jit_product_runner",
path: "/svc/fuchsia.component.runner.ComponentRunner",
},
],
expose: [
{
runner: "dart_jit_product_runner",
from: "self",
},
],
}
// 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: [ "common.shard.cml" ],
program: {
runner: "elf",
binary: "bin/app",
forward_stdout_to: "log",
forward_stderr_to: "log",
// needed for JIT builds
job_policy_ambient_mark_vmo_exec: "true",
},
capabilities: [
{
runner: "dart_jit_runner",
path: "/svc/fuchsia.component.runner.ComponentRunner",
},
],
expose: [
{
runner: "dart_jit_runner",
from: "self",
},
],
}
......@@ -205,6 +205,22 @@ while true; do
\"host_match\": \"fuchsia.com\", \"host_replacement\": \"engine\",
\"path_prefix_match\": \"/flutter_aot_runner\", \"path_prefix_replacement\": \"/flutter_aot_runner\"
},
{
\"host_match\": \"fuchsia.com\", \"host_replacement\": \"engine\",
\"path_prefix_match\": \"/dart_jit_runner/\", \"path_prefix_replacement\": \"/dart_jit_runner/\"
},
{
\"host_match\": \"fuchsia.com\", \"host_replacement\": \"engine\",
\"path_prefix_match\": \"/dart_jit_runner\", \"path_prefix_replacement\": \"/dart_jit_runner\"
},
{
\"host_match\": \"fuchsia.com\", \"host_replacement\": \"engine\",
\"path_prefix_match\": \"/dart_aot_runner/\", \"path_prefix_replacement\": \"/dart_aot_runner/\"
},
{
\"host_match\": \"fuchsia.com\", \"host_replacement\": \"engine\",
\"path_prefix_match\": \"/dart_aot_runner\", \"path_prefix_replacement\": \"/dart_aot_runner\"
},
{
\"host_match\": \"fuchsia.com\", \"host_replacement\": \"devhost\",
\"path_prefix_match\": \"/\", \"path_prefix_replacement\": \"/\"
......
......@@ -146,6 +146,10 @@ template("fuchsia_archive") {
]
sources = copy_outputs
if (defined(invoker.cml_file)) {
sources += [ invoker.cml_file ]
}
inputs = []
if (defined(invoker.inputs)) {
inputs += invoker.inputs
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册