blob: 3d5e8553a658bb84c27dbf04bcdcfb5662c35644 [file] [log] [blame]
[email protected]64860882014-08-04 23:44:171// 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
amistryd4aa70d2016-06-23 07:52:375#include "ipc/ipc_channel_mojo.h"
[email protected]64860882014-08-04 23:44:176
avi246998d82015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
danakj03de39b22016-04-23 04:21:099
dcheng0917ec42015-11-19 07:00:2010#include <memory>
dchenge48600452015-12-28 02:24:5011#include <utility>
dcheng0917ec42015-11-19 07:00:2012
[email protected]64860882014-08-04 23:44:1713#include "base/bind.h"
14#include "base/bind_helpers.h"
jam76bcf0c2015-10-02 21:01:2815#include "base/command_line.h"
[email protected]64860882014-08-04 23:44:1716#include "base/lazy_instance.h"
avi246998d82015-12-22 02:39:0417#include "base/macros.h"
danakj03de39b22016-04-23 04:21:0918#include "base/memory/ptr_util.h"
rockot0e4de5f2016-07-22 21:18:0719#include "base/process/process_handle.h"
gabf08ccc02016-05-11 18:51:1120#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0421#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1722#include "ipc/ipc_listener.h"
morrita7126b7a2014-12-17 19:01:4023#include "ipc/ipc_logging.h"
morrita4b5c28e22015-01-14 21:17:0624#include "ipc/ipc_message_attachment_set.h"
morrita7126b7a2014-12-17 19:01:4025#include "ipc/ipc_message_macros.h"
amistryd4aa70d2016-06-23 07:52:3726#include "ipc/ipc_mojo_bootstrap.h"
27#include "ipc/ipc_mojo_handle_attachment.h"
rockot85dce0862015-11-13 01:33:5928#include "mojo/public/cpp/bindings/binding.h"
amistrycbdbf182016-06-09 04:08:1229#include "mojo/public/cpp/system/platform_handle.h"
[email protected]64860882014-08-04 23:44:1730
amistrye309ea32016-06-06 03:20:4931#if defined(OS_POSIX)
morrita1aa788c2015-01-31 05:45:4232#include "ipc/ipc_platform_file_attachment_posix.h"
33#endif
34
sammc57ed9f982016-03-10 06:28:3535#if defined(OS_MACOSX)
36#include "ipc/mach_port_attachment_mac.h"
37#endif
38
39#if defined(OS_WIN)
40#include "ipc/handle_attachment_win.h"
41#endif
42
[email protected]64860882014-08-04 23:44:1743namespace IPC {
44
45namespace {
46
[email protected]64860882014-08-04 23:44:1747class MojoChannelFactory : public ChannelFactory {
48 public:
rockota34707ca2016-07-20 04:28:3249 MojoChannelFactory(
50 mojo::ScopedMessagePipeHandle handle,
51 Channel::Mode mode,
52 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
53 : handle_(std::move(handle)),
54 mode_(mode),
55 ipc_task_runner_(ipc_task_runner) {}
[email protected]64860882014-08-04 23:44:1756
danakj03de39b22016-04-23 04:21:0957 std::unique_ptr<Channel> BuildChannel(Listener* listener) override {
rockota34707ca2016-07-20 04:28:3258 return ChannelMojo::Create(
59 std::move(handle_), mode_, listener, ipc_task_runner_);
60 }
61
62 scoped_refptr<base::SingleThreadTaskRunner> GetIPCTaskRunner() override {
63 return ipc_task_runner_;
[email protected]64860882014-08-04 23:44:1764 }
65
66 private:
sammc57ed9f982016-03-10 06:28:3567 mojo::ScopedMessagePipeHandle handle_;
sammce4d0abd2016-03-07 22:38:0468 const Channel::Mode mode_;
rockota34707ca2016-07-20 04:28:3269 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
[email protected]64860882014-08-04 23:44:1770
sammce4d0abd2016-03-07 22:38:0471 DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory);
morritaf8f92dcd2014-10-27 20:10:2572};
73
sammc57ed9f982016-03-10 06:28:3574mojom::SerializedHandlePtr CreateSerializedHandle(
75 mojo::ScopedHandle handle,
76 mojom::SerializedHandle::Type type) {
77 mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New();
78 serialized_handle->the_handle = std::move(handle);
79 serialized_handle->type = type;
80 return serialized_handle;
81}
82
amistrycbdbf182016-06-09 04:08:1283MojoResult WrapPlatformHandle(base::PlatformFile handle,
sammc57ed9f982016-03-10 06:28:3584 mojom::SerializedHandle::Type type,
85 mojom::SerializedHandlePtr* serialized) {
amistrycbdbf182016-06-09 04:08:1286 mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformFile(handle);
87 if (!wrapped_handle.is_valid())
88 return MOJO_RESULT_UNKNOWN;
sammc57ed9f982016-03-10 06:28:3589
amistrycbdbf182016-06-09 04:08:1290 *serialized = CreateSerializedHandle(std::move(wrapped_handle), type);
sammc57ed9f982016-03-10 06:28:3591 return MOJO_RESULT_OK;
92}
93
amistrycbdbf182016-06-09 04:08:1294#if defined(OS_MACOSX)
95
96MojoResult WrapMachPort(mach_port_t mach_port,
97 mojom::SerializedHandlePtr* serialized) {
98 MojoPlatformHandle platform_handle = {
99 sizeof(MojoPlatformHandle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
100 static_cast<uint64_t>(mach_port)
101 };
102
103 MojoHandle wrapped_handle;
104 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &wrapped_handle);
105 if (result != MOJO_RESULT_OK)
106 return result;
107
108 *serialized = CreateSerializedHandle(
109 mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)),
110 mojom::SerializedHandle::Type::MACH_PORT);
111 return MOJO_RESULT_OK;
112}
113
114#endif
115
amistrye309ea32016-06-06 03:20:49116#if defined(OS_POSIX)
morrita98ac98f2015-02-25 02:55:04117
118base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
119 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile())
120 : base::ScopedFD(dup(attachment->file()));
121}
122
123#endif
124
sammc57ed9f982016-03-10 06:28:35125MojoResult WrapAttachmentImpl(MessageAttachment* attachment,
126 mojom::SerializedHandlePtr* serialized) {
sammc6ed3efb2016-11-23 03:17:35127 if (attachment->GetType() == MessageAttachment::Type::MOJO_HANDLE) {
sammc57ed9f982016-03-10 06:28:35128 *serialized = CreateSerializedHandle(
129 static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(),
130 mojom::SerializedHandle::Type::MOJO_HANDLE);
131 return MOJO_RESULT_OK;
132 }
amistrye309ea32016-06-06 03:20:49133#if defined(OS_POSIX)
sammc6ed3efb2016-11-23 03:17:35134 if (attachment->GetType() == MessageAttachment::Type::PLATFORM_FILE) {
sammc57ed9f982016-03-10 06:28:35135 // We dup() the handles in IPC::Message to transmit.
136 // IPC::MessageAttachmentSet has intricate lifecycle semantics
137 // of FDs, so just to dup()-and-own them is the safest option.
138 base::ScopedFD file = TakeOrDupFile(
139 static_cast<IPC::internal::PlatformFileAttachment*>(attachment));
140 if (!file.is_valid()) {
141 DPLOG(WARNING) << "Failed to dup FD to transmit.";
142 return MOJO_RESULT_UNKNOWN;
143 }
144
amistrycbdbf182016-06-09 04:08:12145 return WrapPlatformHandle(file.release(),
amistry980a61b2016-06-09 02:51:20146 mojom::SerializedHandle::Type::PLATFORM_FILE,
sammc57ed9f982016-03-10 06:28:35147 serialized);
148 }
149#endif
150#if defined(OS_MACOSX)
sammc6ed3efb2016-11-23 03:17:35151 DCHECK_EQ(attachment->GetType(), MessageAttachment::Type::MACH_PORT);
sammc57ed9f982016-03-10 06:28:35152 internal::MachPortAttachmentMac& mach_port_attachment =
153 static_cast<internal::MachPortAttachmentMac&>(*attachment);
amistrycbdbf182016-06-09 04:08:12154 MojoResult result = WrapMachPort(mach_port_attachment.get_mach_port(),
155 serialized);
sammc57ed9f982016-03-10 06:28:35156 mach_port_attachment.reset_mach_port_ownership();
157 return result;
158#elif defined(OS_WIN)
sammc6ed3efb2016-11-23 03:17:35159 DCHECK_EQ(attachment->GetType(), MessageAttachment::Type::WIN_HANDLE);
sammc57ed9f982016-03-10 06:28:35160 internal::HandleAttachmentWin& handle_attachment =
161 static_cast<internal::HandleAttachmentWin&>(*attachment);
162 MojoResult result = WrapPlatformHandle(
amistrycbdbf182016-06-09 04:08:12163 handle_attachment.get_handle(),
sammc57ed9f982016-03-10 06:28:35164 mojom::SerializedHandle::Type::WIN_HANDLE, serialized);
165 handle_attachment.reset_handle_ownership();
166 return result;
167#else
168 NOTREACHED();
169 return MOJO_RESULT_UNKNOWN;
170#endif // defined(OS_MACOSX)
171}
172
173MojoResult WrapAttachment(MessageAttachment* attachment,
yzshen24b40a32016-08-24 01:10:13174 std::vector<mojom::SerializedHandlePtr>* handles) {
sammc57ed9f982016-03-10 06:28:35175 mojom::SerializedHandlePtr serialized_handle;
176 MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle);
177 if (wrap_result != MOJO_RESULT_OK) {
178 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
179 return wrap_result;
180 }
181 handles->push_back(std::move(serialized_handle));
182 return MOJO_RESULT_OK;
183}
184
185MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle,
186 scoped_refptr<MessageAttachment>* attachment) {
187 if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) {
188 *attachment =
189 new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle));
190 return MOJO_RESULT_OK;
191 }
amistrycbdbf182016-06-09 04:08:12192 MojoPlatformHandle platform_handle = { sizeof(MojoPlatformHandle), 0, 0 };
193 MojoResult unwrap_result = MojoUnwrapPlatformHandle(
sammc57ed9f982016-03-10 06:28:35194 handle->the_handle.release().value(), &platform_handle);
195 if (unwrap_result != MOJO_RESULT_OK)
196 return unwrap_result;
amistry980a61b2016-06-09 02:51:20197#if defined(OS_POSIX)
amistrycbdbf182016-06-09 04:08:12198 if (handle->type == mojom::SerializedHandle::Type::PLATFORM_FILE) {
199 base::PlatformFile file = base::kInvalidPlatformFile;
200 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
201 file = static_cast<base::PlatformFile>(platform_handle.value);
202 *attachment = new internal::PlatformFileAttachment(file);
amistry980a61b2016-06-09 02:51:20203 return MOJO_RESULT_OK;
204 }
205#endif // defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35206#if defined(OS_MACOSX)
amistrycbdbf182016-06-09 04:08:12207 if (handle->type == mojom::SerializedHandle::Type::MACH_PORT) {
208 mach_port_t mach_port = MACH_PORT_NULL;
209 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
210 mach_port = static_cast<mach_port_t>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35211 *attachment = new internal::MachPortAttachmentMac(
amistrycbdbf182016-06-09 04:08:12212 mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35213 return MOJO_RESULT_OK;
214 }
215#endif // defined(OS_MACOSX)
216#if defined(OS_WIN)
217 if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) {
amistrycbdbf182016-06-09 04:08:12218 base::PlatformFile handle = base::kInvalidPlatformFile;
219 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
220 handle = reinterpret_cast<base::PlatformFile>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35221 *attachment = new internal::HandleAttachmentWin(
amistrycbdbf182016-06-09 04:08:12222 handle, internal::HandleAttachmentWin::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35223 return MOJO_RESULT_OK;
224 }
225#endif // defined(OS_WIN)
226 NOTREACHED();
227 return MOJO_RESULT_UNKNOWN;
228}
229
sammcf810f07f2016-11-10 22:34:07230base::ProcessId GetSelfPID() {
231#if defined(OS_LINUX)
232 if (int global_pid = Channel::GetGlobalPid())
233 return global_pid;
234#endif // OS_LINUX
235#if defined(OS_NACL)
236 return -1;
237#else
238 return base::GetCurrentProcId();
239#endif // defined(OS_NACL)
240}
241
rockotdbb3bb6b2015-05-11 22:53:22242} // namespace
[email protected]64860882014-08-04 23:44:17243
244//------------------------------------------------------------------------------
245
[email protected]64860882014-08-04 23:44:17246// static
danakj03de39b22016-04-23 04:21:09247std::unique_ptr<ChannelMojo> ChannelMojo::Create(
sammc57ed9f982016-03-10 06:28:35248 mojo::ScopedMessagePipeHandle handle,
249 Mode mode,
rockota34707ca2016-07-20 04:28:32250 Listener* listener,
251 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
252 return base::WrapUnique(
253 new ChannelMojo(std::move(handle), mode, listener, ipc_task_runner));
[email protected]64860882014-08-04 23:44:17254}
255
256// static
danakj03de39b22016-04-23 04:21:09257std::unique_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
rockota34707ca2016-07-20 04:28:32258 mojo::ScopedMessagePipeHandle handle,
259 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
ricead4fe03702016-09-05 05:06:18260 return base::MakeUnique<MojoChannelFactory>(
261 std::move(handle), Channel::MODE_SERVER, ipc_task_runner);
[email protected]64860882014-08-04 23:44:17262}
263
morrita54f6f80c2014-09-23 21:16:00264// static
danakj03de39b22016-04-23 04:21:09265std::unique_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
rockota34707ca2016-07-20 04:28:32266 mojo::ScopedMessagePipeHandle handle,
267 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
ricead4fe03702016-09-05 05:06:18268 return base::MakeUnique<MojoChannelFactory>(
269 std::move(handle), Channel::MODE_CLIENT, ipc_task_runner);
morrita54f6f80c2014-09-23 21:16:00270}
271
rockota34707ca2016-07-20 04:28:32272ChannelMojo::ChannelMojo(
273 mojo::ScopedMessagePipeHandle handle,
274 Mode mode,
275 Listener* listener,
276 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
rockota628d0b2017-02-09 08:40:15277 : task_runner_(ipc_task_runner),
278 pipe_(handle.get()),
279 listener_(listener),
280 weak_factory_(this) {
281 bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, ipc_task_runner);
282}
283
284void ChannelMojo::ForwardMessageFromThreadSafePtr(mojo::Message message) {
285 DCHECK(task_runner_->RunsTasksOnCurrentThread());
286 if (!message_reader_)
287 return;
288 message_reader_->sender().internal_state()->ForwardMessage(
289 std::move(message));
290}
291
292void ChannelMojo::ForwardMessageWithResponderFromThreadSafePtr(
293 mojo::Message message,
294 std::unique_ptr<mojo::MessageReceiver> responder) {
295 DCHECK(task_runner_->RunsTasksOnCurrentThread());
296 if (!message_reader_)
297 return;
298 message_reader_->sender().internal_state()->ForwardMessageWithResponder(
299 std::move(message), std::move(responder));
[email protected]64860882014-08-04 23:44:17300}
301
302ChannelMojo::~ChannelMojo() {
rockota628d0b2017-02-09 08:40:15303 DCHECK(task_runner_->RunsTasksOnCurrentThread());
[email protected]64860882014-08-04 23:44:17304 Close();
morritae9453ea2014-09-26 03:20:48305}
morrita54f6f80c2014-09-23 21:16:00306
[email protected]64860882014-08-04 23:44:17307bool ChannelMojo::Connect() {
rockota628d0b2017-02-09 08:40:15308 DCHECK(task_runner_->RunsTasksOnCurrentThread());
309
erikchen90971902016-04-25 23:45:31310 WillConnect();
rockot0e4de5f2016-07-22 21:18:07311
rockota628d0b2017-02-09 08:40:15312 mojom::ChannelAssociatedPtr sender;
313 mojom::ChannelAssociatedRequest receiver;
314 bootstrap_->Connect(&sender, &receiver);
rockot0e4de5f2016-07-22 21:18:07315
rockota628d0b2017-02-09 08:40:15316 DCHECK(!message_reader_);
317 sender->SetPeerPid(GetSelfPID());
318 message_reader_.reset(new internal::MessagePipeReader(
319 pipe_, std::move(sender), std::move(receiver), this));
sammce4d0abd2016-03-07 22:38:04320 return true;
[email protected]64860882014-08-04 23:44:17321}
322
rockot10188752016-09-08 18:24:56323void ChannelMojo::Pause() {
324 bootstrap_->Pause();
325}
326
rockot401fb2c2016-09-06 18:35:57327void ChannelMojo::Unpause(bool flush) {
rockot10188752016-09-08 18:24:56328 bootstrap_->Unpause();
rockot401fb2c2016-09-06 18:35:57329 if (flush)
330 Flush();
331}
332
333void ChannelMojo::Flush() {
334 bootstrap_->Flush();
335}
336
[email protected]64860882014-08-04 23:44:17337void ChannelMojo::Close() {
rockot0e4de5f2016-07-22 21:18:07338 // NOTE: The MessagePipeReader's destructor may re-enter this function. Use
339 // caution when changing this method.
340 std::unique_ptr<internal::MessagePipeReader> reader =
341 std::move(message_reader_);
msramek5507fee2016-07-22 10:06:21342 reader.reset();
rockot0e4de5f2016-07-22 21:18:07343
344 base::AutoLock lock(associated_interface_lock_);
345 associated_interfaces_.clear();
sammce4d0abd2016-03-07 22:38:04346}
morritab4472142015-04-20 21:20:12347
rockot506f92fa22016-03-23 01:32:18348void ChannelMojo::OnPipeError() {
rockotc18f64f2016-03-25 04:49:18349 DCHECK(task_runner_);
rockot506f92fa22016-03-23 01:32:18350 if (task_runner_->RunsTasksOnCurrentThread()) {
351 listener_->OnChannelError();
352 } else {
353 task_runner_->PostTask(
354 FROM_HERE,
355 base::Bind(&ChannelMojo::OnPipeError, weak_factory_.GetWeakPtr()));
356 }
[email protected]64860882014-08-04 23:44:17357}
358
rockot0e4de5f2016-07-22 21:18:07359void ChannelMojo::OnAssociatedInterfaceRequest(
360 const std::string& name,
361 mojo::ScopedInterfaceEndpointHandle handle) {
362 GenericAssociatedInterfaceFactory factory;
363 {
364 base::AutoLock locker(associated_interface_lock_);
365 auto iter = associated_interfaces_.find(name);
366 if (iter != associated_interfaces_.end())
367 factory = iter->second;
msramek5507fee2016-07-22 10:06:21368 }
rockot508da2462016-07-22 03:53:59369
rockot0e4de5f2016-07-22 21:18:07370 if (!factory.is_null())
371 factory.Run(std::move(handle));
rockotf62002a2016-09-15 00:08:59372 else
373 listener_->OnAssociatedInterfaceRequest(name, std::move(handle));
rockot0e4de5f2016-07-22 21:18:07374}
375
376bool ChannelMojo::Send(Message* message) {
377 std::unique_ptr<Message> scoped_message = base::WrapUnique(message);
378 if (!message_reader_)
379 return false;
380
amistry1e355dd12016-07-11 21:33:28381 // Comment copied from ipc_channel_posix.cc:
382 // We can't close the pipe here, because calling OnChannelError may destroy
383 // this object, and that would be bad if we are called from Send(). Instead,
384 // we return false and hope the caller will close the pipe. If they do not,
385 // the pipe will still be closed next time OnFileCanReadWithoutBlocking is
386 // called.
387 //
388 // With Mojo, there's no OnFileCanReadWithoutBlocking, but we expect the
389 // pipe's connection error handler will be invoked in its place.
rockot0e4de5f2016-07-22 21:18:07390 return message_reader_->Send(std::move(scoped_message));
rockot506f92fa22016-03-23 01:32:18391}
392
rockot7c6bf952016-07-14 00:34:11393Channel::AssociatedInterfaceSupport*
394ChannelMojo::GetAssociatedInterfaceSupport() { return this; }
395
rockota628d0b2017-02-09 08:40:15396std::unique_ptr<mojo::ThreadSafeForwarder<mojom::Channel>>
397ChannelMojo::CreateThreadSafeChannel() {
398 return base::MakeUnique<mojo::ThreadSafeForwarder<mojom::Channel>>(
399 task_runner_, base::Bind(&ChannelMojo::ForwardMessageFromThreadSafePtr,
400 weak_factory_.GetWeakPtr()),
401 base::Bind(&ChannelMojo::ForwardMessageWithResponderFromThreadSafePtr,
402 weak_factory_.GetWeakPtr()));
403}
404
sammcf810f07f2016-11-10 22:34:07405void ChannelMojo::OnPeerPidReceived(int32_t peer_pid) {
406 listener_->OnChannelConnected(peer_pid);
rockot0e4de5f2016-07-22 21:18:07407}
408
sammce4d0abd2016-03-07 22:38:04409void ChannelMojo::OnMessageReceived(const Message& message) {
morrita7126b7a2014-12-17 19:01:40410 TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
411 "class", IPC_MESSAGE_ID_CLASS(message.type()),
412 "line", IPC_MESSAGE_ID_LINE(message.type()));
[email protected]64860882014-08-04 23:44:17413 listener_->OnMessageReceived(message);
414 if (message.dispatch_error())
415 listener_->OnBadMessageReceived(message);
416}
417
morrita3b41d6c2014-09-11 19:06:29418// static
morrita4b5c28e22015-01-14 21:17:06419MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
morrita96693852014-09-24 20:11:45420 Message* message,
yzshen24b40a32016-08-24 01:10:13421 base::Optional<std::vector<mojom::SerializedHandlePtr>>* handles) {
422 DCHECK(!*handles);
423
424 MojoResult result = MOJO_RESULT_OK;
425 if (!message->HasAttachments())
426 return result;
427
428 std::vector<mojom::SerializedHandlePtr> output_handles;
429 MessageAttachmentSet* set = message->attachment_set();
430
sammc6ed3efb2016-11-23 03:17:35431 for (unsigned i = 0; result == MOJO_RESULT_OK && i < set->size(); ++i) {
432 result = WrapAttachment(set->GetAttachmentAt(i).get(), &output_handles);
morrita3b41d6c2014-09-11 19:06:29433 }
yzshen24b40a32016-08-24 01:10:13434 set->CommitAllDescriptors();
435
436 if (!output_handles.empty())
437 *handles = std::move(output_handles);
438
439 return result;
morrita3b41d6c2014-09-11 19:06:29440}
441
morrita81b17e02015-02-06 00:58:30442// static
443MojoResult ChannelMojo::WriteToMessageAttachmentSet(
yzshen24b40a32016-08-24 01:10:13444 base::Optional<std::vector<mojom::SerializedHandlePtr>> handle_buffer,
morrita81b17e02015-02-06 00:58:30445 Message* message) {
yzshen24b40a32016-08-24 01:10:13446 if (!handle_buffer)
447 return MOJO_RESULT_OK;
448 for (size_t i = 0; i < handle_buffer->size(); ++i) {
sammc57ed9f982016-03-10 06:28:35449 scoped_refptr<MessageAttachment> unwrapped_attachment;
yzshen24b40a32016-08-24 01:10:13450 MojoResult unwrap_result =
451 UnwrapAttachment(std::move((*handle_buffer)[i]), &unwrapped_attachment);
sammc57ed9f982016-03-10 06:28:35452 if (unwrap_result != MOJO_RESULT_OK) {
453 LOG(WARNING) << "Pipe failed to unwrap handles. Closing: "
454 << unwrap_result;
455 return unwrap_result;
456 }
457 DCHECK(unwrapped_attachment);
458
morrita81b17e02015-02-06 00:58:30459 bool ok = message->attachment_set()->AddAttachment(
sammc57ed9f982016-03-10 06:28:35460 std::move(unwrapped_attachment));
morrita81b17e02015-02-06 00:58:30461 DCHECK(ok);
462 if (!ok) {
morritaa3889aa2015-03-16 22:40:51463 LOG(ERROR) << "Failed to add new Mojo handle.";
morrita81b17e02015-02-06 00:58:30464 return MOJO_RESULT_UNKNOWN;
465 }
466 }
morrita81b17e02015-02-06 00:58:30467 return MOJO_RESULT_OK;
468}
[email protected]64860882014-08-04 23:44:17469
rockot7c6bf952016-07-14 00:34:11470mojo::AssociatedGroup* ChannelMojo::GetAssociatedGroup() {
471 DCHECK(bootstrap_);
472 return bootstrap_->GetAssociatedGroup();
473}
474
475void ChannelMojo::AddGenericAssociatedInterface(
476 const std::string& name,
477 const GenericAssociatedInterfaceFactory& factory) {
rockot0e4de5f2016-07-22 21:18:07478 base::AutoLock locker(associated_interface_lock_);
rockot7c6bf952016-07-14 00:34:11479 auto result = associated_interfaces_.insert({ name, factory });
480 DCHECK(result.second);
481}
482
483void ChannelMojo::GetGenericRemoteAssociatedInterface(
484 const std::string& name,
485 mojo::ScopedInterfaceEndpointHandle handle) {
rockot0e4de5f2016-07-22 21:18:07486 if (message_reader_)
487 message_reader_->GetRemoteInterface(name, std::move(handle));
rockot8d890f62016-07-14 16:37:14488}
489
[email protected]64860882014-08-04 23:44:17490} // namespace IPC