| // Copyright 2015 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_ASSOCIATED_BINDING_H_ |
| #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/threading/sequenced_task_runner_handle.h" |
| #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" |
| #include "mojo/public/cpp/bindings/associated_interface_request.h" |
| #include "mojo/public/cpp/bindings/bindings_export.h" |
| #include "mojo/public/cpp/bindings/connection_error_callback.h" |
| #include "mojo/public/cpp/bindings/interface_endpoint_client.h" |
| #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h" |
| #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
| |
| namespace mojo { |
| |
| class MessageReceiver; |
| |
| // Base class used to factor out code in AssociatedBinding<T> expansions, in |
| // particular for Bind(). |
| class MOJO_CPP_BINDINGS_EXPORT AssociatedBindingBase { |
| public: |
| AssociatedBindingBase(); |
| ~AssociatedBindingBase(); |
| |
| // Adds a message filter to be notified of each incoming message before |
| // dispatch. If a filter returns |false| from Accept(), the message is not |
| // dispatched and the pipe is closed. Filters cannot be removed. |
| void AddFilter(std::unique_ptr<MessageReceiver> filter); |
| |
| // Closes the associated interface. Puts this object into a state where it can |
| // be rebound. |
| void Close(); |
| |
| // Similar to the method above, but also specifies a disconnect reason. |
| void CloseWithReason(uint32_t custom_reason, const std::string& description); |
| |
| // Sets an error handler that will be called if a connection error occurs. |
| // |
| // This method may only be called after this AssociatedBinding has been bound |
| // to a message pipe. The error handler will be reset when this |
| // AssociatedBinding is unbound or closed. |
| void set_connection_error_handler(base::OnceClosure error_handler); |
| |
| void set_connection_error_with_reason_handler( |
| ConnectionErrorWithReasonCallback error_handler); |
| |
| // Indicates whether the associated binding has been completed. |
| bool is_bound() const { return !!endpoint_client_; } |
| |
| // Sends a message on the underlying message pipe and runs the current |
| // message loop until its response is received. This can be used in tests to |
| // verify that no message was sent on a message pipe in response to some |
| // stimulus. |
| void FlushForTesting(); |
| |
| protected: |
| void BindImpl(ScopedInterfaceEndpointHandle handle, |
| MessageReceiverWithResponderStatus* receiver, |
| std::unique_ptr<MessageReceiver> payload_validator, |
| bool expect_sync_requests, |
| scoped_refptr<base::SequencedTaskRunner> runner, |
| uint32_t interface_version); |
| |
| std::unique_ptr<InterfaceEndpointClient> endpoint_client_; |
| }; |
| |
| // Represents the implementation side of an associated interface. It is similar |
| // to Binding, except that it doesn't own a message pipe handle. |
| // |
| // When you bind this class to a request, optionally you can specify a |
| // base::SequencedTaskRunner. This task runner must belong to the same |
| // thread. It will be used to dispatch incoming method calls and connection |
| // error notification. It is useful when you attach multiple task runners to a |
| // single thread for the purposes of task scheduling. Please note that incoming |
| // synchrounous method calls may not be run from this task runner, when they |
| // reenter outgoing synchrounous calls on the same thread. |
| template <typename Interface, |
| typename ImplRefTraits = RawPtrImplRefTraits<Interface>> |
| class AssociatedBinding : public AssociatedBindingBase { |
| public: |
| using ImplPointerType = typename ImplRefTraits::PointerType; |
| |
| // Constructs an incomplete associated binding that will use the |
| // implementation |impl|. It may be completed with a subsequent call to the |
| // |Bind| method. |
| explicit AssociatedBinding(ImplPointerType impl) { |
| stub_.set_sink(std::move(impl)); |
| } |
| |
| // Constructs a completed associated binding of |impl|. |impl| must outlive |
| // the binding. |
| AssociatedBinding(ImplPointerType impl, |
| AssociatedInterfaceRequest<Interface> request, |
| scoped_refptr<base::SequencedTaskRunner> runner = |
| base::SequencedTaskRunnerHandle::Get()) |
| : AssociatedBinding(std::move(impl)) { |
| Bind(std::move(request), std::move(runner)); |
| } |
| |
| ~AssociatedBinding() {} |
| |
| // Sets up this object as the implementation side of an associated interface. |
| void Bind(AssociatedInterfaceRequest<Interface> request, |
| scoped_refptr<base::SequencedTaskRunner> runner = |
| base::SequencedTaskRunnerHandle::Get()) { |
| BindImpl(request.PassHandle(), &stub_, |
| base::WrapUnique(new typename Interface::RequestValidator_()), |
| Interface::HasSyncMethods_, std::move(runner), |
| Interface::Version_); |
| } |
| |
| // Unbinds and returns the associated interface request so it can be |
| // used in another context, such as on another thread or with a different |
| // implementation. Puts this object into a state where it can be rebound. |
| AssociatedInterfaceRequest<Interface> Unbind() { |
| DCHECK(endpoint_client_); |
| AssociatedInterfaceRequest<Interface> request( |
| endpoint_client_->PassHandle()); |
| endpoint_client_.reset(); |
| return request; |
| } |
| |
| // Returns the interface implementation that was previously specified. |
| Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); } |
| |
| private: |
| typename Interface::template Stub_<ImplRefTraits> stub_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AssociatedBinding); |
| }; |
| |
| } // namespace mojo |
| |
| #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |