blob: 797c884916d4889528f66adfdc240648df9b6b7e [file] [log] [blame]
// Copyright 2017 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 PERIDOT_LIB_FIDL_PROXY_H_
#define PERIDOT_LIB_FIDL_PROXY_H_
#include <memory>
#include <vector>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_request.h>
#include <src/lib/fxl/macros.h>
namespace modular {
class ProxyBase;
// A proxy allows to bind a fidl interface request to an existing fidl interface
// ptr of the same interface type.
//
// Proxy instances are held in a proxy set, from which they are automatically
// removed once one of their connection closes, which then also closes the other
// connection.
//
// A proxy set can polymorphically hold proxies of various interface types.
class ProxySet {
public:
ProxySet();
~ProxySet();
template <typename I>
void Connect(fidl::InterfacePtr<I> ptr, fidl::InterfaceRequest<I> request);
private:
friend class ProxyBase;
void Drop(ProxyBase* proxy);
std::vector<std::unique_ptr<ProxyBase>> proxies_;
FXL_DISALLOW_COPY_AND_ASSIGN(ProxySet);
};
// Used internally by ProxySet, but needs to be here because it supports the
// Proxy template class below.
class ProxyBase {
public:
explicit ProxyBase(ProxySet* set);
virtual ~ProxyBase();
protected:
void Drop();
private:
ProxySet* const set_;
FXL_DISALLOW_COPY_AND_ASSIGN(ProxyBase);
};
// Used internally by ProxySet, but needs to be here because it is a
// template.
template <typename I>
class Proxy : public ProxyBase {
public:
Proxy(ProxySet* set, fidl::InterfacePtr<I> ptr,
fidl::InterfaceRequest<I> request);
~Proxy() override;
private:
fidl::InterfacePtr<I> ptr_;
fidl::Binding<I> binding_;
FXL_DISALLOW_COPY_AND_ASSIGN(Proxy);
};
template <typename I>
void ProxySet::Connect(fidl::InterfacePtr<I> ptr,
fidl::InterfaceRequest<I> request) {
proxies_.emplace_back(new Proxy<I>(this, std::move(ptr), std::move(request)));
}
template <typename I>
Proxy<I>::Proxy(ProxySet* const set, fidl::InterfacePtr<I> ptr,
fidl::InterfaceRequest<I> request)
: ProxyBase(set),
ptr_(std::move(ptr)),
binding_(ptr_.get(), std::move(request)) {
ptr_.set_error_handler([this](zx_status_t status) { Drop(); });
binding_.set_error_handler([this](zx_status_t status) { Drop(); });
}
template <typename I>
Proxy<I>::~Proxy() = default;
} // namespace modular
#endif // PERIDOT_LIB_FIDL_PROXY_H_