| // 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 <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_ |