| // Copyright 2018 The Chromium 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 BASE_FUCHSIA_SCOPED_SERVICE_BINDING_H_ |
| #define BASE_FUCHSIA_SCOPED_SERVICE_BINDING_H_ |
| |
| #include <lib/fidl/cpp/binding_set.h> |
| |
| #include "base/bind.h" |
| #include "base/fuchsia/service_directory.h" |
| #include "starboard/types.h" |
| |
| namespace base { |
| namespace fuchsia { |
| |
| template <typename Interface> |
| class ScopedServiceBinding { |
| public: |
| // |service_directory| and |impl| must outlive the binding. |
| ScopedServiceBinding(ServiceDirectory* service_directory, Interface* impl) |
| : directory_(service_directory), impl_(impl) { |
| directory_->AddService( |
| Interface::Name_, |
| BindRepeating(&ScopedServiceBinding::BindClient, Unretained(this))); |
| } |
| |
| ~ScopedServiceBinding() { directory_->RemoveService(Interface::Name_); } |
| |
| void SetOnLastClientCallback(base::OnceClosure on_last_client_callback) { |
| on_last_client_callback_ = std::move(on_last_client_callback); |
| bindings_.set_empty_set_handler( |
| fit::bind_member(this, &ScopedServiceBinding::OnBindingSetEmpty)); |
| } |
| |
| private: |
| void BindClient(zx::channel channel) { |
| bindings_.AddBinding(impl_, |
| fidl::InterfaceRequest<Interface>(std::move(channel))); |
| } |
| |
| void OnBindingSetEmpty() { |
| bindings_.set_empty_set_handler(nullptr); |
| std::move(on_last_client_callback_).Run(); |
| } |
| |
| ServiceDirectory* const directory_; |
| Interface* const impl_; |
| fidl::BindingSet<Interface> bindings_; |
| base::OnceClosure on_last_client_callback_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedServiceBinding); |
| }; |
| |
| } // namespace fuchsia |
| } // namespace base |
| |
| #endif // BASE_FUCHSIA_SCOPED_SERVICE_BINDING_H_ |