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 13namespace 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. 18template <typename Interface> 19class InterfaceImpl : public internal::InterfaceImplBase<Interface> { 20 public: 21 typedef typename Interface::Client Client; 22 typedef Interface ImplementedInterface; 23 24 InterfaceImpl() : internal_state_(this) {} 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. 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. 36 bool WaitForIncomingMethodCall() { 37 return internal_state_.WaitForIncomingMethodCall(); 38 } 39 40 // Called when the client has connected to this instance. 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. 47 virtual void OnConnectionError() {} 48 49 // DO NOT USE. Exposed only for internal use and for testing. 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. 72template <typename Impl> 73Impl* 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. 82template <typename Impl> 83Impl* 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. 102template <typename Impl, typename Interface> 103Impl* 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. 112template <typename Impl, typename Interface> 113Impl* 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. 133template <typename Impl, typename Interface> 134Impl* 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. 142template <typename Impl, typename Interface> 143Impl* 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