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 3 // found in the LICENSE file. 4 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_ 7 8 #include <utility> 9 10 #include "base/bind.h" 11 #include "base/callback.h" 12 #include "base/logging.h" 13 #include "base/macros.h" 14 #include "mojo/public/cpp/bindings/binding.h" 15 #include "mojo/public/cpp/bindings/interface_ptr.h" 16 #include "mojo/public/cpp/bindings/interface_request.h" 17 #include "mojo/public/cpp/bindings/lib/filter_chain.h" 18 #include "mojo/public/cpp/bindings/lib/router.h" 19 #include "mojo/public/cpp/bindings/message_header_validator.h" 20 #include "mojo/public/cpp/system/core.h" 21 22 namespace mojo { 23 24 // This connects an interface implementation strongly to a pipe. When a 25 // connection error is detected the implementation is deleted. Deleting the 26 // connector also closes the pipe. 27 // 28 // Example of an implementation that is always bound strongly to a pipe 29 // 30 // class StronglyBound : public Foo { 31 // public: 32 // explicit StronglyBound(InterfaceRequest<Foo> request) 33 // : binding_(this, std::move(request)) {} 34 // 35 // // Foo implementation here 36 // 37 // private: 38 // StrongBinding<Foo> binding_; 39 // }; 40 // 41 // class MyFooFactory : public InterfaceFactory<Foo> { 42 // public: 43 // void Create(..., InterfaceRequest<Foo> request) override { 44 // new StronglyBound(std::move(request)); // The binding now owns the 45 // // instance of StronglyBound. 46 // } 47 // }; 48 // 49 // This class is thread hostile once it is bound to a message pipe. Until it is 50 // bound, it may be bound or destroyed on any thread. 51 template <typename Interface> 52 class StrongBinding { 53 public: StrongBinding(Interface * impl)54 explicit StrongBinding(Interface* impl) : binding_(impl) {} 55 StrongBinding(Interface * impl,ScopedMessagePipeHandle handle)56 StrongBinding(Interface* impl, ScopedMessagePipeHandle handle) 57 : StrongBinding(impl) { 58 Bind(std::move(handle)); 59 } 60 StrongBinding(Interface * impl,InterfacePtr<Interface> * ptr)61 StrongBinding(Interface* impl, InterfacePtr<Interface>* ptr) 62 : StrongBinding(impl) { 63 Bind(ptr); 64 } 65 StrongBinding(Interface * impl,InterfaceRequest<Interface> request)66 StrongBinding(Interface* impl, InterfaceRequest<Interface> request) 67 : StrongBinding(impl) { 68 Bind(std::move(request)); 69 } 70 ~StrongBinding()71 ~StrongBinding() {} 72 Bind(ScopedMessagePipeHandle handle)73 void Bind(ScopedMessagePipeHandle handle) { 74 DCHECK(!binding_.is_bound()); 75 binding_.Bind(std::move(handle)); 76 binding_.set_connection_error_handler( 77 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this))); 78 } 79 Bind(InterfacePtr<Interface> * ptr)80 void Bind(InterfacePtr<Interface>* ptr) { 81 DCHECK(!binding_.is_bound()); 82 binding_.Bind(ptr); 83 binding_.set_connection_error_handler( 84 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this))); 85 } 86 Bind(InterfaceRequest<Interface> request)87 void Bind(InterfaceRequest<Interface> request) { 88 DCHECK(!binding_.is_bound()); 89 binding_.Bind(std::move(request)); 90 binding_.set_connection_error_handler( 91 base::Bind(&StrongBinding::OnConnectionError, base::Unretained(this))); 92 } 93 WaitForIncomingMethodCall()94 bool WaitForIncomingMethodCall() { 95 return binding_.WaitForIncomingMethodCall(); 96 } 97 98 // Note: The error handler must not delete the interface implementation. 99 // 100 // This method may only be called after this StrongBinding has been bound to a 101 // message pipe. set_connection_error_handler(const base::Closure & error_handler)102 void set_connection_error_handler(const base::Closure& error_handler) { 103 DCHECK(binding_.is_bound()); 104 connection_error_handler_ = error_handler; 105 } 106 impl()107 Interface* impl() { return binding_.impl(); } 108 // Exposed for testing, should not generally be used. internal_router()109 internal::Router* internal_router() { return binding_.internal_router(); } 110 OnConnectionError()111 void OnConnectionError() { 112 if (!connection_error_handler_.is_null()) 113 connection_error_handler_.Run(); 114 delete binding_.impl(); 115 } 116 117 private: 118 base::Closure connection_error_handler_; 119 Binding<Interface> binding_; 120 121 DISALLOW_COPY_AND_ASSIGN(StrongBinding); 122 }; 123 124 } // namespace mojo 125 126 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_ 127