• 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_INTERFACE_ENDPOINT_CLIENT_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_ENDPOINT_CLIENT_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 
13 #include "base/callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/logging.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/optional.h"
20 #include "base/single_thread_task_runner.h"
21 #include "base/threading/thread_checker.h"
22 #include "mojo/public/cpp/bindings/bindings_export.h"
23 #include "mojo/public/cpp/bindings/connection_error_callback.h"
24 #include "mojo/public/cpp/bindings/disconnect_reason.h"
25 #include "mojo/public/cpp/bindings/filter_chain.h"
26 #include "mojo/public/cpp/bindings/lib/control_message_handler.h"
27 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h"
28 #include "mojo/public/cpp/bindings/message.h"
29 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
30 
31 namespace mojo {
32 
33 class AssociatedGroup;
34 class InterfaceEndpointController;
35 
36 // InterfaceEndpointClient handles message sending and receiving of an interface
37 // endpoint, either the implementation side or the client side.
38 // It should only be accessed and destructed on the creating thread.
39 class MOJO_CPP_BINDINGS_EXPORT InterfaceEndpointClient
NON_EXPORTED_BASE(public MessageReceiverWithResponder)40     : NON_EXPORTED_BASE(public MessageReceiverWithResponder) {
41  public:
42   // |receiver| is okay to be null. If it is not null, it must outlive this
43   // object.
44   InterfaceEndpointClient(ScopedInterfaceEndpointHandle handle,
45                           MessageReceiverWithResponderStatus* receiver,
46                           std::unique_ptr<MessageReceiver> payload_validator,
47                           bool expect_sync_requests,
48                           scoped_refptr<base::SingleThreadTaskRunner> runner,
49                           uint32_t interface_version);
50   ~InterfaceEndpointClient() override;
51 
52   // Sets the error handler to receive notifications when an error is
53   // encountered.
54   void set_connection_error_handler(const base::Closure& error_handler) {
55     DCHECK(thread_checker_.CalledOnValidThread());
56     error_handler_ = error_handler;
57     error_with_reason_handler_.Reset();
58   }
59 
60   void set_connection_error_with_reason_handler(
61       const ConnectionErrorWithReasonCallback& error_handler) {
62     DCHECK(thread_checker_.CalledOnValidThread());
63     error_with_reason_handler_ = error_handler;
64     error_handler_.Reset();
65   }
66 
67   // Returns true if an error was encountered.
68   bool encountered_error() const {
69     DCHECK(thread_checker_.CalledOnValidThread());
70     return encountered_error_;
71   }
72 
73   // Returns true if this endpoint has any pending callbacks.
74   bool has_pending_responders() const {
75     DCHECK(thread_checker_.CalledOnValidThread());
76     return !async_responders_.empty() || !sync_responses_.empty();
77   }
78 
79   AssociatedGroup* associated_group();
80 
81   // Adds a MessageReceiver which can filter a message after validation but
82   // before dispatch.
83   void AddFilter(std::unique_ptr<MessageReceiver> filter);
84 
85   // After this call the object is in an invalid state and shouldn't be reused.
86   ScopedInterfaceEndpointHandle PassHandle();
87 
88   // Raises an error on the underlying message pipe. It disconnects the pipe
89   // and notifies all interfaces running on this pipe.
90   void RaiseError();
91 
92   void CloseWithReason(uint32_t custom_reason, const std::string& description);
93 
94   // MessageReceiverWithResponder implementation:
95   // They must only be called when the handle is not in pending association
96   // state.
97   bool Accept(Message* message) override;
98   bool AcceptWithResponder(Message* message,
99                            MessageReceiver* responder) override;
100 
101   // The following methods are called by the router. They must be called
102   // outside of the router's lock.
103 
104   // NOTE: |message| must have passed message header validation.
105   bool HandleIncomingMessage(Message* message);
106   void NotifyError(const base::Optional<DisconnectReason>& reason);
107 
108   // The following methods send interface control messages.
109   // They must only be called when the handle is not in pending association
110   // state.
111   void QueryVersion(const base::Callback<void(uint32_t)>& callback);
112   void RequireVersion(uint32_t version);
113   void FlushForTesting();
114 
115  private:
116   // Maps from the id of a response to the MessageReceiver that handles the
117   // response.
118   using AsyncResponderMap =
119       std::map<uint64_t, std::unique_ptr<MessageReceiver>>;
120 
121   struct SyncResponseInfo {
122    public:
123     explicit SyncResponseInfo(bool* in_response_received);
124     ~SyncResponseInfo();
125 
126     Message response;
127 
128     // Points to a stack-allocated variable.
129     bool* response_received;
130 
131    private:
132     DISALLOW_COPY_AND_ASSIGN(SyncResponseInfo);
133   };
134 
135   using SyncResponseMap = std::map<uint64_t, std::unique_ptr<SyncResponseInfo>>;
136 
137   // Used as the sink for |payload_validator_| and forwards messages to
138   // HandleValidatedMessage().
139   class HandleIncomingMessageThunk : public MessageReceiver {
140    public:
141     explicit HandleIncomingMessageThunk(InterfaceEndpointClient* owner);
142     ~HandleIncomingMessageThunk() override;
143 
144     // MessageReceiver implementation:
145     bool Accept(Message* message) override;
146 
147    private:
148     InterfaceEndpointClient* const owner_;
149 
150     DISALLOW_COPY_AND_ASSIGN(HandleIncomingMessageThunk);
151   };
152 
153   void InitControllerIfNecessary();
154 
155   void OnAssociationEvent(
156       ScopedInterfaceEndpointHandle::AssociationEvent event);
157 
158   bool HandleValidatedMessage(Message* message);
159 
160   const bool expect_sync_requests_ = false;
161 
162   ScopedInterfaceEndpointHandle handle_;
163   std::unique_ptr<AssociatedGroup> associated_group_;
164   InterfaceEndpointController* controller_ = nullptr;
165 
166   MessageReceiverWithResponderStatus* const incoming_receiver_ = nullptr;
167   HandleIncomingMessageThunk thunk_;
168   FilterChain filters_;
169 
170   AsyncResponderMap async_responders_;
171   SyncResponseMap sync_responses_;
172 
173   uint64_t next_request_id_ = 1;
174 
175   base::Closure error_handler_;
176   ConnectionErrorWithReasonCallback error_with_reason_handler_;
177   bool encountered_error_ = false;
178 
179   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
180 
181   internal::ControlMessageProxy control_message_proxy_;
182   internal::ControlMessageHandler control_message_handler_;
183 
184   base::ThreadChecker thread_checker_;
185 
186   base::WeakPtrFactory<InterfaceEndpointClient> weak_ptr_factory_;
187 
188   DISALLOW_COPY_AND_ASSIGN(InterfaceEndpointClient);
189 };
190 
191 }  // namespace mojo
192 
193 #endif  // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_ENDPOINT_CLIENT_H_
194