blob: bc3fbfce11e6e9433d464e5cf5d6f158e6a7c020 [file] [log] [blame]
// Copyright 2016 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.
#ifndef GARNET_BIN_APPMGR_COMPONENT_CONTROLLER_IMPL_H_
#define GARNET_BIN_APPMGR_COMPONENT_CONTROLLER_IMPL_H_
#include <fs/pseudo-dir.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async/cpp/wait.h>
#include <lib/zx/process.h>
#include "garnet/bin/appmgr/component_container.h"
#include "garnet/bin/appmgr/hub/component_hub.h"
#include "garnet/bin/appmgr/hub/hub_info.h"
#include "garnet/bin/appmgr/namespace.h"
#include "lib/fidl/cpp/binding.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_ptr.h"
namespace component {
enum class ExportedDirType {
// Legacy exported directory layout where each file / service is exposed at
// the top level. Appmgr forwards a client's
// |fuchsia::sys::LaunchInfo.directory_request| to the top level directory.
kLegacyFlatLayout,
// A nested directory structure where appmgr expects 3 sub-directories-
// (1) public - A client's |fuchsia::sys::LaunchInfo.directory_request| is
// forwarded to this directory.
// (2) debug - This directory is used to expose debug files.
// (3) ctrl - This deirectory is used to expose files to the system.
kPublicDebugCtrlLayout,
};
class ComponentControllerBase : public fuchsia::sys::ComponentController {
public:
ComponentControllerBase(
fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
std::string url, std::string args, std::string label,
std::string hub_instance_id, fxl::RefPtr<Namespace> ns,
ExportedDirType export_dir_type, zx::channel exported_dir,
zx::channel client_request);
~ComponentControllerBase() override;
public:
HubInfo HubInfo();
const std::string& label() const { return label_; }
const fbl::RefPtr<fs::PseudoDir>& hub_dir() const { return hub_.dir(); }
// |fuchsia::sys::ComponentController| implementation:
void Detach() override;
protected:
ComponentHub* hub() { return &hub_; }
private:
fidl::Binding<fuchsia::sys::ComponentController> binding_;
std::string label_;
std::string hub_instance_id_;
ComponentHub hub_;
zx::channel exported_dir_;
fxl::RefPtr<Namespace> ns_;
};
class ComponentControllerImpl : public ComponentControllerBase {
public:
ComponentControllerImpl(
fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
ComponentContainer<ComponentControllerImpl>* container,
std::string job_id, zx::process process, std::string url,
std::string args, std::string label, fxl::RefPtr<Namespace> ns,
ExportedDirType export_dir_type, zx::channel exported_dir,
zx::channel client_request);
~ComponentControllerImpl() override;
const std::string& koid() const { return koid_; }
zx_status_t AddSubComponentHub(const component::HubInfo& hub_info);
zx_status_t RemoveSubComponentHub(const component::HubInfo& hub_info);
// |fuchsia::sys::ComponentController| implementation:
void Kill() override;
void Wait(WaitCallback callback) override;
private:
void Handler(async_t* async, async::WaitBase* wait, zx_status_t status,
const zx_packet_signal* signal);
bool SendReturnCodeIfTerminated();
ComponentContainer<ComponentControllerImpl>* container_;
zx::process process_;
const std::string koid_;
std::vector<WaitCallback> wait_callbacks_;
async::WaitMethod<ComponentControllerImpl, &ComponentControllerImpl::Handler>
wait_;
FXL_DISALLOW_COPY_AND_ASSIGN(ComponentControllerImpl);
};
// This class acts as a bridge between the components created by ComponentRunner
// and |request|.
class ComponentBridge : public ComponentControllerBase {
public:
ComponentBridge(
fidl::InterfaceRequest<fuchsia::sys::ComponentController> request,
fuchsia::sys::ComponentControllerPtr remote_controller,
ComponentContainer<ComponentBridge>* container, std::string url,
std::string args, std::string label, std::string hub_instance_id,
fxl::RefPtr<Namespace> ns, ExportedDirType export_dir_type,
zx::channel exported_dir, zx::channel client_request);
~ComponentBridge() override;
void SetParentJobId(const std::string& id);
// |fuchsia::sys::ComponentController| implementation:
void Kill() override;
void Wait(WaitCallback callback) override;
private:
fuchsia::sys::ComponentControllerPtr remote_controller_;
ComponentContainer<ComponentBridge>* container_;
FXL_DISALLOW_COPY_AND_ASSIGN(ComponentBridge);
};
} // namespace component
#endif // GARNET_BIN_APPMGR_COMPONENT_CONTROLLER_IMPL_H_