| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/logging.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 16 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
| 17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "mojo/public/cpp/bindings/associated_group.h" | 20 #include "mojo/public/cpp/bindings/associated_group.h" |
| 20 #include "mojo/public/cpp/bindings/associated_interface_request.h" | 21 #include "mojo/public/cpp/bindings/associated_interface_request.h" |
| 22 #include "mojo/public/cpp/bindings/bindings_export.h" |
| 21 #include "mojo/public/cpp/bindings/connection_error_callback.h" | 23 #include "mojo/public/cpp/bindings/connection_error_callback.h" |
| 22 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" | 24 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" |
| 23 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" | 25 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" |
| 24 #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h" | 26 #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h" |
| 25 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" | 27 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
| 26 | 28 |
| 27 namespace mojo { | 29 namespace mojo { |
| 28 | 30 |
| 29 class MessageReceiver; | 31 class MessageReceiver; |
| 30 | 32 |
| 33 // Base class used to factor out code in AssociatedBinding<T> expansions, in |
| 34 // particular for Bind(). |
| 35 class MOJO_CPP_BINDINGS_EXPORT AssociatedBindingBase { |
| 36 public: |
| 37 AssociatedBindingBase(); |
| 38 ~AssociatedBindingBase(); |
| 39 |
| 40 // Adds a message filter to be notified of each incoming message before |
| 41 // dispatch. If a filter returns |false| from Accept(), the message is not |
| 42 // dispatched and the pipe is closed. Filters cannot be removed. |
| 43 void AddFilter(std::unique_ptr<MessageReceiver> filter); |
| 44 |
| 45 // Closes the associated interface. Puts this object into a state where it can |
| 46 // be rebound. |
| 47 void Close(); |
| 48 |
| 49 // Similar to the method above, but also specifies a disconnect reason. |
| 50 void CloseWithReason(uint32_t custom_reason, const std::string& description); |
| 51 |
| 52 // Sets an error handler that will be called if a connection error occurs. |
| 53 // |
| 54 // This method may only be called after this AssociatedBinding has been bound |
| 55 // to a message pipe. The error handler will be reset when this |
| 56 // AssociatedBinding is unbound or closed. |
| 57 void set_connection_error_handler(const base::Closure& error_handler); |
| 58 |
| 59 void set_connection_error_with_reason_handler( |
| 60 const ConnectionErrorWithReasonCallback& error_handler); |
| 61 |
| 62 // Indicates whether the associated binding has been completed. |
| 63 bool is_bound() const { return !!endpoint_client_; } |
| 64 |
| 65 // Returns the associated group that this object belongs to. Returns null if |
| 66 // the object is not bound. |
| 67 AssociatedGroup* associated_group() { |
| 68 return endpoint_client_ ? endpoint_client_->associated_group() : nullptr; |
| 69 } |
| 70 |
| 71 // Sends a message on the underlying message pipe and runs the current |
| 72 // message loop until its response is received. This can be used in tests to |
| 73 // verify that no message was sent on a message pipe in response to some |
| 74 // stimulus. |
| 75 void FlushForTesting(); |
| 76 |
| 77 protected: |
| 78 void BindImpl(ScopedInterfaceEndpointHandle handle, |
| 79 MessageReceiverWithResponderStatus* receiver, |
| 80 std::unique_ptr<MessageReceiver> payload_validator, |
| 81 bool expect_sync_requests, |
| 82 scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 83 uint32_t interface_version); |
| 84 |
| 85 std::unique_ptr<InterfaceEndpointClient> endpoint_client_; |
| 86 }; |
| 87 |
| 31 // Represents the implementation side of an associated interface. It is similar | 88 // Represents the implementation side of an associated interface. It is similar |
| 32 // to Binding, except that it doesn't own a message pipe handle. | 89 // to Binding, except that it doesn't own a message pipe handle. |
| 33 // | 90 // |
| 34 // When you bind this class to a request, optionally you can specify a | 91 // When you bind this class to a request, optionally you can specify a |
| 35 // base::SingleThreadTaskRunner. This task runner must belong to the same | 92 // base::SingleThreadTaskRunner. This task runner must belong to the same |
| 36 // thread. It will be used to dispatch incoming method calls and connection | 93 // thread. It will be used to dispatch incoming method calls and connection |
| 37 // error notification. It is useful when you attach multiple task runners to a | 94 // error notification. It is useful when you attach multiple task runners to a |
| 38 // single thread for the purposes of task scheduling. Please note that incoming | 95 // single thread for the purposes of task scheduling. Please note that incoming |
| 39 // synchrounous method calls may not be run from this task runner, when they | 96 // synchrounous method calls may not be run from this task runner, when they |
| 40 // reenter outgoing synchrounous calls on the same thread. | 97 // reenter outgoing synchrounous calls on the same thread. |
| 41 template <typename Interface, | 98 template <typename Interface, |
| 42 typename ImplRefTraits = RawPtrImplRefTraits<Interface>> | 99 typename ImplRefTraits = RawPtrImplRefTraits<Interface>> |
| 43 class AssociatedBinding { | 100 class AssociatedBinding : public AssociatedBindingBase { |
| 44 public: | 101 public: |
| 45 using ImplPointerType = typename ImplRefTraits::PointerType; | 102 using ImplPointerType = typename ImplRefTraits::PointerType; |
| 46 | 103 |
| 47 // Constructs an incomplete associated binding that will use the | 104 // Constructs an incomplete associated binding that will use the |
| 48 // implementation |impl|. It may be completed with a subsequent call to the | 105 // implementation |impl|. It may be completed with a subsequent call to the |
| 49 // |Bind| method. Does not take ownership of |impl|, which must outlive this | 106 // |Bind| method. Does not take ownership of |impl|, which must outlive this |
| 50 // object. | 107 // object. |
| 51 explicit AssociatedBinding(ImplPointerType impl) { stub_.set_sink(impl); } | 108 explicit AssociatedBinding(ImplPointerType impl) { stub_.set_sink(impl); } |
| 52 | 109 |
| 53 // Constructs a completed associated binding of |impl|. The output |ptr_info| | 110 // Constructs a completed associated binding of |impl|. The output |ptr_info| |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 AssociatedInterfaceRequest<Interface> request; | 143 AssociatedInterfaceRequest<Interface> request; |
| 87 associated_group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_PTR, | 144 associated_group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_PTR, |
| 88 ptr_info, &request); | 145 ptr_info, &request); |
| 89 Bind(std::move(request), std::move(runner)); | 146 Bind(std::move(request), std::move(runner)); |
| 90 } | 147 } |
| 91 | 148 |
| 92 // Sets up this object as the implementation side of an associated interface. | 149 // Sets up this object as the implementation side of an associated interface. |
| 93 void Bind(AssociatedInterfaceRequest<Interface> request, | 150 void Bind(AssociatedInterfaceRequest<Interface> request, |
| 94 scoped_refptr<base::SingleThreadTaskRunner> runner = | 151 scoped_refptr<base::SingleThreadTaskRunner> runner = |
| 95 base::ThreadTaskRunnerHandle::Get()) { | 152 base::ThreadTaskRunnerHandle::Get()) { |
| 96 ScopedInterfaceEndpointHandle handle = request.PassHandle(); | 153 BindImpl(request.PassHandle(), &stub_, |
| 97 | 154 base::WrapUnique(new typename Interface::RequestValidator_()), |
| 98 DCHECK(handle.is_local()) | 155 Interface::HasSyncMethods_, std::move(runner), |
| 99 << "The AssociatedInterfaceRequest is supposed to be used at the " | 156 Interface::Version_); |
| 100 << "other side of the message pipe."; | |
| 101 | |
| 102 if (!handle.is_valid() || !handle.is_local()) { | |
| 103 endpoint_client_.reset(); | |
| 104 return; | |
| 105 } | |
| 106 | |
| 107 endpoint_client_.reset(new InterfaceEndpointClient( | |
| 108 std::move(handle), &stub_, | |
| 109 base::WrapUnique(new typename Interface::RequestValidator_()), | |
| 110 Interface::HasSyncMethods_, std::move(runner), Interface::Version_)); | |
| 111 } | |
| 112 | |
| 113 // Adds a message filter to be notified of each incoming message before | |
| 114 // dispatch. If a filter returns |false| from Accept(), the message is not | |
| 115 // dispatched and the pipe is closed. Filters cannot be removed. | |
| 116 void AddFilter(std::unique_ptr<MessageReceiver> filter) { | |
| 117 DCHECK(endpoint_client_); | |
| 118 endpoint_client_->AddFilter(std::move(filter)); | |
| 119 } | |
| 120 | |
| 121 // Closes the associated interface. Puts this object into a state where it can | |
| 122 // be rebound. | |
| 123 void Close() { | |
| 124 endpoint_client_.reset(); | |
| 125 } | |
| 126 | |
| 127 // Similar to the method above, but also specifies a disconnect reason. | |
| 128 void CloseWithReason(uint32_t custom_reason, const std::string& description) { | |
| 129 if (endpoint_client_) | |
| 130 endpoint_client_->CloseWithReason(custom_reason, description); | |
| 131 Close(); | |
| 132 } | 157 } |
| 133 | 158 |
| 134 // Unbinds and returns the associated interface request so it can be | 159 // Unbinds and returns the associated interface request so it can be |
| 135 // used in another context, such as on another thread or with a different | 160 // used in another context, such as on another thread or with a different |
| 136 // implementation. Puts this object into a state where it can be rebound. | 161 // implementation. Puts this object into a state where it can be rebound. |
| 137 AssociatedInterfaceRequest<Interface> Unbind() { | 162 AssociatedInterfaceRequest<Interface> Unbind() { |
| 138 DCHECK(endpoint_client_); | 163 DCHECK(endpoint_client_); |
| 139 | 164 |
| 140 AssociatedInterfaceRequest<Interface> request; | 165 AssociatedInterfaceRequest<Interface> request; |
| 141 request.Bind(endpoint_client_->PassHandle()); | 166 request.Bind(endpoint_client_->PassHandle()); |
| 142 | 167 |
| 143 endpoint_client_.reset(); | 168 endpoint_client_.reset(); |
| 144 | 169 |
| 145 return request; | 170 return request; |
| 146 } | 171 } |
| 147 | 172 |
| 148 // Sets an error handler that will be called if a connection error occurs. | |
| 149 // | |
| 150 // This method may only be called after this AssociatedBinding has been bound | |
| 151 // to a message pipe. The error handler will be reset when this | |
| 152 // AssociatedBinding is unbound or closed. | |
| 153 void set_connection_error_handler(const base::Closure& error_handler) { | |
| 154 DCHECK(is_bound()); | |
| 155 endpoint_client_->set_connection_error_handler(error_handler); | |
| 156 } | |
| 157 | |
| 158 void set_connection_error_with_reason_handler( | |
| 159 const ConnectionErrorWithReasonCallback& error_handler) { | |
| 160 DCHECK(is_bound()); | |
| 161 endpoint_client_->set_connection_error_with_reason_handler(error_handler); | |
| 162 } | |
| 163 | |
| 164 // Returns the interface implementation that was previously specified. | 173 // Returns the interface implementation that was previously specified. |
| 165 Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); } | 174 Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); } |
| 166 | 175 |
| 167 // Indicates whether the associated binding has been completed. | |
| 168 bool is_bound() const { return !!endpoint_client_; } | |
| 169 | |
| 170 // Returns the associated group that this object belongs to. Returns null if | |
| 171 // the object is not bound. | |
| 172 AssociatedGroup* associated_group() { | |
| 173 return endpoint_client_ ? endpoint_client_->associated_group() : nullptr; | |
| 174 } | |
| 175 | |
| 176 // Sends a message on the underlying message pipe and runs the current | |
| 177 // message loop until its response is received. This can be used in tests to | |
| 178 // verify that no message was sent on a message pipe in response to some | |
| 179 // stimulus. | |
| 180 void FlushForTesting() { | |
| 181 endpoint_client_->control_message_proxy()->FlushForTesting(); | |
| 182 } | |
| 183 | |
| 184 private: | 176 private: |
| 185 std::unique_ptr<InterfaceEndpointClient> endpoint_client_; | |
| 186 typename Interface::template Stub_<ImplRefTraits> stub_; | 177 typename Interface::template Stub_<ImplRefTraits> stub_; |
| 187 | 178 |
| 188 DISALLOW_COPY_AND_ASSIGN(AssociatedBinding); | 179 DISALLOW_COPY_AND_ASSIGN(AssociatedBinding); |
| 189 }; | 180 }; |
| 190 | 181 |
| 191 } // namespace mojo | 182 } // namespace mojo |
| 192 | 183 |
| 193 #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ | 184 #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| OLD | NEW |