blob: cc6bcea1d867f1f62eed17e16be88d07c25c1233 [file] [log] [blame]
// Copyright 2023 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 EXAMPLES_COMPONENTS_PW_RPC_RUNNER_COMPONENT_RUNNER_H_
#define EXAMPLES_COMPONENTS_PW_RPC_RUNNER_COMPONENT_RUNNER_H_
#include <fidl/fuchsia.component.runner/cpp/fidl.h>
#include <fidl/fuchsia.io/cpp/fidl.h>
#include <fidl/fuchsia.logger/cpp/fidl.h>
#include <lib/async/cpp/wait.h>
#include <lib/async/dispatcher.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/fit/function.h>
#include <lib/zx/eventpair.h>
#include <lib/zx/result.h>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include "examples/components/pw_rpc/runner/connection.h"
#include "examples/components/pw_rpc/runner/remote_endpoint.h"
#include "pw_stream/socket_stream.h"
class ComponentInstance : public fidl::Server<fuchsia_component_runner::ComponentController> {
public:
// Creates an object that manages a component instance's runtime.
//
// The object has ownership of the `ComponentController`, and implements the `ComponentController`
// server.
//
// `stream` should contain a socket to the remote Pigweed server endpoint. The socket should have
// the `O_NONBLOCK` flag.
ComponentInstance(
async_dispatcher_t* dispatcher, pw::stream::SocketStream stream,
fidl::ServerEnd<fuchsia_component_runner::ComponentController> controller_server_end,
fit::callback<void()> deletion_cb);
~ComponentInstance() override;
ComponentInstance(ComponentInstance&&) = delete;
ComponentInstance& operator=(ComponentInstance&&) = delete;
zx::result<> Serve(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir_server_end);
void Stop(StopCompleter::Sync& completer) override;
void Kill(KillCompleter::Sync& completer) override;
void handle_unknown_method(
fidl::UnknownMethodMetadata<fuchsia_component_runner::ComponentController> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override {}
void Start(fidl::ClientEnd<fuchsia_logger::LogSink> log_sink);
void Close();
private:
zx::result<pw::stream::SocketStream> OpenLoggerStream();
async_dispatcher_t* const dispatcher_;
fidl::ServerBinding<fuchsia_component_runner::ComponentController> binding_;
std::shared_ptr<ConnectionGroup> connections_;
component::OutgoingDirectory outgoing_dir_;
fit::callback<void()> deletion_cb_;
zx::eventpair disconnect_event_;
std::optional<async::WaitOnce> disconnect_wait_;
};
class ComponentRunnerImpl : public fidl::Server<fuchsia_component_runner::ComponentRunner> {
public:
explicit ComponentRunnerImpl(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}
void Start(StartRequest& request, StartCompleter::Sync& completer) override;
void handle_unknown_method(
fidl::UnknownMethodMetadata<fuchsia_component_runner::ComponentRunner> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override {}
private:
zx::result<> DoStart(fuchsia_component_runner::ComponentStartInfo start_info,
fidl::ServerEnd<fuchsia_component_runner::ComponentController>& controller);
async_dispatcher_t* const dispatcher_;
std::unordered_map<uint64_t, std::unique_ptr<ComponentInstance>> components_;
uint64_t next_component_id_ = 0;
};
#endif // EXAMPLES_COMPONENTS_PW_RPC_RUNNER_COMPONENT_RUNNER_H_