Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / mojo / public / cpp / bindings / lib / interface_ptr_internal.h
index a318d61..7e9a262 100644 (file)
@@ -5,13 +5,14 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
 
-#include <assert.h>
-#include <stdio.h>
+#include <algorithm>  // For |std::swap()|.
 
 #include "mojo/public/cpp/bindings/lib/filter_chain.h"
 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
 #include "mojo/public/cpp/bindings/lib/router.h"
-#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/public/cpp/environment/logging.h"
+
+struct MojoAsyncWaiter;
 
 namespace mojo {
 namespace internal {
@@ -19,7 +20,7 @@ namespace internal {
 template <typename Interface>
 class InterfacePtrState {
  public:
-  InterfacePtrState() : proxy_(NULL), router_(NULL) {}
+  InterfacePtrState() : proxy_(NULL), router_(NULL), waiter_(NULL) {}
 
   ~InterfacePtrState() {
     // Destruction order matters here. We delete |proxy_| first, even though
@@ -29,38 +30,72 @@ class InterfacePtrState {
     delete router_;
   }
 
-  Interface* instance() const { return proxy_; }
+  Interface* instance() {
+    ConfigureProxyIfNecessary();
 
-  Router* router() const { return router_; }
+    // This will be NULL if the object is not bound.
+    return proxy_;
+  }
 
   void Swap(InterfacePtrState* other) {
     std::swap(other->proxy_, proxy_);
     std::swap(other->router_, router_);
+    handle_.swap(other->handle_);
+    std::swap(other->waiter_, waiter_);
   }
 
-  void ConfigureProxy(
-      ScopedMessagePipeHandle handle,
-      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
-    assert(!proxy_);
-    assert(!router_);
+  void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
+    MOJO_DCHECK(!proxy_);
+    MOJO_DCHECK(!router_);
+    MOJO_DCHECK(!handle_.is_valid());
+    MOJO_DCHECK(!waiter_);
 
-    FilterChain filters;
-    filters.Append<MessageHeaderValidator>();
-    filters.Append<typename Interface::Client::RequestValidator_>();
-    filters.Append<typename Interface::ResponseValidator_>();
+    handle_ = handle.Pass();
+    waiter_ = waiter;
+  }
 
-    router_ = new Router(handle.Pass(), filters.Pass(), waiter);
-    ProxyWithStub* proxy = new ProxyWithStub(router_);
-    router_->set_incoming_receiver(&proxy->stub);
+  bool WaitForIncomingMethodCall() {
+    ConfigureProxyIfNecessary();
 
-    proxy_ = proxy;
+    MOJO_DCHECK(router_);
+    return router_->WaitForIncomingMessage();
+  }
+
+  ScopedMessagePipeHandle PassMessagePipe() {
+    if (router_)
+      return router_->PassMessagePipe();
+
+    waiter_ = NULL;
+    return handle_.Pass();
+  }
+
+  bool is_bound() const {
+    return handle_.is_valid() || router_;
   }
 
   void set_client(typename Interface::Client* client) {
-    assert(proxy_);
+    ConfigureProxyIfNecessary();
+
+    MOJO_DCHECK(proxy_);
     proxy_->stub.set_sink(client);
   }
 
+  bool encountered_error() const {
+    return router_ ? router_->encountered_error() : false;
+  }
+
+  void set_error_handler(ErrorHandler* error_handler) {
+    ConfigureProxyIfNecessary();
+
+    MOJO_DCHECK(router_);
+    router_->set_error_handler(error_handler);
+  }
+
+  Router* router_for_testing() {
+    ConfigureProxyIfNecessary();
+    return router_;
+  }
+
  private:
   class ProxyWithStub : public Interface::Proxy_ {
    public:
@@ -72,9 +107,41 @@ class InterfacePtrState {
     MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
   };
 
+  void ConfigureProxyIfNecessary() {
+    // The proxy has been configured.
+    if (proxy_) {
+      MOJO_DCHECK(router_);
+      return;
+    }
+    // The object hasn't been bound.
+    if (!waiter_) {
+      MOJO_DCHECK(!handle_.is_valid());
+      return;
+    }
+
+    FilterChain filters;
+    filters.Append<MessageHeaderValidator>();
+    filters.Append<typename Interface::Client::RequestValidator_>();
+    filters.Append<typename Interface::ResponseValidator_>();
+
+    router_ = new Router(handle_.Pass(), filters.Pass(), waiter_);
+    waiter_ = NULL;
+
+    ProxyWithStub* proxy = new ProxyWithStub(router_);
+    router_->set_incoming_receiver(&proxy->stub);
+
+    proxy_ = proxy;
+  }
+
   ProxyWithStub* proxy_;
   Router* router_;
 
+  // |proxy_| and |router_| are not initialized until read/write with the
+  // message pipe handle is needed. Before that, |handle_| and |waiter_| store
+  // the arguments of Bind().
+  ScopedMessagePipeHandle handle_;
+  const MojoAsyncWaiter* waiter_;
+
   MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
 };