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