10de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 20de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 30de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// found in the LICENSE file. 40de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 50de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_ 60de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_ 70de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 80de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/bindings/error_handler.h" 90de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/bindings/interface_ptr.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/public/cpp/bindings/lib/filter_chain.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/public/cpp/bindings/lib/message_header_validator.h" 126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/cpp/environment/environment.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/environment/logging.h" 140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/system/macros.h" 150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)namespace mojo { 170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)namespace internal { 180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)template <typename Interface> 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class InterfaceImplBase : public Interface { 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~InterfaceImplBase() {} 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnConnectionEstablished() = 0; 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnConnectionError() = 0; 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename Interface> 280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class InterfaceImplState : public ErrorHandler { 290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) public: 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef typename Interface::Client Client; 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) explicit InterfaceImplState(InterfaceImplBase<Interface>* instance) 330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) : router_(NULL), 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) proxy_(NULL), 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) instance_bound_to_pipe_(false) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NDEBUG 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) , 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deleting_instance_due_to_error_(false) 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_DCHECK(instance); 420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) stub_.set_sink(instance); 430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) virtual ~InterfaceImplState() { 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NDEBUG 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_DCHECK(!instance_bound_to_pipe_ || deleting_instance_due_to_error_); 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 490de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) delete proxy_; 500de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (router_) { 510de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) router_->set_error_handler(NULL); 520de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) delete router_; 530de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 540de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 550de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void BindProxy( 570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) InterfacePtr<Interface>* ptr, 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool instance_bound_to_pipe, 596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { 600de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) MessagePipe pipe; 610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ptr->Bind(pipe.handle0.Pass(), waiter); 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Bind(pipe.handle1.Pass(), instance_bound_to_pipe, waiter); 630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void Bind(ScopedMessagePipeHandle handle, 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool instance_bound_to_pipe, 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const MojoAsyncWaiter* waiter) { 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MOJO_CHECK(!router_); 690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FilterChain filters; 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) filters.Append<MessageHeaderValidator>(); 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) filters.Append<typename Interface::RequestValidator_>(); 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) filters.Append<typename Interface::Client::ResponseValidator_>(); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) router_ = new Router(handle.Pass(), filters.Pass(), waiter); 760de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) router_->set_incoming_receiver(&stub_); 770de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) router_->set_error_handler(this); 780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) proxy_ = new typename Client::Proxy_(router_); 800de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) instance_bound_to_pipe_ = instance_bound_to_pipe; 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) instance()->OnConnectionEstablished(); 840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool WaitForIncomingMethodCall() { 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_DCHECK(router_); 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return router_->WaitForIncomingMessage(); 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) Router* router() { return router_; } 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Client* client() { return proxy_; } 930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) private: 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) InterfaceImplBase<Interface>* instance() { 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return static_cast<InterfaceImplBase<Interface>*>(stub_.sink()); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) virtual void OnConnectionError() MOJO_OVERRIDE { 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the the instance is not bound to the pipe, the instance might choose 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // to delete itself in the OnConnectionError handler, which would in turn 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // delete this. Save the error behavior before invoking the error handler 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // so we can correctly decide what to do. 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool bound = instance_bound_to_pipe_; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) instance()->OnConnectionError(); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!bound) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NDEBUG 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deleting_instance_due_to_error_ = true; 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete instance(); 1120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 1130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Router* router_; 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typename Client::Proxy_* proxy_; 1160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) typename Interface::Stub_ stub_; 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool instance_bound_to_pipe_; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NDEBUG 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool deleting_instance_due_to_error_; 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImplState); 1230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}; 1240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} // namespace internal 1260de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} // namespace mojo 1270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 1280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_ 129