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