• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_LIB_ASSOCIATED_INTERFACE_PTR_STATE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ASSOCIATED_INTERFACE_PTR_STATE_H_
7 
8 #include <stdint.h>
9 
10 #include <algorithm>  // For |std::swap()|.
11 #include <memory>
12 #include <string>
13 #include <utility>
14 
15 #include "base/bind.h"
16 #include "base/callback_forward.h"
17 #include "base/macros.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/sequenced_task_runner.h"
21 #include "mojo/public/cpp/bindings/associated_group.h"
22 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
23 #include "mojo/public/cpp/bindings/bindings_export.h"
24 #include "mojo/public/cpp/bindings/connection_error_callback.h"
25 #include "mojo/public/cpp/bindings/interface_endpoint_client.h"
26 #include "mojo/public/cpp/bindings/interface_id.h"
27 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
28 #include "mojo/public/cpp/system/message_pipe.h"
29 
30 namespace mojo {
31 namespace internal {
32 
33 class MOJO_CPP_BINDINGS_EXPORT AssociatedInterfacePtrStateBase {
34  public:
35   AssociatedInterfacePtrStateBase();
36   ~AssociatedInterfacePtrStateBase();
37 
version()38   uint32_t version() const { return version_; }
39 
40   void QueryVersion(const base::Callback<void(uint32_t)>& callback);
41   void RequireVersion(uint32_t version);
42   void FlushForTesting();
43   void CloseWithReason(uint32_t custom_reason, const std::string& description);
44 
is_bound()45   bool is_bound() const { return !!endpoint_client_; }
46 
encountered_error()47   bool encountered_error() const {
48     return endpoint_client_ ? endpoint_client_->encountered_error() : false;
49   }
50 
set_connection_error_handler(base::OnceClosure error_handler)51   void set_connection_error_handler(base::OnceClosure error_handler) {
52     DCHECK(endpoint_client_);
53     endpoint_client_->set_connection_error_handler(std::move(error_handler));
54   }
55 
set_connection_error_with_reason_handler(ConnectionErrorWithReasonCallback error_handler)56   void set_connection_error_with_reason_handler(
57       ConnectionErrorWithReasonCallback error_handler) {
58     DCHECK(endpoint_client_);
59     endpoint_client_->set_connection_error_with_reason_handler(
60         std::move(error_handler));
61   }
62 
63   // Returns true if bound and awaiting a response to a message.
has_pending_callbacks()64   bool has_pending_callbacks() const {
65     return endpoint_client_ && endpoint_client_->has_pending_responders();
66   }
67 
associated_group()68   AssociatedGroup* associated_group() {
69     return endpoint_client_ ? endpoint_client_->associated_group() : nullptr;
70   }
71 
ForwardMessage(Message message)72   void ForwardMessage(Message message) { endpoint_client_->Accept(&message); }
73 
ForwardMessageWithResponder(Message message,std::unique_ptr<MessageReceiver> responder)74   void ForwardMessageWithResponder(Message message,
75                                    std::unique_ptr<MessageReceiver> responder) {
76     endpoint_client_->AcceptWithResponder(&message, std::move(responder));
77   }
78 
79  protected:
80   void Swap(AssociatedInterfacePtrStateBase* other);
81   void Bind(ScopedInterfaceEndpointHandle handle,
82             uint32_t version,
83             std::unique_ptr<MessageReceiver> validator,
84             scoped_refptr<base::SequencedTaskRunner> runner);
85   ScopedInterfaceEndpointHandle PassHandle();
86 
endpoint_client()87   InterfaceEndpointClient* endpoint_client() { return endpoint_client_.get(); }
88 
89  private:
90   void OnQueryVersion(const base::Callback<void(uint32_t)>& callback,
91                       uint32_t version);
92 
93   std::unique_ptr<InterfaceEndpointClient> endpoint_client_;
94   uint32_t version_ = 0;
95 };
96 
97 template <typename Interface>
98 class AssociatedInterfacePtrState : public AssociatedInterfacePtrStateBase {
99  public:
100   using Proxy = typename Interface::Proxy_;
101 
AssociatedInterfacePtrState()102   AssociatedInterfacePtrState() {}
103   ~AssociatedInterfacePtrState() = default;
104 
instance()105   Proxy* instance() {
106     // This will be null if the object is not bound.
107     return proxy_.get();
108   }
109 
Swap(AssociatedInterfacePtrState * other)110   void Swap(AssociatedInterfacePtrState* other) {
111     AssociatedInterfacePtrStateBase::Swap(other);
112     std::swap(other->proxy_, proxy_);
113   }
114 
Bind(AssociatedInterfacePtrInfo<Interface> info,scoped_refptr<base::SequencedTaskRunner> runner)115   void Bind(AssociatedInterfacePtrInfo<Interface> info,
116             scoped_refptr<base::SequencedTaskRunner> runner) {
117     DCHECK(!proxy_);
118     AssociatedInterfacePtrStateBase::Bind(
119         info.PassHandle(), info.version(),
120         std::make_unique<typename Interface::ResponseValidator_>(),
121         std::move(runner));
122     proxy_.reset(new Proxy(endpoint_client()));
123   }
124 
125   // After this method is called, the object is in an invalid state and
126   // shouldn't be reused.
PassInterface()127   AssociatedInterfacePtrInfo<Interface> PassInterface() {
128     AssociatedInterfacePtrInfo<Interface> info(PassHandle(), version());
129     proxy_.reset();
130     return info;
131   }
132 
133  private:
134   std::unique_ptr<Proxy> proxy_;
135 
136   DISALLOW_COPY_AND_ASSIGN(AssociatedInterfacePtrState);
137 };
138 
139 }  // namespace internal
140 }  // namespace mojo
141 
142 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_ASSOCIATED_INTERFACE_PTR_STATE_H_
143