OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
| 7 |
| 8 #include "base/macros.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "mojo/public/cpp/bindings/associated_group.h" |
| 11 #include "mojo/public/cpp/bindings/associated_interface_request.h" |
| 12 #include "mojo/public/cpp/bindings/callback.h" |
| 13 #include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h" |
| 14 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" |
| 15 #include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h" |
| 16 |
| 17 namespace mojo { |
| 18 |
| 19 // Represents the implementation side of an associated interface. It is similar |
| 20 // to Binding, except that it doesn't own a message pipe handle. |
| 21 template <typename Interface> |
| 22 class AssociatedBinding { |
| 23 public: |
| 24 // Constructs an incomplete associated binding that will use the |
| 25 // implementation |impl|. It may be completed with a subsequent call to the |
| 26 // |Bind| method. Does not take ownership of |impl|, which must outlive this |
| 27 // object. |
| 28 explicit AssociatedBinding(Interface* impl) : impl_(impl) { |
| 29 stub_.set_sink(impl_); |
| 30 } |
| 31 |
| 32 // Constructs a completed associated binding of |impl|. The output |ptr_info| |
| 33 // should be passed through the message pipe endpoint referred to by |
| 34 // |associated_group| to setup the corresponding asssociated interface |
| 35 // pointer. |impl| must outlive this object. |
| 36 AssociatedBinding(Interface* impl, |
| 37 AssociatedInterfacePtrInfo<Interface>* ptr_info, |
| 38 AssociatedGroup* associated_group) |
| 39 : AssociatedBinding(impl) { |
| 40 Bind(ptr_info, associated_group); |
| 41 } |
| 42 |
| 43 // Constructs a completed associated binding of |impl|. |impl| must outlive |
| 44 // the binding. |
| 45 AssociatedBinding(Interface* impl, |
| 46 AssociatedInterfaceRequest<Interface> request) |
| 47 : AssociatedBinding(impl) { |
| 48 Bind(request.Pass()); |
| 49 } |
| 50 |
| 51 ~AssociatedBinding() {} |
| 52 |
| 53 // Creates an associated inteface and sets up this object as the |
| 54 // implementation side. The output |ptr_info| should be passed through the |
| 55 // message pipe endpoint referred to by |associated_group| to setup the |
| 56 // corresponding asssociated interface pointer. |
| 57 void Bind(AssociatedInterfacePtrInfo<Interface>* ptr_info, |
| 58 AssociatedGroup* associated_group) { |
| 59 AssociatedInterfaceRequest<Interface> request; |
| 60 associated_group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_PTR, |
| 61 ptr_info, &request); |
| 62 Bind(request.Pass()); |
| 63 } |
| 64 |
| 65 // Sets up this object as the implementation side of an associated interface. |
| 66 void Bind(AssociatedInterfaceRequest<Interface> request) { |
| 67 internal::ScopedInterfaceEndpointHandle handle = |
| 68 internal::AssociatedInterfaceRequestHelper::PassHandle(&request); |
| 69 |
| 70 DCHECK(handle.is_local()) |
| 71 << "The AssociatedInterfaceRequest is supposed to be used at the " |
| 72 << "other side of the message pipe."; |
| 73 |
| 74 if (!handle.is_valid() || !handle.is_local()) { |
| 75 endpoint_client_.reset(); |
| 76 return; |
| 77 } |
| 78 |
| 79 endpoint_client_.reset(new internal::InterfaceEndpointClient( |
| 80 handle.Pass(), &stub_, |
| 81 make_scoped_ptr(new typename Interface::RequestValidator_()))); |
| 82 |
| 83 endpoint_client_->set_connection_error_handler( |
| 84 [this]() { connection_error_handler_.Run(); }); |
| 85 } |
| 86 |
| 87 // Closes the associated interface. Puts this object into a state where it can |
| 88 // be rebound. |
| 89 void Close() { |
| 90 DCHECK(endpoint_client_); |
| 91 endpoint_client_.reset(); |
| 92 } |
| 93 |
| 94 // Unbinds and returns the associated interface request so it can be |
| 95 // used in another context, such as on another thread or with a different |
| 96 // implementation. Puts this object into a state where it can be rebound. |
| 97 AssociatedInterfaceRequest<Interface> Unbind() { |
| 98 DCHECK(endpoint_client_); |
| 99 |
| 100 AssociatedInterfaceRequest<Interface> request; |
| 101 internal::AssociatedInterfaceRequestHelper::SetHandle( |
| 102 &request, endpoint_client_->PassHandle()); |
| 103 |
| 104 endpoint_client_.reset(); |
| 105 |
| 106 return request.Pass(); |
| 107 } |
| 108 |
| 109 // Sets an error handler that will be called if a connection error occurs. |
| 110 void set_connection_error_handler(const Closure& error_handler) { |
| 111 connection_error_handler_ = error_handler; |
| 112 } |
| 113 |
| 114 // Returns the interface implementation that was previously specified. |
| 115 Interface* impl() { return impl_; } |
| 116 |
| 117 // Indicates whether the associated binding has been completed. |
| 118 bool is_bound() const { return !!endpoint_client_; } |
| 119 |
| 120 // Returns the associated group that this object belongs to. Returns null if |
| 121 // the object is not bound. |
| 122 AssociatedGroup* associated_group() { |
| 123 return endpoint_client_ ? endpoint_client_->associated_group() : nullptr; |
| 124 } |
| 125 |
| 126 private: |
| 127 scoped_ptr<internal::InterfaceEndpointClient> endpoint_client_; |
| 128 |
| 129 typename Interface::Stub_ stub_; |
| 130 Interface* impl_; |
| 131 Closure connection_error_handler_; |
| 132 |
| 133 DISALLOW_COPY_AND_ASSIGN(AssociatedBinding); |
| 134 }; |
| 135 |
| 136 } // namespace mojo |
| 137 |
| 138 #endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_ |
OLD | NEW |