blob: 42f47d2d1a90c5187510bb99db454fb3061d62c9 [file] [log] [blame]
rockot85dce0862015-11-13 01:33:591// Copyright 2013 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#include "mojo/public/cpp/bindings/message.h"
6
Avi Drissman2e88ac372015-12-21 18:14:577#include <stddef.h>
8#include <stdint.h>
rockot85dce0862015-11-13 01:33:599#include <stdlib.h>
10
11#include <algorithm>
rockot596231c2016-04-29 18:46:4512#include <utility>
rockot85dce0862015-11-13 01:33:5913
rockot160577e92016-08-03 20:24:4414#include "base/bind.h"
15#include "base/lazy_instance.h"
yzshen380137e2016-02-16 18:26:5316#include "base/logging.h"
Ken Rockot559b70d2017-07-17 22:35:2417#include "base/numerics/safe_math.h"
rockot8a88e80c2016-06-16 02:30:3018#include "base/strings/stringprintf.h"
rockot160577e92016-08-03 20:24:4419#include "base/threading/thread_local.h"
yzshenea784ea2017-01-31 21:20:2020#include "mojo/public/cpp/bindings/associated_group_controller.h"
21#include "mojo/public/cpp/bindings/lib/array_internal.h"
Ken Rockot474df0142017-07-12 13:28:5622#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
rockot85dce0862015-11-13 01:33:5923
24namespace mojo {
25
rockot160577e92016-08-03 20:24:4426namespace {
27
scottmg5e65e3a2017-03-08 08:48:4628base::LazyInstance<base::ThreadLocalPointer<internal::MessageDispatchContext>>::
Sam McNally04e9abf2017-06-22 23:53:4529 Leaky g_tls_message_dispatch_context = LAZY_INSTANCE_INITIALIZER;
rockot160577e92016-08-03 20:24:4430
Sam McNally04e9abf2017-06-22 23:53:4531base::LazyInstance<base::ThreadLocalPointer<SyncMessageResponseContext>>::Leaky
32 g_tls_sync_response_context = LAZY_INSTANCE_INITIALIZER;
rockot160577e92016-08-03 20:24:4433
rockotc4cc691e2016-08-19 18:48:5734void DoNotifyBadMessage(Message message, const std::string& error) {
35 message.NotifyBadMessage(error);
36}
37
Ken Rockot474df0142017-07-12 13:28:5638template <typename HeaderType>
39void AllocateHeaderFromBuffer(internal::Buffer* buffer, HeaderType** header) {
Ken Rockot7c91af2d2017-07-28 09:54:4040 *header = buffer->AllocateAndGet<HeaderType>();
Ken Rockot474df0142017-07-12 13:28:5641 (*header)->num_bytes = sizeof(HeaderType);
Ken Rockota5a7c952017-06-17 09:10:0742}
43
44void WriteMessageHeader(uint32_t name,
45 uint32_t flags,
46 size_t payload_interface_id_count,
47 internal::Buffer* payload_buffer) {
48 if (payload_interface_id_count > 0) {
49 // Version 2
50 internal::MessageHeaderV2* header;
51 AllocateHeaderFromBuffer(payload_buffer, &header);
52 header->version = 2;
53 header->name = name;
54 header->flags = flags;
55 // The payload immediately follows the header.
56 header->payload.Set(header + 1);
57 } else if (flags &
58 (Message::kFlagExpectsResponse | Message::kFlagIsResponse)) {
59 // Version 1
60 internal::MessageHeaderV1* header;
61 AllocateHeaderFromBuffer(payload_buffer, &header);
62 header->version = 1;
63 header->name = name;
64 header->flags = flags;
65 } else {
66 internal::MessageHeader* header;
67 AllocateHeaderFromBuffer(payload_buffer, &header);
68 header->version = 0;
69 header->name = name;
70 header->flags = flags;
71 }
72}
73
74void CreateSerializedMessageObject(uint32_t name,
75 uint32_t flags,
76 size_t payload_size,
77 size_t payload_interface_id_count,
Ken Rockotf7a2fe12017-06-19 21:22:0778 std::vector<ScopedHandle>* handles,
Ken Rockota5a7c952017-06-17 09:10:0779 ScopedMessageHandle* out_handle,
80 internal::Buffer* out_buffer) {
Ken Rockota5a7c952017-06-17 09:10:0781 ScopedMessageHandle handle;
Ken Rockot559b70d2017-07-17 22:35:2482 MojoResult rv = mojo::CreateMessage(&handle);
Ken Rockota5a7c952017-06-17 09:10:0783 DCHECK_EQ(MOJO_RESULT_OK, rv);
84 DCHECK(handle.is_valid());
85
Ken Rockot559b70d2017-07-17 22:35:2486 void* buffer;
87 uint32_t buffer_size;
88 size_t total_size = internal::ComputeSerializedMessageSize(
89 flags, payload_size, payload_interface_id_count);
90 DCHECK(base::IsValueInRangeForNumericType<uint32_t>(total_size));
91 DCHECK(!handles ||
92 base::IsValueInRangeForNumericType<uint32_t>(handles->size()));
93 rv = MojoAttachSerializedMessageBuffer(
94 handle->value(), static_cast<uint32_t>(total_size),
95 handles ? reinterpret_cast<MojoHandle*>(handles->data()) : nullptr,
96 handles ? static_cast<uint32_t>(handles->size()) : 0, &buffer,
97 &buffer_size);
Ken Rockota5a7c952017-06-17 09:10:0798 DCHECK_EQ(MOJO_RESULT_OK, rv);
Ken Rockot559b70d2017-07-17 22:35:2499 if (handles) {
100 // Handle ownership has been taken by MojoAttachSerializedMessageBuffer.
101 for (size_t i = 0; i < handles->size(); ++i)
102 ignore_result(handles->at(i).release());
103 }
104
Ken Rockot7c91af2d2017-07-28 09:54:40105 internal::Buffer payload_buffer(handle.get(), buffer, buffer_size);
Ken Rockota5a7c952017-06-17 09:10:07106
107 // Make sure we zero the memory first!
Ken Rockot559b70d2017-07-17 22:35:24108 memset(payload_buffer.data(), 0, total_size);
109 WriteMessageHeader(name, flags, payload_interface_id_count, &payload_buffer);
Ken Rockota5a7c952017-06-17 09:10:07110
111 *out_handle = std::move(handle);
Ken Rockot559b70d2017-07-17 22:35:24112 *out_buffer = std::move(payload_buffer);
Ken Rockota5a7c952017-06-17 09:10:07113}
114
Ken Rockot559b70d2017-07-17 22:35:24115void SerializeUnserializedContext(MojoMessageHandle message,
116 uintptr_t context_value) {
Ken Rockot474df0142017-07-12 13:28:56117 auto* context =
118 reinterpret_cast<internal::UnserializedMessageContext*>(context_value);
Ken Rockot559b70d2017-07-17 22:35:24119 void* buffer;
120 uint32_t buffer_size;
Ken Rockotfda282af2017-08-10 16:29:12121 MojoResult attach_result = MojoAttachSerializedMessageBuffer(
122 message, 0, nullptr, 0, &buffer, &buffer_size);
123 if (attach_result != MOJO_RESULT_OK)
Ken Rockot559b70d2017-07-17 22:35:24124 return;
125
Ken Rockot7c91af2d2017-07-28 09:54:40126 internal::Buffer payload_buffer(MessageHandle(message), buffer, buffer_size);
Ken Rockot474df0142017-07-12 13:28:56127 WriteMessageHeader(context->message_name(), context->message_flags(),
128 0 /* payload_interface_id_count */, &payload_buffer);
129
130 // We need to copy additional header data which may have been set after
131 // message construction, as this codepath may be reached at some arbitrary
132 // time between message send and message dispatch.
Ken Rockot559b70d2017-07-17 22:35:24133 static_cast<internal::MessageHeader*>(buffer)->interface_id =
Ken Rockot474df0142017-07-12 13:28:56134 context->header()->interface_id;
135 if (context->header()->flags &
136 (Message::kFlagExpectsResponse | Message::kFlagIsResponse)) {
137 DCHECK_GE(context->header()->version, 1u);
Ken Rockot559b70d2017-07-17 22:35:24138 static_cast<internal::MessageHeaderV1*>(buffer)->request_id =
Ken Rockot474df0142017-07-12 13:28:56139 context->header()->request_id;
140 }
Ken Rockot559b70d2017-07-17 22:35:24141
Ken Rockotfda282af2017-08-10 16:29:12142 internal::SerializationContext serialization_context;
143 context->Serialize(&serialization_context, &payload_buffer);
144
145 // TODO(crbug.com/753433): Support lazy serialization of associated endpoint
146 // handles. See corresponding TODO in the bindings generator for proof that
147 // this DCHECK is indeed valid.
148 DCHECK(serialization_context.associated_endpoint_handles()->empty());
149 if (!serialization_context.handles()->empty())
150 payload_buffer.AttachHandles(serialization_context.mutable_handles());
Ken Rockot7c91af2d2017-07-28 09:54:40151 payload_buffer.Seal();
Ken Rockot474df0142017-07-12 13:28:56152}
153
154void DestroyUnserializedContext(uintptr_t context) {
155 delete reinterpret_cast<internal::UnserializedMessageContext*>(context);
156}
157
Ken Rockot474df0142017-07-12 13:28:56158ScopedMessageHandle CreateUnserializedMessageObject(
159 std::unique_ptr<internal::UnserializedMessageContext> context) {
160 ScopedMessageHandle handle;
Ken Rockot559b70d2017-07-17 22:35:24161 MojoResult rv = mojo::CreateMessage(&handle);
Ken Rockot474df0142017-07-12 13:28:56162 DCHECK_EQ(MOJO_RESULT_OK, rv);
163 DCHECK(handle.is_valid());
Ken Rockot559b70d2017-07-17 22:35:24164
165 rv = MojoAttachMessageContext(
166 handle->value(), reinterpret_cast<uintptr_t>(context.release()),
167 &SerializeUnserializedContext, &DestroyUnserializedContext);
168 DCHECK_EQ(MOJO_RESULT_OK, rv);
Ken Rockot474df0142017-07-12 13:28:56169 return handle;
170}
171
rockot160577e92016-08-03 20:24:44172} // namespace
173
Ken Rockota5a7c952017-06-17 09:10:07174Message::Message() = default;
175
Yuzhu Shen91044a732017-08-19 03:41:04176Message::Message(Message&& other)
177 : handle_(std::move(other.handle_)),
178 payload_buffer_(std::move(other.payload_buffer_)),
179 handles_(std::move(other.handles_)),
180 associated_endpoint_handles_(
181 std::move(other.associated_endpoint_handles_)),
182 transferable_(other.transferable_),
183 serialized_(other.serialized_) {
184 other.transferable_ = false;
185 other.serialized_ = false;
186}
Ken Rockota5a7c952017-06-17 09:10:07187
Ken Rockot474df0142017-07-12 13:28:56188Message::Message(std::unique_ptr<internal::UnserializedMessageContext> context)
189 : Message(CreateUnserializedMessageObject(std::move(context))) {}
190
Ken Rockota5a7c952017-06-17 09:10:07191Message::Message(uint32_t name,
192 uint32_t flags,
193 size_t payload_size,
Ken Rockot11be895d2017-06-28 17:21:18194 size_t payload_interface_id_count,
195 std::vector<ScopedHandle>* handles) {
Ken Rockota5a7c952017-06-17 09:10:07196 CreateSerializedMessageObject(name, flags, payload_size,
Ken Rockot11be895d2017-06-28 17:21:18197 payload_interface_id_count, handles, &handle_,
Ken Rockotf7a2fe12017-06-19 21:22:07198 &payload_buffer_);
Ken Rockota5a7c952017-06-17 09:10:07199 transferable_ = true;
Ken Rockot474df0142017-07-12 13:28:56200 serialized_ = true;
rockot85dce0862015-11-13 01:33:59201}
202
Ken Rockota5a7c952017-06-17 09:10:07203Message::Message(ScopedMessageHandle handle) {
204 DCHECK(handle.is_valid());
rockotc4cc691e2016-08-19 18:48:57205
Ken Rockot474df0142017-07-12 13:28:56206 uintptr_t context_value = 0;
207 MojoResult get_context_result = MojoGetMessageContext(
208 handle->value(), &context_value, MOJO_GET_MESSAGE_CONTEXT_FLAG_NONE);
209 if (get_context_result == MOJO_RESULT_NOT_FOUND) {
210 // It's a serialized message. Extract handles if possible.
211 uint32_t num_bytes;
212 void* buffer;
213 uint32_t num_handles = 0;
214 MojoResult rv = MojoGetSerializedMessageContents(
215 handle->value(), &buffer, &num_bytes, nullptr, &num_handles,
Ken Rockota5a7c952017-06-17 09:10:07216 MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE);
Ken Rockot474df0142017-07-12 13:28:56217 if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) {
218 handles_.resize(num_handles);
219 rv = MojoGetSerializedMessageContents(
220 handle->value(), &buffer, &num_bytes,
221 reinterpret_cast<MojoHandle*>(handles_.data()), &num_handles,
222 MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE);
223 } else {
224 // No handles, so it's safe to retransmit this message if the caller
225 // really wants to.
226 transferable_ = true;
227 }
rockot85dce0862015-11-13 01:33:59228
Ken Rockot474df0142017-07-12 13:28:56229 if (rv != MOJO_RESULT_OK) {
230 // Failed to deserialize handles. Leave the Message uninitialized.
231 return;
232 }
233
Ken Rockot7c91af2d2017-07-28 09:54:40234 payload_buffer_ = internal::Buffer(buffer, num_bytes, num_bytes);
Ken Rockot474df0142017-07-12 13:28:56235 serialized_ = true;
236 } else {
237 DCHECK_EQ(MOJO_RESULT_OK, get_context_result);
238 auto* context =
239 reinterpret_cast<internal::UnserializedMessageContext*>(context_value);
240 // Dummy data address so common header accessors still behave properly. The
241 // choice is V1 reflects unserialized message capabilities: we may or may
242 // not need to support request IDs (which require at least V1), but we never
243 // (for now, anyway) need to support associated interface handles (V2).
Ken Rockot7c91af2d2017-07-28 09:54:40244 payload_buffer_ =
245 internal::Buffer(context->header(), sizeof(internal::MessageHeaderV1),
246 sizeof(internal::MessageHeaderV1));
Ken Rockot474df0142017-07-12 13:28:56247 transferable_ = true;
248 serialized_ = false;
Ken Rockota5a7c952017-06-17 09:10:07249 }
250
251 handle_ = std::move(handle);
rockotc4cc691e2016-08-19 18:48:57252}
253
Ken Rockota5a7c952017-06-17 09:10:07254Message::~Message() = default;
255
Yuzhu Shen91044a732017-08-19 03:41:04256Message& Message::operator=(Message&& other) {
257 handle_ = std::move(other.handle_);
258 payload_buffer_ = std::move(other.payload_buffer_);
259 handles_ = std::move(other.handles_);
260 associated_endpoint_handles_ = std::move(other.associated_endpoint_handles_);
261 transferable_ = other.transferable_;
262 other.transferable_ = false;
263 serialized_ = other.serialized_;
264 other.serialized_ = false;
265 return *this;
266}
Ken Rockota5a7c952017-06-17 09:10:07267
rockotc4cc691e2016-08-19 18:48:57268void Message::Reset() {
Ken Rockota5a7c952017-06-17 09:10:07269 handle_.reset();
Ken Rockot7c91af2d2017-07-28 09:54:40270 payload_buffer_.Reset();
rockotc4cc691e2016-08-19 18:48:57271 handles_.clear();
yzshenea784ea2017-01-31 21:20:20272 associated_endpoint_handles_.clear();
Ken Rockota5a7c952017-06-17 09:10:07273 transferable_ = false;
Ken Rockot474df0142017-07-12 13:28:56274 serialized_ = false;
rockot85dce0862015-11-13 01:33:59275}
276
yzshenea784ea2017-01-31 21:20:20277const uint8_t* Message::payload() const {
278 if (version() < 2)
279 return data() + header()->num_bytes;
280
yzshen876a00f92017-04-29 02:11:35281 DCHECK(!header_v2()->payload.is_null());
yzshenea784ea2017-01-31 21:20:20282 return static_cast<const uint8_t*>(header_v2()->payload.Get());
283}
284
285uint32_t Message::payload_num_bytes() const {
286 DCHECK_GE(data_num_bytes(), header()->num_bytes);
287 size_t num_bytes;
288 if (version() < 2) {
289 num_bytes = data_num_bytes() - header()->num_bytes;
290 } else {
yzshen876a00f92017-04-29 02:11:35291 auto payload_begin =
292 reinterpret_cast<uintptr_t>(header_v2()->payload.Get());
293 auto payload_end =
294 reinterpret_cast<uintptr_t>(header_v2()->payload_interface_ids.Get());
295 if (!payload_end)
296 payload_end = reinterpret_cast<uintptr_t>(data() + data_num_bytes());
297 DCHECK_GE(payload_end, payload_begin);
298 num_bytes = payload_end - payload_begin;
yzshenea784ea2017-01-31 21:20:20299 }
Ken Rockot7c91af2d2017-07-28 09:54:40300 DCHECK(base::IsValueInRangeForNumericType<uint32_t>(num_bytes));
yzshenea784ea2017-01-31 21:20:20301 return static_cast<uint32_t>(num_bytes);
302}
303
304uint32_t Message::payload_num_interface_ids() const {
vmpstr6d9996c82017-02-23 00:43:25305 auto* array_pointer =
yzshenea784ea2017-01-31 21:20:20306 version() < 2 ? nullptr : header_v2()->payload_interface_ids.Get();
307 return array_pointer ? static_cast<uint32_t>(array_pointer->size()) : 0;
308}
309
310const uint32_t* Message::payload_interface_ids() const {
vmpstr6d9996c82017-02-23 00:43:25311 auto* array_pointer =
yzshenea784ea2017-01-31 21:20:20312 version() < 2 ? nullptr : header_v2()->payload_interface_ids.Get();
313 return array_pointer ? array_pointer->storage() : nullptr;
314}
315
Ken Rockotfda282af2017-08-10 16:29:12316void Message::AttachHandlesFromSerializationContext(
317 internal::SerializationContext* context) {
318 if (context->handles()->empty() &&
319 context->associated_endpoint_handles()->empty()) {
320 // No handles attached, so no extra serialization work.
321 return;
322 }
323
324 if (context->associated_endpoint_handles()->empty()) {
325 // Attaching only non-associated handles is easier since we don't have to
326 // modify the message header. Faster path for that.
327 payload_buffer_.AttachHandles(context->mutable_handles());
328 return;
329 }
330
331 // Allocate a new message with enough space to hold all attached handles. Copy
332 // this message's contents into the new one and use it to replace ourself.
333 //
334 // TODO(rockot): We could avoid the extra full message allocation by instead
335 // growing the buffer and carefully moving its contents around. This errs on
336 // the side of less complexity with probably only marginal performance cost.
337 uint32_t payload_size = payload_num_bytes();
338 mojo::Message new_message(name(), header()->flags, payload_size,
339 context->associated_endpoint_handles()->size(),
340 context->mutable_handles());
341 std::swap(*context->mutable_associated_endpoint_handles(),
342 new_message.associated_endpoint_handles_);
343 memcpy(new_message.payload_buffer()->AllocateAndGet(payload_size), payload(),
344 payload_size);
345 *this = std::move(new_message);
346}
347
rockot596231c2016-04-29 18:46:45348ScopedMessageHandle Message::TakeMojoMessage() {
yzshenea784ea2017-01-31 21:20:20349 // If there are associated endpoints transferred,
350 // SerializeAssociatedEndpointHandles() must be called before this method.
351 DCHECK(associated_endpoint_handles_.empty());
Ken Rockota5a7c952017-06-17 09:10:07352 DCHECK(transferable_);
Ken Rockot7c91af2d2017-07-28 09:54:40353 payload_buffer_.Seal();
Ken Rockota5a7c952017-06-17 09:10:07354 auto handle = std::move(handle_);
355 Reset();
356 return handle;
rockot596231c2016-04-29 18:46:45357}
358
rockot8a88e80c2016-06-16 02:30:30359void Message::NotifyBadMessage(const std::string& error) {
Ken Rockota5a7c952017-06-17 09:10:07360 DCHECK(handle_.is_valid());
361 mojo::NotifyBadMessage(handle_.get(), error);
rockot8a88e80c2016-06-16 02:30:30362}
363
yzshenea784ea2017-01-31 21:20:20364void Message::SerializeAssociatedEndpointHandles(
365 AssociatedGroupController* group_controller) {
366 if (associated_endpoint_handles_.empty())
367 return;
368
369 DCHECK_GE(version(), 2u);
370 DCHECK(header_v2()->payload_interface_ids.is_null());
Ken Rockota5a7c952017-06-17 09:10:07371 DCHECK(payload_buffer_.is_valid());
Ken Rockot7c91af2d2017-07-28 09:54:40372 DCHECK(handle_.is_valid());
yzshenea784ea2017-01-31 21:20:20373
374 size_t size = associated_endpoint_handles_.size();
Ken Rockot7c91af2d2017-07-28 09:54:40375
376 internal::Array_Data<uint32_t>::BufferWriter handle_writer;
377 handle_writer.Allocate(size, &payload_buffer_);
378 header_v2()->payload_interface_ids.Set(handle_writer.data());
yzshenea784ea2017-01-31 21:20:20379
380 for (size_t i = 0; i < size; ++i) {
381 ScopedInterfaceEndpointHandle& handle = associated_endpoint_handles_[i];
382
yzshen2859a2ac2017-02-14 22:24:25383 DCHECK(handle.pending_association());
Ken Rockot7c91af2d2017-07-28 09:54:40384 handle_writer->storage()[i] =
yzshen2859a2ac2017-02-14 22:24:25385 group_controller->AssociateInterface(std::move(handle));
yzshenea784ea2017-01-31 21:20:20386 }
387 associated_endpoint_handles_.clear();
388}
389
390bool Message::DeserializeAssociatedEndpointHandles(
391 AssociatedGroupController* group_controller) {
Yuzhu Shen91044a732017-08-19 03:41:04392 if (!serialized_)
393 return true;
394
yzshenea784ea2017-01-31 21:20:20395 associated_endpoint_handles_.clear();
396
397 uint32_t num_ids = payload_num_interface_ids();
398 if (num_ids == 0)
399 return true;
400
401 associated_endpoint_handles_.reserve(num_ids);
402 uint32_t* ids = header_v2()->payload_interface_ids.Get()->storage();
403 bool result = true;
404 for (uint32_t i = 0; i < num_ids; ++i) {
405 auto handle = group_controller->CreateLocalEndpointHandle(ids[i]);
406 if (IsValidInterfaceId(ids[i]) && !handle.is_valid()) {
407 // |ids[i]| itself is valid but handle creation failed. In that case, mark
408 // deserialization as failed but continue to deserialize the rest of
409 // handles.
410 result = false;
411 }
412
413 associated_endpoint_handles_.push_back(std::move(handle));
414 ids[i] = kInvalidInterfaceId;
415 }
416 return result;
417}
418
Ken Rockot474df0142017-07-12 13:28:56419void Message::SerializeIfNecessary() {
420 MojoResult rv = MojoSerializeMessage(handle_->value());
421 if (rv == MOJO_RESULT_FAILED_PRECONDITION)
422 return;
423
424 // Reconstruct this Message instance from the serialized message's handle.
425 *this = Message(std::move(handle_));
426}
427
428std::unique_ptr<internal::UnserializedMessageContext>
429Message::TakeUnserializedContext(
430 const internal::UnserializedMessageContext::Tag* tag) {
431 DCHECK(handle_.is_valid());
432 uintptr_t context_value = 0;
433 MojoResult rv = MojoGetMessageContext(handle_->value(), &context_value,
434 MOJO_GET_MESSAGE_CONTEXT_FLAG_NONE);
435 if (rv == MOJO_RESULT_NOT_FOUND)
436 return nullptr;
437 DCHECK_EQ(MOJO_RESULT_OK, rv);
438
439 auto* context =
440 reinterpret_cast<internal::UnserializedMessageContext*>(context_value);
441 if (context->tag() != tag)
442 return nullptr;
443
444 // Detach the context from the message.
445 rv = MojoGetMessageContext(handle_->value(), &context_value,
446 MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE);
447 DCHECK_EQ(MOJO_RESULT_OK, rv);
448 DCHECK_EQ(context_value, reinterpret_cast<uintptr_t>(context));
449 return base::WrapUnique(context);
450}
451
452bool MessageReceiver::PrefersSerializedMessages() {
453 return false;
454}
455
rockot222e7dd2016-08-24 23:37:11456PassThroughFilter::PassThroughFilter() {}
457
458PassThroughFilter::~PassThroughFilter() {}
459
Ken Rockotf7a2fe12017-06-19 21:22:07460bool PassThroughFilter::Accept(Message* message) {
461 return true;
462}
rockot222e7dd2016-08-24 23:37:11463
rockot160577e92016-08-03 20:24:44464SyncMessageResponseContext::SyncMessageResponseContext()
465 : outer_context_(current()) {
466 g_tls_sync_response_context.Get().Set(this);
467}
468
469SyncMessageResponseContext::~SyncMessageResponseContext() {
470 DCHECK_EQ(current(), this);
471 g_tls_sync_response_context.Get().Set(outer_context_);
472}
473
474// static
475SyncMessageResponseContext* SyncMessageResponseContext::current() {
476 return g_tls_sync_response_context.Get().Get();
477}
478
479void SyncMessageResponseContext::ReportBadMessage(const std::string& error) {
480 GetBadMessageCallback().Run(error);
481}
482
483const ReportBadMessageCallback&
484SyncMessageResponseContext::GetBadMessageCallback() {
485 if (bad_message_callback_.is_null()) {
rockotc4cc691e2016-08-19 18:48:57486 bad_message_callback_ =
487 base::Bind(&DoNotifyBadMessage, base::Passed(&response_));
rockot160577e92016-08-03 20:24:44488 }
489 return bad_message_callback_;
490}
491
skyf8701562016-01-11 17:17:04492MojoResult ReadMessage(MessagePipeHandle handle, Message* message) {
Ken Rockota5a7c952017-06-17 09:10:07493 ScopedMessageHandle message_handle;
Ken Rockotfdf158da2017-06-12 20:45:29494 MojoResult rv =
Ken Rockota5a7c952017-06-17 09:10:07495 ReadMessageNew(handle, &message_handle, MOJO_READ_MESSAGE_FLAG_NONE);
Ken Rockotfdf158da2017-06-12 20:45:29496 if (rv != MOJO_RESULT_OK)
497 return rv;
rockot596231c2016-04-29 18:46:45498
Ken Rockota5a7c952017-06-17 09:10:07499 *message = Message(std::move(message_handle));
rockot596231c2016-04-29 18:46:45500 return MOJO_RESULT_OK;
rockot85dce0862015-11-13 01:33:59501}
502
rockot160577e92016-08-03 20:24:44503void ReportBadMessage(const std::string& error) {
504 internal::MessageDispatchContext* context =
505 internal::MessageDispatchContext::current();
506 DCHECK(context);
507 context->GetBadMessageCallback().Run(error);
508}
509
510ReportBadMessageCallback GetBadMessageCallback() {
511 internal::MessageDispatchContext* context =
512 internal::MessageDispatchContext::current();
513 DCHECK(context);
514 return context->GetBadMessageCallback();
515}
516
517namespace internal {
518
yzshenea784ea2017-01-31 21:20:20519MessageHeaderV2::MessageHeaderV2() = default;
520
rockot160577e92016-08-03 20:24:44521MessageDispatchContext::MessageDispatchContext(Message* message)
522 : outer_context_(current()), message_(message) {
523 g_tls_message_dispatch_context.Get().Set(this);
524}
525
526MessageDispatchContext::~MessageDispatchContext() {
527 DCHECK_EQ(current(), this);
528 g_tls_message_dispatch_context.Get().Set(outer_context_);
529}
530
531// static
532MessageDispatchContext* MessageDispatchContext::current() {
533 return g_tls_message_dispatch_context.Get().Get();
534}
535
536const ReportBadMessageCallback&
537MessageDispatchContext::GetBadMessageCallback() {
538 if (bad_message_callback_.is_null()) {
rockotc4cc691e2016-08-19 18:48:57539 bad_message_callback_ =
540 base::Bind(&DoNotifyBadMessage, base::Passed(message_));
rockot160577e92016-08-03 20:24:44541 }
542 return bad_message_callback_;
543}
544
545// static
546void SyncMessageResponseSetup::SetCurrentSyncResponseMessage(Message* message) {
547 SyncMessageResponseContext* context = SyncMessageResponseContext::current();
548 if (context)
rockotc4cc691e2016-08-19 18:48:57549 context->response_ = std::move(*message);
rockot160577e92016-08-03 20:24:44550}
551
552} // namespace internal
553
rockot85dce0862015-11-13 01:33:59554} // namespace mojo