| // 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 SRC_MODULAR_LIB_FIDL_PROXY_H_ | |
| #define SRC_MODULAR_LIB_FIDL_PROXY_H_ | |
| #include <lib/fidl/cpp/binding.h> | |
| #include <lib/fidl/cpp/interface_request.h> | |
| #include <memory> | |
| #include <vector> | |
| #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 // SRC_MODULAR_LIB_FIDL_PROXY_H_ |