Home | History | Annotate | Download | only in bindings
      1 // Copyright 2015 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_ASSOCIATED_GROUP_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_GROUP_H_
      7 
      8 #include <utility>
      9 
     10 #include "base/memory/ref_counted.h"
     11 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
     12 #include "mojo/public/cpp/bindings/associated_interface_request.h"
     13 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
     14 
     15 namespace mojo {
     16 
     17 class AssociatedGroupController;
     18 
     19 // AssociatedGroup refers to all the interface endpoints running at one end of a
     20 // message pipe. It is used to create associated interfaces for that message
     21 // pipe.
     22 // It is thread safe and cheap to make copies.
     23 class AssociatedGroup {
     24  public:
     25   // Configuration used by CreateAssociatedInterface(). Please see the comments
     26   // of that method for more details.
     27   enum AssociatedInterfaceConfig { WILL_PASS_PTR, WILL_PASS_REQUEST };
     28 
     29   AssociatedGroup();
     30   AssociatedGroup(const AssociatedGroup& other);
     31 
     32   ~AssociatedGroup();
     33 
     34   AssociatedGroup& operator=(const AssociatedGroup& other);
     35 
     36   // |config| indicates whether |ptr_info| or |request| will be sent to the
     37   // remote side of the message pipe.
     38   //
     39   // NOTE: If |config| is |WILL_PASS_REQUEST|, you will want to bind |ptr_info|
     40   // to a local AssociatedInterfacePtr to make calls. However, there is one
     41   // restriction: the pointer should NOT be used to make calls before |request|
     42   // is sent. Violating that will cause the message pipe to be closed. On the
     43   // other hand, as soon as |request| is sent, the pointer is usable. There is
     44   // no need to wait until |request| is bound to an implementation at the remote
     45   // side.
     46   template <typename T>
     47   void CreateAssociatedInterface(
     48       AssociatedInterfaceConfig config,
     49       AssociatedInterfacePtrInfo<T>* ptr_info,
     50       AssociatedInterfaceRequest<T>* request) {
     51     ScopedInterfaceEndpointHandle local;
     52     ScopedInterfaceEndpointHandle remote;
     53     CreateEndpointHandlePair(&local, &remote);
     54 
     55     if (!local.is_valid() || !remote.is_valid()) {
     56       *ptr_info = AssociatedInterfacePtrInfo<T>();
     57       *request = AssociatedInterfaceRequest<T>();
     58       return;
     59     }
     60 
     61     if (config == WILL_PASS_PTR) {
     62       ptr_info->set_handle(std::move(remote));
     63 
     64       // The implementation is local, therefore set the version according to
     65       // the interface definition that this code is built against.
     66       ptr_info->set_version(T::Version_);
     67       request->Bind(std::move(local));
     68     } else {
     69       ptr_info->set_handle(std::move(local));
     70 
     71       // The implementation is remote, we don't know about its actual version
     72       // yet.
     73       ptr_info->set_version(0u);
     74       request->Bind(std::move(remote));
     75     }
     76   }
     77 
     78  private:
     79   friend class AssociatedGroupController;
     80 
     81   void CreateEndpointHandlePair(
     82       ScopedInterfaceEndpointHandle* local_endpoint,
     83       ScopedInterfaceEndpointHandle* remote_endpoint);
     84 
     85   scoped_refptr<AssociatedGroupController> controller_;
     86 };
     87 
     88 }  // namespace mojo
     89 
     90 #endif  // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_GROUP_H_
     91