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