1 // Copyright 2014 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_MESSAGE_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <limits> 12 #include <memory> 13 #include <string> 14 #include <vector> 15 16 #include "base/callback.h" 17 #include "base/compiler_specific.h" 18 #include "base/logging.h" 19 #include "mojo/public/cpp/bindings/bindings_export.h" 20 #include "mojo/public/cpp/bindings/lib/message_buffer.h" 21 #include "mojo/public/cpp/bindings/lib/message_internal.h" 22 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 23 #include "mojo/public/cpp/system/message.h" 24 25 namespace mojo { 26 27 class AssociatedGroupController; 28 29 using ReportBadMessageCallback = base::Callback<void(const std::string& error)>; 30 31 // Message is a holder for the data and handles to be sent over a MessagePipe. 32 // Message owns its data and handles, but a consumer of Message is free to 33 // mutate the data and handles. The message's data is comprised of a header 34 // followed by payload. 35 class MOJO_CPP_BINDINGS_EXPORT Message { 36 public: 37 static const uint32_t kFlagExpectsResponse = 1 << 0; 38 static const uint32_t kFlagIsResponse = 1 << 1; 39 static const uint32_t kFlagIsSync = 1 << 2; 40 41 Message(); 42 Message(Message&& other); 43 44 ~Message(); 45 46 Message& operator=(Message&& other); 47 48 // Resets the Message to an uninitialized state. Upon reset, the Message 49 // exists as if it were default-constructed: it has no data buffer and owns no 50 // handles. 51 void Reset(); 52 53 // Indicates whether this Message is uninitialized. IsNull()54 bool IsNull() const { return !buffer_; } 55 56 // Initializes a Message with enough space for |capacity| bytes. 57 void Initialize(size_t capacity, bool zero_initialized); 58 59 // Initializes a Message from an existing Mojo MessageHandle. 60 void InitializeFromMojoMessage(ScopedMessageHandle message, 61 uint32_t num_bytes, 62 std::vector<Handle>* handles); 63 data_num_bytes()64 uint32_t data_num_bytes() const { 65 return static_cast<uint32_t>(buffer_->size()); 66 } 67 68 // Access the raw bytes of the message. data()69 const uint8_t* data() const { 70 return static_cast<const uint8_t*>(buffer_->data()); 71 } 72 mutable_data()73 uint8_t* mutable_data() { return static_cast<uint8_t*>(buffer_->data()); } 74 75 // Access the header. header()76 const internal::MessageHeader* header() const { 77 return static_cast<const internal::MessageHeader*>(buffer_->data()); 78 } header()79 internal::MessageHeader* header() { 80 return static_cast<internal::MessageHeader*>(buffer_->data()); 81 } 82 header_v1()83 const internal::MessageHeaderV1* header_v1() const { 84 DCHECK_GE(version(), 1u); 85 return static_cast<const internal::MessageHeaderV1*>(buffer_->data()); 86 } header_v1()87 internal::MessageHeaderV1* header_v1() { 88 DCHECK_GE(version(), 1u); 89 return static_cast<internal::MessageHeaderV1*>(buffer_->data()); 90 } 91 header_v2()92 const internal::MessageHeaderV2* header_v2() const { 93 DCHECK_GE(version(), 2u); 94 return static_cast<const internal::MessageHeaderV2*>(buffer_->data()); 95 } header_v2()96 internal::MessageHeaderV2* header_v2() { 97 DCHECK_GE(version(), 2u); 98 return static_cast<internal::MessageHeaderV2*>(buffer_->data()); 99 } 100 version()101 uint32_t version() const { return header()->version; } 102 interface_id()103 uint32_t interface_id() const { return header()->interface_id; } set_interface_id(uint32_t id)104 void set_interface_id(uint32_t id) { header()->interface_id = id; } 105 name()106 uint32_t name() const { return header()->name; } has_flag(uint32_t flag)107 bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); } 108 109 // Access the request_id field (if present). request_id()110 uint64_t request_id() const { return header_v1()->request_id; } set_request_id(uint64_t request_id)111 void set_request_id(uint64_t request_id) { 112 header_v1()->request_id = request_id; 113 } 114 115 // Access the payload. 116 const uint8_t* payload() const; mutable_payload()117 uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); } 118 uint32_t payload_num_bytes() const; 119 120 uint32_t payload_num_interface_ids() const; 121 const uint32_t* payload_interface_ids() const; 122 123 // Access the handles. handles()124 const std::vector<Handle>* handles() const { return &handles_; } mutable_handles()125 std::vector<Handle>* mutable_handles() { return &handles_; } 126 127 const std::vector<ScopedInterfaceEndpointHandle>* associated_endpoint_handles()128 associated_endpoint_handles() const { 129 return &associated_endpoint_handles_; 130 } 131 std::vector<ScopedInterfaceEndpointHandle>* mutable_associated_endpoint_handles()132 mutable_associated_endpoint_handles() { 133 return &associated_endpoint_handles_; 134 } 135 136 // Access the underlying Buffer interface. buffer()137 internal::Buffer* buffer() { return buffer_.get(); } 138 139 // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for 140 // transmission. Note that this invalidates this Message object, taking 141 // ownership of its internal storage and any attached handles. 142 ScopedMessageHandle TakeMojoMessage(); 143 144 // Notifies the system that this message is "bad," in this case meaning it was 145 // rejected by bindings validation code. 146 void NotifyBadMessage(const std::string& error); 147 148 // Serializes |associated_endpoint_handles_| into the payload_interface_ids 149 // field. 150 void SerializeAssociatedEndpointHandles( 151 AssociatedGroupController* group_controller); 152 153 // Deserializes |associated_endpoint_handles_| from the payload_interface_ids 154 // field. 155 bool DeserializeAssociatedEndpointHandles( 156 AssociatedGroupController* group_controller); 157 158 private: 159 void CloseHandles(); 160 161 std::unique_ptr<internal::MessageBuffer> buffer_; 162 std::vector<Handle> handles_; 163 std::vector<ScopedInterfaceEndpointHandle> associated_endpoint_handles_; 164 165 DISALLOW_COPY_AND_ASSIGN(Message); 166 }; 167 168 class MessageReceiver { 169 public: ~MessageReceiver()170 virtual ~MessageReceiver() {} 171 172 // The receiver may mutate the given message. Returns true if the message 173 // was accepted and false otherwise, indicating that the message was invalid 174 // or malformed. 175 virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0; 176 }; 177 178 class MessageReceiverWithResponder : public MessageReceiver { 179 public: ~MessageReceiverWithResponder()180 ~MessageReceiverWithResponder() override {} 181 182 // A variant on Accept that registers a MessageReceiver (known as the 183 // responder) to handle the response message generated from the given 184 // message. The responder's Accept method may be called during 185 // AcceptWithResponder or some time after its return. 186 // 187 // NOTE: Upon returning true, AcceptWithResponder assumes ownership of 188 // |responder| and will delete it after calling |responder->Accept| or upon 189 // its own destruction. 190 // 191 // TODO(yzshen): consider changing |responder| to 192 // std::unique_ptr<MessageReceiver>. 193 virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) 194 WARN_UNUSED_RESULT = 0; 195 }; 196 197 // A MessageReceiver that is also able to provide status about the state 198 // of the underlying MessagePipe to which it will be forwarding messages 199 // received via the |Accept()| call. 200 class MessageReceiverWithStatus : public MessageReceiver { 201 public: ~MessageReceiverWithStatus()202 ~MessageReceiverWithStatus() override {} 203 204 // Returns |true| if this MessageReceiver is currently bound to a MessagePipe, 205 // the pipe has not been closed, and the pipe has not encountered an error. 206 virtual bool IsValid() = 0; 207 208 // DCHECKs if this MessageReceiver is currently bound to a MessagePipe, the 209 // pipe has not been closed, and the pipe has not encountered an error. 210 // This function may be called on any thread. 211 virtual void DCheckInvalid(const std::string& message) = 0; 212 }; 213 214 // An alternative to MessageReceiverWithResponder for cases in which it 215 // is necessary for the implementor of this interface to know about the status 216 // of the MessagePipe which will carry the responses. 217 class MessageReceiverWithResponderStatus : public MessageReceiver { 218 public: ~MessageReceiverWithResponderStatus()219 ~MessageReceiverWithResponderStatus() override {} 220 221 // A variant on Accept that registers a MessageReceiverWithStatus (known as 222 // the responder) to handle the response message generated from the given 223 // message. Any of the responder's methods (Accept or IsValid) may be called 224 // during AcceptWithResponder or some time after its return. 225 // 226 // NOTE: Upon returning true, AcceptWithResponder assumes ownership of 227 // |responder| and will delete it after calling |responder->Accept| or upon 228 // its own destruction. 229 // 230 // TODO(yzshen): consider changing |responder| to 231 // std::unique_ptr<MessageReceiver>. 232 virtual bool AcceptWithResponder(Message* message, 233 MessageReceiverWithStatus* responder) 234 WARN_UNUSED_RESULT = 0; 235 }; 236 237 class MOJO_CPP_BINDINGS_EXPORT PassThroughFilter NON_EXPORTED_BASE(public MessageReceiver)238 : NON_EXPORTED_BASE(public MessageReceiver) { 239 public: 240 PassThroughFilter(); 241 ~PassThroughFilter() override; 242 243 // MessageReceiver: 244 bool Accept(Message* message) override; 245 246 private: 247 DISALLOW_COPY_AND_ASSIGN(PassThroughFilter); 248 }; 249 250 namespace internal { 251 class SyncMessageResponseSetup; 252 } 253 254 // An object which should be constructed on the stack immediately before making 255 // a sync request for which the caller wishes to perform custom validation of 256 // the response value(s). It is illegal to make more than one sync call during 257 // the lifetime of the topmost SyncMessageResponseContext, but it is legal to 258 // nest contexts to support reentrancy. 259 // 260 // Usage should look something like: 261 // 262 // SyncMessageResponseContext response_context; 263 // foo_interface->SomeSyncCall(&response_value); 264 // if (response_value.IsBad()) 265 // response_context.ReportBadMessage("Bad response_value!"); 266 // 267 class MOJO_CPP_BINDINGS_EXPORT SyncMessageResponseContext { 268 public: 269 SyncMessageResponseContext(); 270 ~SyncMessageResponseContext(); 271 272 static SyncMessageResponseContext* current(); 273 274 void ReportBadMessage(const std::string& error); 275 276 const ReportBadMessageCallback& GetBadMessageCallback(); 277 278 private: 279 friend class internal::SyncMessageResponseSetup; 280 281 SyncMessageResponseContext* outer_context_; 282 Message response_; 283 ReportBadMessageCallback bad_message_callback_; 284 285 DISALLOW_COPY_AND_ASSIGN(SyncMessageResponseContext); 286 }; 287 288 // Read a single message from the pipe. The caller should have created the 289 // Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if 290 // the caller should wait on the handle to become readable. Returns 291 // MOJO_RESULT_OK if the message was read successfully and should be 292 // dispatched, otherwise returns an error code if something went wrong. 293 // 294 // NOTE: The message hasn't been validated and may be malformed! 295 MojoResult ReadMessage(MessagePipeHandle handle, Message* message); 296 297 // Reports the currently dispatching Message as bad. Note that this is only 298 // legal to call from directly within the stack frame of a message dispatch. If 299 // you need to do asynchronous work before you can determine the legitimacy of 300 // a message, use TakeBadMessageCallback() and retain its result until you're 301 // ready to invoke or discard it. 302 MOJO_CPP_BINDINGS_EXPORT 303 void ReportBadMessage(const std::string& error); 304 305 // Acquires a callback which may be run to report the currently dispatching 306 // Message as bad. Note that this is only legal to call from directly within the 307 // stack frame of a message dispatch, but the returned callback may be called 308 // exactly once any time thereafter to report the message as bad. This may only 309 // be called once per message. 310 MOJO_CPP_BINDINGS_EXPORT 311 ReportBadMessageCallback GetBadMessageCallback(); 312 313 } // namespace mojo 314 315 #endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 316