• 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/single_thread_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/connection_error_callback.h"
24 #include "mojo/public/cpp/bindings/interface_endpoint_client.h"
25 #include "mojo/public/cpp/bindings/interface_id.h"
26 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
27 #include "mojo/public/cpp/system/message_pipe.h"
28 
29 namespace mojo {
30 namespace internal {
31 
32 template <typename Interface>
33 class AssociatedInterfacePtrState {
34  public:
AssociatedInterfacePtrState()35   AssociatedInterfacePtrState() : version_(0u) {}
36 
~AssociatedInterfacePtrState()37   ~AssociatedInterfacePtrState() {
38     endpoint_client_.reset();
39     proxy_.reset();
40   }
41 
instance()42   Interface* instance() {
43     // This will be null if the object is not bound.
44     return proxy_.get();
45   }
46 
version()47   uint32_t version() const { return version_; }
48 
QueryVersion(const base::Callback<void (uint32_t)> & callback)49   void QueryVersion(const base::Callback<void(uint32_t)>& callback) {
50     // It is safe to capture |this| because the callback won't be run after this
51     // object goes away.
52     endpoint_client_->QueryVersion(
53         base::Bind(&AssociatedInterfacePtrState::OnQueryVersion,
54                    base::Unretained(this), callback));
55   }
56 
RequireVersion(uint32_t version)57   void RequireVersion(uint32_t version) {
58     if (version <= version_)
59       return;
60 
61     version_ = version;
62     endpoint_client_->RequireVersion(version);
63   }
64 
FlushForTesting()65   void FlushForTesting() { endpoint_client_->FlushForTesting(); }
66 
CloseWithReason(uint32_t custom_reason,const std::string & description)67   void CloseWithReason(uint32_t custom_reason, const std::string& description) {
68     endpoint_client_->CloseWithReason(custom_reason, description);
69   }
70 
Swap(AssociatedInterfacePtrState * other)71   void Swap(AssociatedInterfacePtrState* other) {
72     using std::swap;
73     swap(other->endpoint_client_, endpoint_client_);
74     swap(other->proxy_, proxy_);
75     swap(other->version_, version_);
76   }
77 
Bind(AssociatedInterfacePtrInfo<Interface> info,scoped_refptr<base::SingleThreadTaskRunner> runner)78   void Bind(AssociatedInterfacePtrInfo<Interface> info,
79             scoped_refptr<base::SingleThreadTaskRunner> runner) {
80     DCHECK(!endpoint_client_);
81     DCHECK(!proxy_);
82     DCHECK_EQ(0u, version_);
83     DCHECK(info.is_valid());
84 
85     version_ = info.version();
86     // The version is only queried from the client so the value passed here
87     // will not be used.
88     endpoint_client_.reset(new InterfaceEndpointClient(
89         info.PassHandle(), nullptr,
90         base::WrapUnique(new typename Interface::ResponseValidator_()), false,
91         std::move(runner), 0u));
92     proxy_.reset(new Proxy(endpoint_client_.get()));
93   }
94 
95   // After this method is called, the object is in an invalid state and
96   // shouldn't be reused.
PassInterface()97   AssociatedInterfacePtrInfo<Interface> PassInterface() {
98     ScopedInterfaceEndpointHandle handle = endpoint_client_->PassHandle();
99     endpoint_client_.reset();
100     proxy_.reset();
101     return AssociatedInterfacePtrInfo<Interface>(std::move(handle), version_);
102   }
103 
is_bound()104   bool is_bound() const { return !!endpoint_client_; }
105 
encountered_error()106   bool encountered_error() const {
107     return endpoint_client_ ? endpoint_client_->encountered_error() : false;
108   }
109 
set_connection_error_handler(const base::Closure & error_handler)110   void set_connection_error_handler(const base::Closure& error_handler) {
111     DCHECK(endpoint_client_);
112     endpoint_client_->set_connection_error_handler(error_handler);
113   }
114 
set_connection_error_with_reason_handler(const ConnectionErrorWithReasonCallback & error_handler)115   void set_connection_error_with_reason_handler(
116       const ConnectionErrorWithReasonCallback& error_handler) {
117     DCHECK(endpoint_client_);
118     endpoint_client_->set_connection_error_with_reason_handler(error_handler);
119   }
120 
121   // Returns true if bound and awaiting a response to a message.
has_pending_callbacks()122   bool has_pending_callbacks() const {
123     return endpoint_client_ && endpoint_client_->has_pending_responders();
124   }
125 
associated_group()126   AssociatedGroup* associated_group() {
127     return endpoint_client_ ? endpoint_client_->associated_group() : nullptr;
128   }
129 
ForwardMessage(Message message)130   void ForwardMessage(Message message) { endpoint_client_->Accept(&message); }
131 
ForwardMessageWithResponder(Message message,std::unique_ptr<MessageReceiver> responder)132   void ForwardMessageWithResponder(Message message,
133                                    std::unique_ptr<MessageReceiver> responder) {
134     endpoint_client_->AcceptWithResponder(&message, responder.release());
135   }
136 
137  private:
138   using Proxy = typename Interface::Proxy_;
139 
OnQueryVersion(const base::Callback<void (uint32_t)> & callback,uint32_t version)140   void OnQueryVersion(const base::Callback<void(uint32_t)>& callback,
141                       uint32_t version) {
142     version_ = version;
143     callback.Run(version);
144   }
145 
146   std::unique_ptr<InterfaceEndpointClient> endpoint_client_;
147   std::unique_ptr<Proxy> proxy_;
148 
149   uint32_t version_;
150 
151   DISALLOW_COPY_AND_ASSIGN(AssociatedInterfacePtrState);
152 };
153 
154 }  // namespace internal
155 }  // namespace mojo
156 
157 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_ASSOCIATED_INTERFACE_PTR_STATE_H_
158