Chromium Code Reviews| 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> |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "mojo/public/cpp/bindings/connection_error_callback.h" | 21 #include "mojo/public/cpp/bindings/connection_error_callback.h" |
| 22 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" | 22 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" |
| 23 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" | 23 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" |
| 24 #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h" | 24 #include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h" |
| 25 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" | 25 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
| 26 | 26 |
| 27 namespace mojo { | 27 namespace mojo { |
| 28 | 28 |
| 29 class MessageReceiver; | 29 class MessageReceiver; |
| 30 | 30 |
| 31 // Base class used to factor out code in AssociatedBinding<T> expansions, in | |
| 32 // particular for Bind(). | |
| 33 class AssociatedBindingBase { | |
| 34 public: | |
| 35 AssociatedBindingBase(); | |
| 36 ~AssociatedBindingBase(); | |
| 37 | |
| 38 // Adds a message filter to be notified of each incoming message before | |
| 39 // dispatch. If a filter returns |false| from Accept(), the message is not | |
| 40 // dispatched and the pipe is closed. Filters cannot be removed. | |
| 41 void AddFilter(std::unique_ptr<MessageReceiver> filter); | |
| 42 | |
| 43 // Closes the associated interface. Puts this object into a state where it can | |
| 44 // be rebound. | |
| 45 void Close(); | |
| 46 | |
| 47 // Similar to the method above, but also specifies a disconnect reason. | |
| 48 void CloseWithReason(uint32_t custom_reason, const std::string& description); | |
| 49 | |
| 50 // Sets an error handler that will be called if a connection error occurs. | |
| 51 // | |
| 52 // This method may only be called after this AssociatedBinding has been bound | |
| 53 // to a message pipe. The error handler will be reset when this | |
| 54 // AssociatedBinding is unbound or closed. | |
| 55 void set_connection_error_handler(const base::Closure& error_handler); | |
| 56 | |
| 57 void set_connection_error_with_reason_handler( | |
| 58 const ConnectionErrorWithReasonCallback& error_handler); | |
| 59 | |
| 60 // Indicates whether the associated binding has been completed. | |
| 61 bool is_bound() const { return !!endpoint_client_; } | |
| 62 | |
| 63 // Returns the associated group that this object belongs to. Returns null if | |
| 64 // the object is not bound. | |
| 65 AssociatedGroup* associated_group() { | |
| 66 return endpoint_client_ ? endpoint_client_->associated_group() : nullptr; | |
| 67 } | |
| 68 | |
| 69 // Sends a message on the underlying message pipe and runs the current | |
| 70 // message loop until its response is received. This can be used in tests to | |
| 71 // verify that no message was sent on a message pipe in response to some | |
| 72 // stimulus. | |
| 73 void FlushForTesting(); | |
| 74 | |
| 75 protected: | |
| 76 void BindImpl(ScopedInterfaceEndpointHandle handle, | |
| 77 MessageReceiverWithResponderStatus* receiver, | |
| 78 std::unique_ptr<MessageReceiver> payload_validator, | |
| 79 bool expect_sync_requests, | |
| 80 scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 81 uint32_t interface_version); | |
| 82 | |
| 83 std::unique_ptr<InterfaceEndpointClient> endpoint_client_; | |
| 84 }; | |
| 85 | |
| 31 // Represents the implementation side of an associated interface. It is similar | 86 // Represents the implementation side of an associated interface. It is similar |
| 32 // to Binding, except that it doesn't own a message pipe handle. | 87 // to Binding, except that it doesn't own a message pipe handle. |
| 33 // | 88 // |
| 34 // When you bind this class to a request, optionally you can specify a | 89 // When you bind this class to a request, optionally you can specify a |
| 35 // base::SingleThreadTaskRunner. This task runner must belong to the same | 90 // base::SingleThreadTaskRunner. This task runner must belong to the same |
| 36 // thread. It will be used to dispatch incoming method calls and connection | 91 // 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 | 92 // 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 | 93 // 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 | 94 // synchrounous method calls may not be run from this task runner, when they |
| 40 // reenter outgoing synchrounous calls on the same thread. | 95 // reenter outgoing synchrounous calls on the same thread. |
| 41 template <typename Interface, | 96 template <typename Interface, |
| 42 typename ImplRefTraits = RawPtrImplRefTraits<Interface>> | 97 typename ImplRefTraits = RawPtrImplRefTraits<Interface>> |
| 43 class AssociatedBinding { | 98 class AssociatedBinding : public AssociatedBindingBase { |
| 44 public: | 99 public: |
| 45 using ImplPointerType = typename ImplRefTraits::PointerType; | 100 using ImplPointerType = typename ImplRefTraits::PointerType; |
| 46 | 101 |
| 47 // Constructs an incomplete associated binding that will use the | 102 // Constructs an incomplete associated binding that will use the |
| 48 // implementation |impl|. It may be completed with a subsequent call to the | 103 // 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 | 104 // |Bind| method. Does not take ownership of |impl|, which must outlive this |
| 50 // object. | 105 // object. |
| 51 explicit AssociatedBinding(ImplPointerType impl) { stub_.set_sink(impl); } | 106 explicit AssociatedBinding(ImplPointerType impl) { stub_.set_sink(impl); } |
| 52 | 107 |
| 53 // Constructs a completed associated binding of |impl|. The output |ptr_info| | 108 // 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; | 141 AssociatedInterfaceRequest<Interface> request; |
| 87 associated_group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_PTR, | 142 associated_group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_PTR, |
| 88 ptr_info, &request); | 143 ptr_info, &request); |
| 89 Bind(std::move(request), std::move(runner)); | 144 Bind(std::move(request), std::move(runner)); |
| 90 } | 145 } |
| 91 | 146 |
| 92 // Sets up this object as the implementation side of an associated interface. | 147 // Sets up this object as the implementation side of an associated interface. |
| 93 void Bind(AssociatedInterfaceRequest<Interface> request, | 148 void Bind(AssociatedInterfaceRequest<Interface> request, |
| 94 scoped_refptr<base::SingleThreadTaskRunner> runner = | 149 scoped_refptr<base::SingleThreadTaskRunner> runner = |
| 95 base::ThreadTaskRunnerHandle::Get()) { | 150 base::ThreadTaskRunnerHandle::Get()) { |
| 96 ScopedInterfaceEndpointHandle handle = request.PassHandle(); | 151 BindImpl(request.PassHandle(), &stub_, |
| 97 | 152 base::WrapUnique(new typename Interface::RequestValidator_()), |
| 98 DCHECK(handle.is_local()) | 153 Interface::HasSyncMethods_, runner, Interface::Version_); |
|
yzshen1
2017/02/09 00:36:52
nit: std::move(runner) will save one addref/releas
scottmg
2017/02/09 01:15:08
Done.
| |
| 99 << "The AssociatedInterfaceRequest is supposed to be used at the " | |
| 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 } | 154 } |
| 133 | 155 |
| 134 // Unbinds and returns the associated interface request so it can be | 156 // 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 | 157 // 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. | 158 // implementation. Puts this object into a state where it can be rebound. |
| 137 AssociatedInterfaceRequest<Interface> Unbind() { | 159 AssociatedInterfaceRequest<Interface> Unbind() { |
| 138 DCHECK(endpoint_client_); | 160 DCHECK(endpoint_client_); |
| 139 | 161 |
| 140 AssociatedInterfaceRequest<Interface> request; | 162 AssociatedInterfaceRequest<Interface> request; |
| 141 request.Bind(endpoint_client_->PassHandle()); | 163 request.Bind(endpoint_client_->PassHandle()); |
| 142 | 164 |
| 143 endpoint_client_.reset(); | 165 endpoint_client_.reset(); |
| 144 | 166 |
| 145 return request; | 167 return request; |
| 146 } | 168 } |
| 147 | 169 |
| 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. | 170 // Returns the interface implementation that was previously specified. |
| 165 Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); } | 171 Interface* impl() { return ImplRefTraits::GetRawPointer(&stub_.sink()); } |
| 166 | 172 |
| 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: | 173 private: |
| 185 std::unique_ptr<InterfaceEndpointClient> endpoint_client_; | |
| 186 typename Interface::template Stub_<ImplRefTraits> stub_; | 174 typename Interface::template Stub_<ImplRefTraits> stub_; |
| 187 | 175 |
| 188 DISALLOW_COPY_AND_ASSIGN(AssociatedBinding); | 176 DISALLOW_COPY_AND_ASSIGN(AssociatedBinding); |
| 189 }; | 177 }; |
| 190 | 178 |
| 191 } // namespace mojo | 179 } // namespace mojo |
| 192 | 180 |
| 193 #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ | 181 #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| OLD | NEW |