| // Copyright 2014 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 MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ |
| #define MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ |
| |
| #include "mojo/public/c/environment/async_waiter.h" |
| #include "mojo/public/cpp/bindings/error_handler.h" |
| #include "mojo/public/cpp/bindings/interface_ptr.h" |
| #include "mojo/public/cpp/bindings/interface_request.h" |
| #include "mojo/public/cpp/bindings/lib/filter_chain.h" |
| #include "mojo/public/cpp/bindings/lib/message_header_validator.h" |
| #include "mojo/public/cpp/bindings/lib/router.h" |
| #include "mojo/public/cpp/environment/logging.h" |
| #include "mojo/public/cpp/system/core.h" |
| |
| namespace mojo { |
| |
| // This binds an interface implementation a pipe. Deleting the binding closes |
| // the pipe. |
| // |
| // Example: |
| // |
| // #include "foo.mojom.h" |
| // |
| // class FooImpl : public Foo { |
| // public: |
| // explicit FooImpl(InterfaceRequest<Foo> request) |
| // : binding_(this, request.Pass()) {} |
| // |
| // // Foo implementation here. |
| // |
| // private: |
| // Binding<Foo> binding_; |
| // }; |
| // |
| // class MyFooFactory : public InterfaceFactory<Foo> { |
| // public: |
| // void Create(..., InterfaceRequest<Foo> request) override { |
| // auto f = new FooImpl(request.Pass()); |
| // // Do something to manage the lifetime of |f|. Use StrongBinding<> to |
| // // delete FooImpl on connection errors. |
| // } |
| // }; |
| template <typename Interface> |
| class Binding : public ErrorHandler { |
| public: |
| using Client = typename Interface::Client; |
| |
| explicit Binding(Interface* impl) : impl_(impl) { stub_.set_sink(impl_); } |
| |
| Binding(Interface* impl, |
| ScopedMessagePipeHandle handle, |
| const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) |
| : Binding(impl) { |
| Bind(handle.Pass(), waiter); |
| } |
| |
| Binding(Interface* impl, |
| InterfacePtr<Interface>* ptr, |
| const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) |
| : Binding(impl) { |
| Bind(ptr, waiter); |
| } |
| |
| Binding(Interface* impl, |
| InterfaceRequest<Interface> request, |
| const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) |
| : Binding(impl) { |
| Bind(request.PassMessagePipe(), waiter); |
| } |
| |
| ~Binding() override { |
| delete proxy_; |
| if (internal_router_) { |
| internal_router_->set_error_handler(nullptr); |
| delete internal_router_; |
| } |
| } |
| |
| void Bind( |
| ScopedMessagePipeHandle handle, |
| const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
| internal::FilterChain filters; |
| filters.Append<internal::MessageHeaderValidator>(); |
| filters.Append<typename Interface::RequestValidator_>(); |
| filters.Append<typename Client::ResponseValidator_>(); |
| |
| internal_router_ = |
| new internal::Router(handle.Pass(), filters.Pass(), waiter); |
| internal_router_->set_incoming_receiver(&stub_); |
| internal_router_->set_error_handler(this); |
| |
| proxy_ = new typename Client::Proxy_(internal_router_); |
| } |
| |
| void Bind( |
| InterfacePtr<Interface>* ptr, |
| const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
| MessagePipe pipe; |
| ptr->Bind(pipe.handle0.Pass(), waiter); |
| Bind(pipe.handle1.Pass(), waiter); |
| } |
| |
| void Bind( |
| InterfaceRequest<Interface> request, |
| const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
| Bind(request.PassMessagePipe(), waiter); |
| } |
| |
| bool WaitForIncomingMethodCall() { |
| MOJO_DCHECK(internal_router_); |
| return internal_router_->WaitForIncomingMessage(); |
| } |
| |
| void Close() { |
| MOJO_DCHECK(internal_router_); |
| internal_router_->CloseMessagePipe(); |
| } |
| |
| void set_error_handler(ErrorHandler* error_handler) { |
| error_handler_ = error_handler; |
| } |
| |
| // ErrorHandler implementation |
| void OnConnectionError() override { |
| if (error_handler_) |
| error_handler_->OnConnectionError(); |
| } |
| |
| Interface* impl() { return impl_; } |
| Client* client() { return proxy_; } |
| |
| bool is_bound() const { return !!internal_router_; } |
| |
| // Exposed for testing, should not generally be used. |
| internal::Router* internal_router() { return internal_router_; } |
| |
| private: |
| internal::Router* internal_router_ = nullptr; |
| typename Client::Proxy_* proxy_ = nullptr; |
| typename Interface::Stub_ stub_; |
| Interface* impl_; |
| ErrorHandler* error_handler_ = nullptr; |
| |
| MOJO_DISALLOW_COPY_AND_ASSIGN(Binding); |
| }; |
| |
| } // namespace mojo |
| |
| #endif // MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_ |