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_INTERFACE_PTR_H_
60de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
70de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
80de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include <algorithm>
90de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/bindings/error_handler.h"
110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/bindings/lib/interface_ptr_internal.h"
126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/cpp/environment/environment.h"
130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "mojo/public/cpp/system/macros.h"
140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)namespace mojo {
160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class ErrorHandler;
170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// InterfacePtr represents a proxy to a remote instance of an interface.
190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)template <typename Interface>
200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class InterfacePtr {
210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr, RValue)
220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) public:
230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  InterfacePtr() {}
240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  InterfacePtr(RValue other) {
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    internal_state_.Swap(&other.object->internal_state_);
270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  InterfacePtr& operator=(RValue other) {
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    reset();
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    internal_state_.Swap(&other.object->internal_state_);
310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    return *this;
320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  ~InterfacePtr() {}
350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  Interface* get() const {
370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    return internal_state_.instance();
380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  Interface* operator->() const { return get(); }
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Interface& operator*() const { return *get(); }
410de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  void reset() {
430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    State doomed;
440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    internal_state_.Swap(&doomed);
450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
460de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Blocks the current thread for the first incoming method call, i.e., either
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // a call to a client method or a callback method. Returns |true| if a method
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // has been called, |false| in case of error. It must only be called on a
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // bound object.
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool WaitForIncomingMethodCall() {
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return internal_state_.WaitForIncomingMethodCall();
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
550de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // This method configures the InterfacePtr<..> to be a proxy to a remote
560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // object on the other end of the given pipe.
570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  //
580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // The proxy is bound to the current thread, which means its methods may
590de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // only be called on the current thread.
600de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  //
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // To move a bound InterfacePtr<..> to another thread, call PassMessagePipe().
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Then create a new InterfacePtr<..> on another thread, and bind the new
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // InterfacePtr<..> to the message pipe on that thread.
646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void Bind(
656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ScopedMessagePipeHandle handle,
666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    reset();
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    internal_state_.Bind(handle.Pass(), waiter);
690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
700de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The client interface may only be set after this InterfacePtr<..> is bound.
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void set_client(typename Interface::Client* client) {
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    internal_state_.set_client(client);
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
760de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // This method may be called to query if the underlying pipe has encountered
770de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // an error. If true, this means method calls made on this interface will be
780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // dropped (and may have already been dropped) on the floor.
790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  bool encountered_error() const {
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return internal_state_.encountered_error();
810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // This method may be called to register an ErrorHandler to observe a
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // connection error on the underlying pipe. It must only be called on a bound
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // object.
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The callback runs asynchronously from the current message loop.
870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  void set_error_handler(ErrorHandler* error_handler) {
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    internal_state_.set_error_handler(error_handler);
890de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Returns the underlying message pipe handle (if any) and resets the
920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // InterfacePtr<..> to its uninitialized state. This method is helpful if you
930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // need to move a proxy to another thread. See related notes for Bind.
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedMessagePipeHandle PassMessagePipe() {
950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    State state;
960de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    internal_state_.Swap(&state);
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return state.PassMessagePipe();
980de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1000de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // DO NOT USE. Exposed only for internal use and for testing.
1010de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  internal::InterfacePtrState<Interface>* internal_state() {
1020de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    return &internal_state_;
1030de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
1040de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Allow InterfacePtr<> to be used in boolean expressions, but not
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // implicitly convertible to a real bool (which is dangerous).
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef internal::InterfacePtrState<Interface> InterfacePtr::*Testable;
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  operator Testable() const {
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return internal_state_.is_bound() ? &InterfacePtr::internal_state_ : NULL;
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) private:
1160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  typedef internal::InterfacePtrState<Interface> State;
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mutable State internal_state_;
1180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)};
1190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Takes a handle to the proxy end-point of a pipe. On the other end is
1210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// presumed to be an interface implementation of type |Interface|. Returns a
1220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// generated proxy to that interface, which may be used on the current thread.
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// It is valid to call set_client on the returned InterfacePtr<..> to set an
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// instance of Interface::Client.
1250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)template <typename Interface>
1260de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)InterfacePtr<Interface> MakeProxy(
1270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    ScopedMessagePipeHandle handle,
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
1290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  InterfacePtr<Interface> ptr;
1300de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  if (handle.is_valid())
1310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    ptr.Bind(handle.Pass(), waiter);
1320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  return ptr.Pass();
1330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
1340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}  // namespace mojo
1360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#endif  // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
138