Home | History | Annotate | Download | only in bindings
      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 
     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.
     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