| 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 17 matching lines...) Expand all Loading... |
| 28 #include "mojo/public/cpp/bindings/lib/router.h" | 28 #include "mojo/public/cpp/bindings/lib/router.h" |
| 29 #include "mojo/public/cpp/bindings/message_header_validator.h" | 29 #include "mojo/public/cpp/bindings/message_header_validator.h" |
| 30 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" | 30 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
| 31 | 31 |
| 32 namespace mojo { | 32 namespace mojo { |
| 33 namespace internal { | 33 namespace internal { |
| 34 | 34 |
| 35 template <typename Interface, bool use_multiplex_router> | 35 template <typename Interface, bool use_multiplex_router> |
| 36 class InterfacePtrState; | 36 class InterfacePtrState; |
| 37 | 37 |
| 38 // Non-templated base class to reduce the amount of code generated for every |
| 39 // mojom file. |
| 40 class SimpleInterfacePtrState { |
| 41 public: |
| 42 SimpleInterfacePtrState(); |
| 43 |
| 44 ~SimpleInterfacePtrState(); |
| 45 |
| 46 uint32_t version() const { return version_; } |
| 47 |
| 48 void QueryVersion(const base::Callback<void(uint32_t)>& callback); |
| 49 |
| 50 void RequireVersion(uint32_t version); |
| 51 |
| 52 bool HasAssociatedInterfaces() const; |
| 53 |
| 54 bool is_bound() const { return handle_.is_valid() || router_; } |
| 55 |
| 56 bool encountered_error() const { |
| 57 return router_ ? router_->encountered_error() : false; |
| 58 } |
| 59 |
| 60 void set_connection_error_handler(const base::Closure& error_handler) { |
| 61 ConfigureProxyIfNecessary(); |
| 62 |
| 63 DCHECK(router_); |
| 64 router_->set_connection_error_handler(error_handler); |
| 65 } |
| 66 |
| 67 // Returns true if bound and awaiting a response to a message. |
| 68 bool has_pending_callbacks() const { |
| 69 return router_ && router_->has_pending_responders(); |
| 70 } |
| 71 |
| 72 AssociatedGroup* associated_group() { return nullptr; } |
| 73 |
| 74 void EnableTestingMode(); |
| 75 |
| 76 protected: |
| 77 void BindInternal(InterfacePtrInfoBase* info, |
| 78 scoped_refptr<base::SingleThreadTaskRunner> runner); |
| 79 |
| 80 virtual void ConfigureProxyIfNecessary() = 0; |
| 81 |
| 82 bool ConfigureProxyIfNecessaryInternal(const char* interface_name); |
| 83 |
| 84 virtual MessageFilter* CreateRequestValidator() = 0; |
| 85 |
| 86 virtual ControlMessageProxy* proxy() = 0; |
| 87 |
| 88 Router* router_; |
| 89 |
| 90 // |proxy_| and |router_| are not initialized until read/write with the |
| 91 // message pipe handle is needed. |handle_| is valid between the Bind() call |
| 92 // and the initialization of |proxy_| and |router_|. |
| 93 ScopedMessagePipeHandle handle_; |
| 94 scoped_refptr<base::SingleThreadTaskRunner> runner_; |
| 95 |
| 96 uint32_t version_; |
| 97 |
| 98 private: |
| 99 void OnQueryVersion(const base::Callback<void(uint32_t)>& callback, |
| 100 uint32_t version); |
| 101 }; |
| 102 |
| 38 // Uses a single-threaded, dedicated router. If |Interface| doesn't have any | 103 // Uses a single-threaded, dedicated router. If |Interface| doesn't have any |
| 39 // methods to pass associated interface pointers or requests, there won't be | 104 // methods to pass associated interface pointers or requests, there won't be |
| 40 // multiple interfaces running on the underlying message pipe. In that case, we | 105 // multiple interfaces running on the underlying message pipe. In that case, we |
| 41 // can use this specialization to reduce cost. | 106 // can use this specialization to reduce cost. |
| 42 template <typename Interface> | 107 template <typename Interface> |
| 43 class InterfacePtrState<Interface, false> { | 108 class InterfacePtrState<Interface, false> : public SimpleInterfacePtrState { |
| 44 public: | 109 public: |
| 45 InterfacePtrState() : proxy_(nullptr), router_(nullptr), version_(0u) {} | 110 InterfacePtrState() : proxy_(nullptr) {} |
| 46 | 111 |
| 47 ~InterfacePtrState() { | 112 ~InterfacePtrState() { |
| 48 // Destruction order matters here. We delete |proxy_| first, even though | 113 // Destruction order matters here. We delete |proxy_| first, even though |
| 49 // |router_| may have a reference to it, so that destructors for any request | 114 // |router_| may have a reference to it, so that destructors for any request |
| 50 // callbacks still pending can interact with the InterfacePtr. | 115 // callbacks still pending can interact with the InterfacePtr. |
| 51 delete proxy_; | 116 delete proxy_; |
| 52 delete router_; | |
| 53 } | 117 } |
| 54 | 118 |
| 55 Interface* instance() { | 119 Interface* instance() { |
| 56 ConfigureProxyIfNecessary(); | 120 ConfigureProxyIfNecessary(); |
| 57 | 121 |
| 58 // This will be null if the object is not bound. | 122 // This will be null if the object is not bound. |
| 59 return proxy_; | 123 return proxy_; |
| 60 } | 124 } |
| 61 | 125 |
| 62 uint32_t version() const { return version_; } | |
| 63 | |
| 64 void QueryVersion(const base::Callback<void(uint32_t)>& callback) { | |
| 65 ConfigureProxyIfNecessary(); | |
| 66 | |
| 67 // Do a static cast in case the interface contains methods with the same | |
| 68 // name. It is safe to capture |this| because the callback won't be run | |
| 69 // after this object goes away. | |
| 70 static_cast<ControlMessageProxy*>(proxy_)->QueryVersion( | |
| 71 base::Bind(&InterfacePtrState::OnQueryVersion, base::Unretained(this), | |
| 72 callback)); | |
| 73 } | |
| 74 | |
| 75 void RequireVersion(uint32_t version) { | |
| 76 ConfigureProxyIfNecessary(); | |
| 77 | |
| 78 if (version <= version_) | |
| 79 return; | |
| 80 | |
| 81 version_ = version; | |
| 82 // Do a static cast in case the interface contains methods with the same | |
| 83 // name. | |
| 84 static_cast<ControlMessageProxy*>(proxy_)->RequireVersion(version); | |
| 85 } | |
| 86 | |
| 87 void Swap(InterfacePtrState* other) { | 126 void Swap(InterfacePtrState* other) { |
| 88 using std::swap; | 127 using std::swap; |
| 89 swap(other->proxy_, proxy_); | 128 swap(other->proxy_, proxy_); |
| 90 swap(other->router_, router_); | 129 swap(other->router_, router_); |
| 91 handle_.swap(other->handle_); | 130 handle_.swap(other->handle_); |
| 92 runner_.swap(other->runner_); | 131 runner_.swap(other->runner_); |
| 93 swap(other->version_, version_); | 132 swap(other->version_, version_); |
| 94 } | 133 } |
| 95 | 134 |
| 96 void Bind(InterfacePtrInfo<Interface> info, | 135 void Bind(InterfacePtrInfo<Interface> info, |
| 97 scoped_refptr<base::SingleThreadTaskRunner> runner) { | 136 scoped_refptr<base::SingleThreadTaskRunner> runner) { |
| 98 DCHECK(!proxy_); | 137 DCHECK(!proxy_); |
| 99 DCHECK(!router_); | 138 BindInternal(&info, runner); |
| 100 DCHECK(!handle_.is_valid()); | |
| 101 DCHECK_EQ(0u, version_); | |
| 102 DCHECK(info.is_valid()); | |
| 103 | |
| 104 handle_ = info.PassHandle(); | |
| 105 version_ = info.version(); | |
| 106 runner_ = std::move(runner); | |
| 107 } | 139 } |
| 108 | 140 |
| 109 bool HasAssociatedInterfaces() const { return false; } | |
| 110 | |
| 111 // After this method is called, the object is in an invalid state and | 141 // After this method is called, the object is in an invalid state and |
| 112 // shouldn't be reused. | 142 // shouldn't be reused. |
| 113 InterfacePtrInfo<Interface> PassInterface() { | 143 InterfacePtrInfo<Interface> PassInterface() { |
| 114 return InterfacePtrInfo<Interface>( | 144 return InterfacePtrInfo<Interface>( |
| 115 router_ ? router_->PassMessagePipe() : std::move(handle_), version_); | 145 router_ ? router_->PassMessagePipe() : std::move(handle_), version_); |
| 116 } | 146 } |
| 117 | 147 |
| 118 bool is_bound() const { return handle_.is_valid() || router_; } | |
| 119 | |
| 120 bool encountered_error() const { | |
| 121 return router_ ? router_->encountered_error() : false; | |
| 122 } | |
| 123 | |
| 124 void set_connection_error_handler(const base::Closure& error_handler) { | |
| 125 ConfigureProxyIfNecessary(); | |
| 126 | |
| 127 DCHECK(router_); | |
| 128 router_->set_connection_error_handler(error_handler); | |
| 129 } | |
| 130 | |
| 131 // Returns true if bound and awaiting a response to a message. | |
| 132 bool has_pending_callbacks() const { | |
| 133 return router_ && router_->has_pending_responders(); | |
| 134 } | |
| 135 | |
| 136 AssociatedGroup* associated_group() { return nullptr; } | |
| 137 | |
| 138 void EnableTestingMode() { | |
| 139 ConfigureProxyIfNecessary(); | |
| 140 router_->EnableTestingMode(); | |
| 141 } | |
| 142 | |
| 143 private: | 148 private: |
| 144 using Proxy = typename Interface::Proxy_; | 149 using Proxy = typename Interface::Proxy_; |
| 145 | 150 |
| 146 void ConfigureProxyIfNecessary() { | 151 void ConfigureProxyIfNecessary() override { |
| 147 // The proxy has been configured. | 152 // The proxy has been configured. |
| 148 if (proxy_) { | 153 if (proxy_) { |
| 149 DCHECK(router_); | 154 DCHECK(router_); |
| 150 return; | 155 return; |
| 151 } | 156 } |
| 152 // The object hasn't been bound. | 157 if (!SimpleInterfacePtrState::ConfigureProxyIfNecessaryInternal( |
| 153 if (!handle_.is_valid()) | 158 Interface::Name_)) { |
| 154 return; | 159 return; |
| 155 | 160 } |
| 156 FilterChain filters; | |
| 157 filters.Append<MessageHeaderValidator>(Interface::Name_); | |
| 158 filters.Append<typename Interface::ResponseValidator_>(); | |
| 159 | |
| 160 router_ = new Router(std::move(handle_), std::move(filters), false, | |
| 161 std::move(runner_)); | |
| 162 | |
| 163 proxy_ = new Proxy(router_); | 161 proxy_ = new Proxy(router_); |
| 164 } | 162 } |
| 165 | 163 |
| 166 void OnQueryVersion(const base::Callback<void(uint32_t)>& callback, | 164 MessageFilter* CreateRequestValidator() override { |
| 167 uint32_t version) { | 165 return new typename Interface::ResponseValidator_(); |
| 168 version_ = version; | |
| 169 callback.Run(version); | |
| 170 } | 166 } |
| 171 | 167 |
| 168 ControlMessageProxy* proxy() override { return proxy_; } |
| 169 |
| 172 Proxy* proxy_; | 170 Proxy* proxy_; |
| 173 Router* router_; | |
| 174 | |
| 175 // |proxy_| and |router_| are not initialized until read/write with the | |
| 176 // message pipe handle is needed. |handle_| is valid between the Bind() call | |
| 177 // and the initialization of |proxy_| and |router_|. | |
| 178 ScopedMessagePipeHandle handle_; | |
| 179 scoped_refptr<base::SingleThreadTaskRunner> runner_; | |
| 180 | |
| 181 uint32_t version_; | |
| 182 | 171 |
| 183 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); | 172 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); |
| 184 }; | 173 }; |
| 185 | 174 |
| 186 // Uses a multiplexing router. If |Interface| has methods to pass associated | 175 // Uses a multiplexing router. If |Interface| has methods to pass associated |
| 187 // interface pointers or requests, this specialization should be used. | 176 // interface pointers or requests, this specialization should be used. |
| 188 template <typename Interface> | 177 template <typename Interface> |
| 189 class InterfacePtrState<Interface, true> { | 178 class InterfacePtrState<Interface, true> { |
| 190 public: | 179 public: |
| 191 InterfacePtrState() : version_(0u) {} | 180 InterfacePtrState() : version_(0u) {} |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 | 328 |
| 340 uint32_t version_; | 329 uint32_t version_; |
| 341 | 330 |
| 342 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); | 331 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); |
| 343 }; | 332 }; |
| 344 | 333 |
| 345 } // namespace internal | 334 } // namespace internal |
| 346 } // namespace mojo | 335 } // namespace mojo |
| 347 | 336 |
| 348 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ | 337 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ |
| OLD | NEW |