blob: 9883bedab9cfaca88f9ca15a16d44a8d2ce08e2b [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 "managed_environment.h"
namespace netemul {
using component::testing::EnclosingEnvironment;
using component::testing::EnvironmentServices;
ManagedEnvironment::Ptr ManagedEnvironment::CreateRoot(
const fuchsia::sys::EnvironmentPtr& parent,
const SandboxEnv::Ptr& sandbox_env) {
auto ret = ManagedEnvironment::Ptr(new ManagedEnvironment(sandbox_env));
Options options;
options.name = "root";
ret->Create(parent, std::move(options));
return ret;
}
ManagedEnvironment::ManagedEnvironment(const SandboxEnv::Ptr& sandbox_env)
: sandbox_env_(sandbox_env) {}
component::testing::EnclosingEnvironment& ManagedEnvironment::environment() {
return *env_;
}
void ManagedEnvironment::GetLauncher(
::fidl::InterfaceRequest<::fuchsia::sys::Launcher> launcher) {
launcher_->Bind(std::move(launcher));
}
void ManagedEnvironment::CreateChildEnvironment(
fidl::InterfaceRequest<FManagedEnvironment> me, Options options) {
ManagedEnvironment::Ptr np(new ManagedEnvironment(sandbox_env_));
fuchsia::sys::EnvironmentPtr env;
env_->ConnectToService(env.NewRequest());
np->Create(env, std::move(options), this);
np->bindings_.AddBinding(np.get(), std::move(me));
children_.emplace_back(std::move(np));
}
void ManagedEnvironment::Create(const fuchsia::sys::EnvironmentPtr& parent,
ManagedEnvironment::Options options,
const ManagedEnvironment* managed_parent) {
auto services = EnvironmentServices::Create(parent);
// add network context service:
services->AddService(sandbox_env_->network_context().GetHandler());
// add Bus service:
services->AddService(sandbox_env_->bus_manager().GetHandler());
// add managed environment itself as a handler
services->AddService(bindings_.GetHandler(this));
// prepare service configurations:
service_config_.clear();
if (options.inherit_parent_launch_services && managed_parent != nullptr) {
service_config_.insert(service_config_.begin(),
managed_parent->service_config_.begin(),
managed_parent->service_config_.end());
}
service_config_.insert(service_config_.begin(), options.services.begin(),
options.services.end());
// push all the allowable launch services:
for (const auto& svc : service_config_) {
fuchsia::sys::LaunchInfo linfo;
linfo.url = svc.url;
services->AddServiceWithLaunchInfo(std::move(linfo), svc.name);
}
// save all handles for virtual devices
for (auto& dev : options.devices) {
virtual_devices_.AddEntry(dev.path, dev.device.Bind());
}
fuchsia::sys::EnvironmentOptions sub_options = {
.kill_on_oom = true,
.allow_parent_runners = false,
.inherit_parent_services = false};
env_ = EnclosingEnvironment::Create(options.name, parent, std::move(services),
sub_options);
env_->SetRunningChangedCallback([this](bool running) {
if (running && running_callback_) {
running_callback_();
}
});
launcher_ = std::make_unique<ManagedLauncher>(this);
}
zx::channel ManagedEnvironment::OpenVdevDirectory() {
return virtual_devices_.OpenAsDirectory();
}
zx::channel ManagedEnvironment::OpenVdataDirectory() {
if (!virtual_data_) {
virtual_data_ = std::make_unique<VirtualData>();
}
return virtual_data_->GetDirectory();
}
} // namespace netemul