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_INTERFACE_IMPL_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_ 7 8 #include "mojo/public/cpp/bindings/interface_request.h" 9 #include "mojo/public/cpp/bindings/lib/interface_impl_internal.h" 10 #include "mojo/public/cpp/environment/environment.h" 11 #include "mojo/public/cpp/system/macros.h" 12 13 namespace mojo { 14 15 // InterfaceImpl<..> is designed to be the base class of an interface 16 // implementation. It may be bound to a pipe or a proxy, see BindToPipe and 17 // BindToProxy. 18 template <typename Interface> 19 class InterfaceImpl : public internal::InterfaceImplBase<Interface> { 20 public: 21 typedef typename Interface::Client Client; 22 typedef Interface ImplementedInterface; 23 InterfaceImpl()24 InterfaceImpl() : internal_state_(this) {} ~InterfaceImpl()25 virtual ~InterfaceImpl() {} 26 27 // Returns a proxy to the client interface. This is null upon construction, 28 // and becomes non-null after OnClientConnected. NOTE: It remains non-null 29 // until this instance is deleted. client()30 Client* client() { return internal_state_.client(); } 31 32 // Blocks the current thread for the first incoming method call, i.e., either 33 // a call to a method or a client callback method. Returns |true| if a method 34 // has been called, |false| in case of error. It must only be called on a 35 // bound object. WaitForIncomingMethodCall()36 bool WaitForIncomingMethodCall() { 37 return internal_state_.WaitForIncomingMethodCall(); 38 } 39 40 // Called when the client has connected to this instance. OnConnectionEstablished()41 virtual void OnConnectionEstablished() {} 42 43 // Called when the client is no longer connected to this instance. NOTE: The 44 // client() method continues to return a non-null pointer after this method 45 // is called. After this method is called, any method calls made on client() 46 // will be silently ignored. OnConnectionError()47 virtual void OnConnectionError() {} 48 49 // DO NOT USE. Exposed only for internal use and for testing. internal_state()50 internal::InterfaceImplState<Interface>* internal_state() { 51 return &internal_state_; 52 } 53 54 private: 55 internal::InterfaceImplState<Interface> internal_state_; 56 MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImpl); 57 }; 58 59 // Takes an instance of an InterfaceImpl<..> subclass and binds it to the given 60 // MessagePipe. The instance is returned for convenience in member initializer 61 // lists, etc. 62 // 63 // If the pipe is closed, the instance's OnConnectionError method will be called 64 // and then the instance will be deleted. 65 // 66 // The instance is also bound to the current thread. Its methods will only be 67 // called on the current thread, and if the current thread exits, then the end 68 // point of the pipe will be closed and the error handler's OnConnectionError 69 // method will be called. 70 // 71 // Before returning, the instance's OnConnectionEstablished method is called. 72 template <typename Impl> 73 Impl* BindToPipe( 74 Impl* instance, 75 ScopedMessagePipeHandle handle, 76 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 77 instance->internal_state()->Bind(handle.Pass(), true, waiter); 78 return instance; 79 } 80 81 // Like BindToPipe but does not delete the instance after a channel error. 82 template <typename Impl> 83 Impl* WeakBindToPipe( 84 Impl* instance, 85 ScopedMessagePipeHandle handle, 86 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 87 instance->internal_state()->Bind(handle.Pass(), false, waiter); 88 return instance; 89 } 90 91 // Takes an instance of an InterfaceImpl<..> subclass and binds it to the given 92 // InterfacePtr<..>. The instance is returned for convenience in member 93 // initializer lists, etc. If the pipe is closed, the instance's 94 // OnConnectionError method will be called and then the instance will be 95 // deleted. 96 // 97 // The instance is also bound to the current thread. Its methods will only be 98 // called on the current thread, and if the current thread exits, then it will 99 // also be deleted, and along with it, its end point of the pipe will be closed. 100 // 101 // Before returning, the instance's OnConnectionEstablished method is called. 102 template <typename Impl, typename Interface> 103 Impl* BindToProxy( 104 Impl* instance, 105 InterfacePtr<Interface>* ptr, 106 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 107 instance->internal_state()->BindProxy(ptr, true, waiter); 108 return instance; 109 } 110 111 // Like BindToProxy but does not delete the instance after a channel error. 112 template <typename Impl, typename Interface> 113 Impl* WeakBindToProxy( 114 Impl* instance, 115 InterfacePtr<Interface>* ptr, 116 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 117 instance->internal_state()->BindProxy(ptr, false, waiter); 118 return instance; 119 } 120 121 // Takes an instance of an InterfaceImpl<..> subclass and binds it to the given 122 // InterfaceRequest<..>. The instance is returned for convenience in member 123 // initializer lists, etc. If the pipe is closed, the instance's 124 // OnConnectionError method will be called and then the instance will be 125 // deleted. 126 // 127 // The instance is also bound to the current thread. Its methods will only be 128 // called on the current thread, and if the current thread exits, then it will 129 // also be deleted, and along with it, its end point of the pipe will be closed. 130 // 131 // Before returning, the instance will receive a SetClient call, providing it 132 // with a proxy to the client on the other end of the pipe. 133 template <typename Impl, typename Interface> 134 Impl* BindToRequest( 135 Impl* instance, 136 InterfaceRequest<Interface>* request, 137 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 138 return BindToPipe(instance, request->PassMessagePipe(), waiter); 139 } 140 141 // Like BindToRequest but does not delete the instance after a channel error. 142 template <typename Impl, typename Interface> 143 Impl* WeakBindToRequest( 144 Impl* instance, 145 InterfaceRequest<Interface>* request, 146 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 147 return WeakBindToPipe(instance, request->PassMessagePipe(), waiter); 148 } 149 150 } // namespace mojo 151 152 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_ 153