blob: 59b66b672575cf5e53fde6e9893b487839e819ef [file] [log] [blame]
// Copyright 2019 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 "src/virtualization/bin/linux_runner/linux_component.h"
#include <lib/async/default.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>
namespace linux_runner {
// static
std::unique_ptr<LinuxComponent> LinuxComponent::Create(
TerminationCallback termination_callback, fuchsia::sys::Package package,
zx::channel directory_request,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> app_controller,
fuchsia::sys::ComponentControllerPtr remote_controller,
fuchsia::ui::app::ViewProviderPtr remote_view_provider, uint32_t id) {
FX_DCHECK(remote_view_provider) << "Missing remote_view_provider";
return std::unique_ptr<LinuxComponent>(
new LinuxComponent(std::move(termination_callback), std::move(package),
std::move(directory_request), std::move(app_controller),
std::move(remote_controller), std::move(remote_view_provider), id));
}
LinuxComponent::LinuxComponent(
TerminationCallback termination_callback, fuchsia::sys::Package package,
zx::channel directory_request,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> application_controller_request,
fuchsia::sys::ComponentControllerPtr remote_controller,
fuchsia::ui::app::ViewProviderPtr remote_view_provider, uint32_t id)
: termination_callback_(std::move(termination_callback)),
application_controller_(this),
remote_controller_(std::move(remote_controller)),
remote_view_provider_(std::move(remote_view_provider)),
id_(id) {
application_controller_.Bind(std::move(application_controller_request));
application_controller_.set_error_handler([this](zx_status_t status) { Kill(); });
remote_controller_.set_error_handler([this](zx_status_t /*status*/) {
HandleOnTerminated(0, fuchsia::sys::TerminationReason::UNKNOWN);
});
remote_controller_.events().OnTerminated =
fit::bind_member(this, &LinuxComponent::HandleOnTerminated);
if (directory_request) {
outgoing_.Serve(std::move(directory_request));
}
outgoing_.AddPublicService<fuchsia::ui::app::ViewProvider>(view_bindings_.GetHandler(this));
}
LinuxComponent::~LinuxComponent() = default;
void LinuxComponent::HandleOnTerminated(int64_t return_code,
fuchsia::sys::TerminationReason reason) {
application_controller_.events().OnTerminated(return_code, reason);
termination_callback_(id_);
// WARNING: Don't do anything past this point as this instance may have been
// collected.
}
// |fuchsia::sys::ComponentController|
void LinuxComponent::Kill() {
remote_controller_->Kill();
application_controller_.events().OnTerminated(0, fuchsia::sys::TerminationReason::EXITED);
termination_callback_(id_);
// WARNING: Don't do anything past this point as this instance may have been
// collected.
}
// |fuchsia::sys::ComponentController|
void LinuxComponent::Detach() { application_controller_.set_error_handler(nullptr); }
// |fuchsia::ui::app::ViewProvider|
void LinuxComponent::CreateView(
zx::eventpair view_token,
fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services,
fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) {
remote_view_provider_->CreateView(std::move(view_token), std::move(incoming_services),
std::move(outgoing_services));
}
// |fuchsia::ui::app::ViewProvider|
void LinuxComponent::CreateViewWithViewRef(zx::eventpair token,
fuchsia::ui::views::ViewRefControl view_ref_control,
fuchsia::ui::views::ViewRef view_ref) {
remote_view_provider_->CreateViewWithViewRef(std::move(token), std::move(view_ref_control),
std::move(view_ref));
}
// |fuchsia::ui::app::ViewProvider|
void LinuxComponent::CreateView2(fuchsia::ui::app::CreateView2Args args) {
remote_view_provider_->CreateView2(std::move(args));
}
} // namespace linux_runner