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