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/logging.h" 15 #include "base/macros.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/single_thread_task_runner.h" 19 #include "base/threading/thread_checker.h" 20 #include "mojo/public/cpp/bindings/message.h" 21 #include "mojo/public/cpp/bindings/message_filter.h" 22 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 23 24 namespace mojo { 25 26 class AssociatedGroup; 27 class AssociatedGroupController; 28 class InterfaceEndpointController; 29 30 // InterfaceEndpointClient handles message sending and receiving of an interface 31 // endpoint, either the implementation side or the client side. 32 // It should only be accessed and destructed on the creating thread. 33 class InterfaceEndpointClient : public MessageReceiverWithResponder { 34 public: 35 // |receiver| is okay to be null. If it is not null, it must outlive this 36 // object. 37 InterfaceEndpointClient(ScopedInterfaceEndpointHandle handle, 38 MessageReceiverWithResponderStatus* receiver, 39 std::unique_ptr<MessageFilter> payload_validator, 40 bool expect_sync_requests, 41 scoped_refptr<base::SingleThreadTaskRunner> runner); 42 ~InterfaceEndpointClient() override; 43 44 // Sets the error handler to receive notifications when an error is 45 // encountered. set_connection_error_handler(const base::Closure & error_handler)46 void set_connection_error_handler(const base::Closure& error_handler) { 47 DCHECK(thread_checker_.CalledOnValidThread()); 48 error_handler_ = error_handler; 49 } 50 51 // Returns true if an error was encountered. encountered_error()52 bool encountered_error() const { 53 DCHECK(thread_checker_.CalledOnValidThread()); 54 return encountered_error_; 55 } 56 57 // Returns true if this endpoint has any pending callbacks. has_pending_responders()58 bool has_pending_responders() const { 59 DCHECK(thread_checker_.CalledOnValidThread()); 60 return !async_responders_.empty() || !sync_responses_.empty(); 61 } 62 group_controller()63 AssociatedGroupController* group_controller() const { 64 return handle_.group_controller(); 65 } 66 AssociatedGroup* associated_group(); 67 uint32_t interface_id() const; 68 69 // After this call the object is in an invalid state and shouldn't be reused. 70 ScopedInterfaceEndpointHandle PassHandle(); 71 72 // Raises an error on the underlying message pipe. It disconnects the pipe 73 // and notifies all interfaces running on this pipe. 74 void RaiseError(); 75 76 // MessageReceiverWithResponder implementation: 77 bool Accept(Message* message) override; 78 bool AcceptWithResponder(Message* message, 79 MessageReceiver* responder) override; 80 81 // The following methods are called by the router. They must be called 82 // outside of the router's lock. 83 84 // NOTE: |message| must have passed message header validation. 85 bool HandleIncomingMessage(Message* message); 86 void NotifyError(); 87 88 private: 89 // Maps from the id of a response to the MessageReceiver that handles the 90 // response. 91 using AsyncResponderMap = 92 std::map<uint64_t, std::unique_ptr<MessageReceiver>>; 93 94 struct SyncResponseInfo { 95 public: 96 explicit SyncResponseInfo(bool* in_response_received); 97 ~SyncResponseInfo(); 98 99 std::unique_ptr<Message> response; 100 101 // Points to a stack-allocated variable. 102 bool* response_received; 103 104 private: 105 DISALLOW_COPY_AND_ASSIGN(SyncResponseInfo); 106 }; 107 108 using SyncResponseMap = std::map<uint64_t, std::unique_ptr<SyncResponseInfo>>; 109 110 // Used as the sink for |payload_validator_| and forwards messages to 111 // HandleValidatedMessage(). 112 class HandleIncomingMessageThunk : public MessageReceiver { 113 public: 114 explicit HandleIncomingMessageThunk(InterfaceEndpointClient* owner); 115 ~HandleIncomingMessageThunk() override; 116 117 // MessageReceiver implementation: 118 bool Accept(Message* message) override; 119 120 private: 121 InterfaceEndpointClient* const owner_; 122 123 DISALLOW_COPY_AND_ASSIGN(HandleIncomingMessageThunk); 124 }; 125 126 bool HandleValidatedMessage(Message* message); 127 128 ScopedInterfaceEndpointHandle handle_; 129 std::unique_ptr<AssociatedGroup> associated_group_; 130 InterfaceEndpointController* controller_; 131 132 MessageReceiverWithResponderStatus* const incoming_receiver_; 133 std::unique_ptr<MessageFilter> payload_validator_; 134 HandleIncomingMessageThunk thunk_; 135 136 AsyncResponderMap async_responders_; 137 SyncResponseMap sync_responses_; 138 139 uint64_t next_request_id_; 140 141 base::Closure error_handler_; 142 bool encountered_error_; 143 144 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 145 146 base::ThreadChecker thread_checker_; 147 148 base::WeakPtrFactory<InterfaceEndpointClient> weak_ptr_factory_; 149 150 DISALLOW_COPY_AND_ASSIGN(InterfaceEndpointClient); 151 }; 152 153 } // namespace mojo 154 155 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_ENDPOINT_CLIENT_H_ 156