| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_LIB_INTERFACE_PTR_STATE_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> // For |std::swap()|. | 10 #include <algorithm> // For |std::swap()|. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "base/single_thread_task_runner.h" | 21 #include "base/single_thread_task_runner.h" |
| 22 #include "mojo/public/cpp/bindings/associated_group.h" | 22 #include "mojo/public/cpp/bindings/associated_group.h" |
| 23 #include "mojo/public/cpp/bindings/connection_error_callback.h" | 23 #include "mojo/public/cpp/bindings/connection_error_callback.h" |
| 24 #include "mojo/public/cpp/bindings/filter_chain.h" | 24 #include "mojo/public/cpp/bindings/filter_chain.h" |
| 25 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" | 25 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" |
| 26 #include "mojo/public/cpp/bindings/interface_id.h" | 26 #include "mojo/public/cpp/bindings/interface_id.h" |
| 27 #include "mojo/public/cpp/bindings/interface_ptr_info.h" | 27 #include "mojo/public/cpp/bindings/interface_ptr_info.h" |
| 28 #include "mojo/public/cpp/bindings/lib/control_message_handler.h" | 28 #include "mojo/public/cpp/bindings/lib/control_message_handler.h" |
| 29 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" | 29 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h" |
| 30 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" | 30 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" |
| 31 #include "mojo/public/cpp/bindings/lib/router.h" | |
| 32 #include "mojo/public/cpp/bindings/message_header_validator.h" | 31 #include "mojo/public/cpp/bindings/message_header_validator.h" |
| 33 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" | 32 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
| 34 | 33 |
| 35 namespace mojo { | 34 namespace mojo { |
| 36 namespace internal { | 35 namespace internal { |
| 37 | 36 |
| 38 template <typename Interface, bool use_multiplex_router> | |
| 39 class InterfacePtrState; | |
| 40 | |
| 41 // Uses a single-threaded, dedicated router. If |Interface| doesn't have any | |
| 42 // methods to pass associated interface pointers or requests, there won't be | |
| 43 // multiple interfaces running on the underlying message pipe. In that case, we | |
| 44 // can use this specialization to reduce cost. | |
| 45 template <typename Interface> | 37 template <typename Interface> |
| 46 class InterfacePtrState<Interface, false> { | 38 class InterfacePtrState { |
| 47 public: | |
| 48 InterfacePtrState() : proxy_(nullptr), router_(nullptr), version_(0u) {} | |
| 49 | |
| 50 ~InterfacePtrState() { | |
| 51 // Destruction order matters here. We delete |proxy_| first, even though | |
| 52 // |router_| may have a reference to it, so that destructors for any request | |
| 53 // callbacks still pending can interact with the InterfacePtr. | |
| 54 delete proxy_; | |
| 55 delete router_; | |
| 56 } | |
| 57 | |
| 58 Interface* instance() { | |
| 59 ConfigureProxyIfNecessary(); | |
| 60 | |
| 61 // This will be null if the object is not bound. | |
| 62 return proxy_; | |
| 63 } | |
| 64 | |
| 65 uint32_t version() const { return version_; } | |
| 66 | |
| 67 void QueryVersion(const base::Callback<void(uint32_t)>& callback) { | |
| 68 ConfigureProxyIfNecessary(); | |
| 69 | |
| 70 // It is safe to capture |this| because the callback won't be run after this | |
| 71 // object goes away. | |
| 72 router_->control_message_proxy()->QueryVersion(base::Bind( | |
| 73 &InterfacePtrState::OnQueryVersion, base::Unretained(this), callback)); | |
| 74 } | |
| 75 | |
| 76 void RequireVersion(uint32_t version) { | |
| 77 ConfigureProxyIfNecessary(); | |
| 78 | |
| 79 if (version <= version_) | |
| 80 return; | |
| 81 | |
| 82 version_ = version; | |
| 83 router_->control_message_proxy()->RequireVersion(version); | |
| 84 } | |
| 85 | |
| 86 void FlushForTesting() { | |
| 87 ConfigureProxyIfNecessary(); | |
| 88 router_->control_message_proxy()->FlushForTesting(); | |
| 89 } | |
| 90 | |
| 91 void SendDisconnectReason(uint32_t custom_reason, | |
| 92 const std::string& description) { | |
| 93 ConfigureProxyIfNecessary(); | |
| 94 router_->control_message_proxy()->SendDisconnectReason(custom_reason, | |
| 95 description); | |
| 96 } | |
| 97 | |
| 98 void Swap(InterfacePtrState* other) { | |
| 99 using std::swap; | |
| 100 swap(other->proxy_, proxy_); | |
| 101 swap(other->router_, router_); | |
| 102 handle_.swap(other->handle_); | |
| 103 runner_.swap(other->runner_); | |
| 104 swap(other->version_, version_); | |
| 105 } | |
| 106 | |
| 107 void Bind(InterfacePtrInfo<Interface> info, | |
| 108 scoped_refptr<base::SingleThreadTaskRunner> runner) { | |
| 109 DCHECK(!proxy_); | |
| 110 DCHECK(!router_); | |
| 111 DCHECK(!handle_.is_valid()); | |
| 112 DCHECK_EQ(0u, version_); | |
| 113 DCHECK(info.is_valid()); | |
| 114 | |
| 115 handle_ = info.PassHandle(); | |
| 116 version_ = info.version(); | |
| 117 runner_ = std::move(runner); | |
| 118 } | |
| 119 | |
| 120 bool HasAssociatedInterfaces() const { return false; } | |
| 121 | |
| 122 // After this method is called, the object is in an invalid state and | |
| 123 // shouldn't be reused. | |
| 124 InterfacePtrInfo<Interface> PassInterface() { | |
| 125 return InterfacePtrInfo<Interface>( | |
| 126 router_ ? router_->PassMessagePipe() : std::move(handle_), version_); | |
| 127 } | |
| 128 | |
| 129 bool is_bound() const { return handle_.is_valid() || router_; } | |
| 130 | |
| 131 bool encountered_error() const { | |
| 132 return router_ ? router_->encountered_error() : false; | |
| 133 } | |
| 134 | |
| 135 void set_connection_error_handler(const base::Closure& error_handler) { | |
| 136 ConfigureProxyIfNecessary(); | |
| 137 | |
| 138 DCHECK(router_); | |
| 139 router_->set_connection_error_handler(error_handler); | |
| 140 } | |
| 141 | |
| 142 void set_connection_error_with_reason_handler( | |
| 143 const ConnectionErrorWithReasonCallback& error_handler) { | |
| 144 ConfigureProxyIfNecessary(); | |
| 145 | |
| 146 DCHECK(router_); | |
| 147 router_->set_connection_error_with_reason_handler(error_handler); | |
| 148 } | |
| 149 | |
| 150 // Returns true if bound and awaiting a response to a message. | |
| 151 bool has_pending_callbacks() const { | |
| 152 return router_ && router_->has_pending_responders(); | |
| 153 } | |
| 154 | |
| 155 AssociatedGroup* associated_group() { return nullptr; } | |
| 156 | |
| 157 void EnableTestingMode() { | |
| 158 ConfigureProxyIfNecessary(); | |
| 159 router_->EnableTestingMode(); | |
| 160 } | |
| 161 | |
| 162 private: | |
| 163 using Proxy = typename Interface::Proxy_; | |
| 164 | |
| 165 void ConfigureProxyIfNecessary() { | |
| 166 // The proxy has been configured. | |
| 167 if (proxy_) { | |
| 168 DCHECK(router_); | |
| 169 return; | |
| 170 } | |
| 171 // The object hasn't been bound. | |
| 172 if (!handle_.is_valid()) | |
| 173 return; | |
| 174 | |
| 175 FilterChain filters; | |
| 176 filters.Append<MessageHeaderValidator>(Interface::Name_); | |
| 177 filters.Append<typename Interface::ResponseValidator_>(); | |
| 178 | |
| 179 // The version is only queried from the client so the value passed here | |
| 180 // will not be used. | |
| 181 router_ = new Router(std::move(handle_), std::move(filters), false, | |
| 182 std::move(runner_), 0u); | |
| 183 | |
| 184 proxy_ = new Proxy(router_); | |
| 185 } | |
| 186 | |
| 187 void OnQueryVersion(const base::Callback<void(uint32_t)>& callback, | |
| 188 uint32_t version) { | |
| 189 version_ = version; | |
| 190 callback.Run(version); | |
| 191 } | |
| 192 | |
| 193 Proxy* proxy_; | |
| 194 Router* router_; | |
| 195 | |
| 196 // |proxy_| and |router_| are not initialized until read/write with the | |
| 197 // message pipe handle is needed. |handle_| is valid between the Bind() call | |
| 198 // and the initialization of |proxy_| and |router_|. | |
| 199 ScopedMessagePipeHandle handle_; | |
| 200 scoped_refptr<base::SingleThreadTaskRunner> runner_; | |
| 201 | |
| 202 uint32_t version_; | |
| 203 | |
| 204 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); | |
| 205 }; | |
| 206 | |
| 207 // Uses a multiplexing router. If |Interface| has methods to pass associated | |
| 208 // interface pointers or requests, this specialization should be used. | |
| 209 template <typename Interface> | |
| 210 class InterfacePtrState<Interface, true> { | |
| 211 public: | 39 public: |
| 212 InterfacePtrState() : version_(0u) {} | 40 InterfacePtrState() : version_(0u) {} |
| 213 | 41 |
| 214 ~InterfacePtrState() { | 42 ~InterfacePtrState() { |
| 215 endpoint_client_.reset(); | 43 endpoint_client_.reset(); |
| 216 proxy_.reset(); | 44 proxy_.reset(); |
| 217 if (router_) | 45 if (router_) |
| 218 router_->CloseMessagePipe(); | 46 router_->CloseMessagePipe(); |
| 219 } | 47 } |
| 220 | 48 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 | 223 |
| 396 uint32_t version_; | 224 uint32_t version_; |
| 397 | 225 |
| 398 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); | 226 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); |
| 399 }; | 227 }; |
| 400 | 228 |
| 401 } // namespace internal | 229 } // namespace internal |
| 402 } // namespace mojo | 230 } // namespace mojo |
| 403 | 231 |
| 404 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ | 232 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ |
| OLD | NEW |