blob: 22efa3a335f6a9594eda2dccad69497dc8579b80 [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"
gabf08ccc02016-05-11 18:51:1119#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0420#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1721#include "ipc/ipc_listener.h"
morrita7126b7a2014-12-17 19:01:4022#include "ipc/ipc_logging.h"
morrita4b5c28e22015-01-14 21:17:0623#include "ipc/ipc_message_attachment_set.h"
morrita7126b7a2014-12-17 19:01:4024#include "ipc/ipc_message_macros.h"
amistryd4aa70d2016-06-23 07:52:3725#include "ipc/ipc_mojo_bootstrap.h"
26#include "ipc/ipc_mojo_handle_attachment.h"
rockot85dce0862015-11-13 01:33:5927#include "mojo/public/cpp/bindings/binding.h"
amistrycbdbf182016-06-09 04:08:1228#include "mojo/public/cpp/system/platform_handle.h"
[email protected]64860882014-08-04 23:44:1729
amistrye309ea32016-06-06 03:20:4930#if defined(OS_POSIX)
morrita1aa788c2015-01-31 05:45:4231#include "ipc/ipc_platform_file_attachment_posix.h"
32#endif
33
sammc57ed9f982016-03-10 06:28:3534#if defined(OS_MACOSX)
35#include "ipc/mach_port_attachment_mac.h"
36#endif
37
38#if defined(OS_WIN)
39#include "ipc/handle_attachment_win.h"
40#endif
41
[email protected]64860882014-08-04 23:44:1742namespace IPC {
43
44namespace {
45
[email protected]64860882014-08-04 23:44:1746class MojoChannelFactory : public ChannelFactory {
47 public:
sammc57ed9f982016-03-10 06:28:3548 MojoChannelFactory(mojo::ScopedMessagePipeHandle handle, Channel::Mode mode)
49 : handle_(std::move(handle)), mode_(mode) {}
[email protected]64860882014-08-04 23:44:1750
sammc57ed9f982016-03-10 06:28:3551 std::string GetName() const override { return ""; }
[email protected]64860882014-08-04 23:44:1752
danakj03de39b22016-04-23 04:21:0953 std::unique_ptr<Channel> BuildChannel(Listener* listener) override {
sammc57ed9f982016-03-10 06:28:3554 return ChannelMojo::Create(std::move(handle_), mode_, listener);
[email protected]64860882014-08-04 23:44:1755 }
56
57 private:
sammc57ed9f982016-03-10 06:28:3558 mojo::ScopedMessagePipeHandle handle_;
sammce4d0abd2016-03-07 22:38:0459 const Channel::Mode mode_;
[email protected]64860882014-08-04 23:44:1760
sammce4d0abd2016-03-07 22:38:0461 DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory);
morritaf8f92dcd2014-10-27 20:10:2562};
63
sammc57ed9f982016-03-10 06:28:3564mojom::SerializedHandlePtr CreateSerializedHandle(
65 mojo::ScopedHandle handle,
66 mojom::SerializedHandle::Type type) {
67 mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New();
68 serialized_handle->the_handle = std::move(handle);
69 serialized_handle->type = type;
70 return serialized_handle;
71}
72
amistrycbdbf182016-06-09 04:08:1273MojoResult WrapPlatformHandle(base::PlatformFile handle,
sammc57ed9f982016-03-10 06:28:3574 mojom::SerializedHandle::Type type,
75 mojom::SerializedHandlePtr* serialized) {
amistrycbdbf182016-06-09 04:08:1276 mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformFile(handle);
77 if (!wrapped_handle.is_valid())
78 return MOJO_RESULT_UNKNOWN;
sammc57ed9f982016-03-10 06:28:3579
amistrycbdbf182016-06-09 04:08:1280 *serialized = CreateSerializedHandle(std::move(wrapped_handle), type);
sammc57ed9f982016-03-10 06:28:3581 return MOJO_RESULT_OK;
82}
83
amistrycbdbf182016-06-09 04:08:1284#if defined(OS_MACOSX)
85
86MojoResult WrapMachPort(mach_port_t mach_port,
87 mojom::SerializedHandlePtr* serialized) {
88 MojoPlatformHandle platform_handle = {
89 sizeof(MojoPlatformHandle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
90 static_cast<uint64_t>(mach_port)
91 };
92
93 MojoHandle wrapped_handle;
94 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &wrapped_handle);
95 if (result != MOJO_RESULT_OK)
96 return result;
97
98 *serialized = CreateSerializedHandle(
99 mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)),
100 mojom::SerializedHandle::Type::MACH_PORT);
101 return MOJO_RESULT_OK;
102}
103
104#endif
105
amistrye309ea32016-06-06 03:20:49106#if defined(OS_POSIX)
morrita98ac98f2015-02-25 02:55:04107
108base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
109 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile())
110 : base::ScopedFD(dup(attachment->file()));
111}
112
113#endif
114
sammc57ed9f982016-03-10 06:28:35115MojoResult WrapAttachmentImpl(MessageAttachment* attachment,
116 mojom::SerializedHandlePtr* serialized) {
117 if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) {
118 *serialized = CreateSerializedHandle(
119 static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(),
120 mojom::SerializedHandle::Type::MOJO_HANDLE);
121 return MOJO_RESULT_OK;
122 }
amistrye309ea32016-06-06 03:20:49123#if defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35124 if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) {
125 // We dup() the handles in IPC::Message to transmit.
126 // IPC::MessageAttachmentSet has intricate lifecycle semantics
127 // of FDs, so just to dup()-and-own them is the safest option.
128 base::ScopedFD file = TakeOrDupFile(
129 static_cast<IPC::internal::PlatformFileAttachment*>(attachment));
130 if (!file.is_valid()) {
131 DPLOG(WARNING) << "Failed to dup FD to transmit.";
132 return MOJO_RESULT_UNKNOWN;
133 }
134
amistrycbdbf182016-06-09 04:08:12135 return WrapPlatformHandle(file.release(),
amistry980a61b2016-06-09 02:51:20136 mojom::SerializedHandle::Type::PLATFORM_FILE,
sammc57ed9f982016-03-10 06:28:35137 serialized);
138 }
139#endif
140#if defined(OS_MACOSX)
141 DCHECK_EQ(attachment->GetType(),
142 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
143 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
144 BrokerableAttachment::MACH_PORT);
145 internal::MachPortAttachmentMac& mach_port_attachment =
146 static_cast<internal::MachPortAttachmentMac&>(*attachment);
amistrycbdbf182016-06-09 04:08:12147 MojoResult result = WrapMachPort(mach_port_attachment.get_mach_port(),
148 serialized);
sammc57ed9f982016-03-10 06:28:35149 mach_port_attachment.reset_mach_port_ownership();
150 return result;
151#elif defined(OS_WIN)
152 DCHECK_EQ(attachment->GetType(),
153 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
154 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
155 BrokerableAttachment::WIN_HANDLE);
156 internal::HandleAttachmentWin& handle_attachment =
157 static_cast<internal::HandleAttachmentWin&>(*attachment);
158 MojoResult result = WrapPlatformHandle(
amistrycbdbf182016-06-09 04:08:12159 handle_attachment.get_handle(),
sammc57ed9f982016-03-10 06:28:35160 mojom::SerializedHandle::Type::WIN_HANDLE, serialized);
161 handle_attachment.reset_handle_ownership();
162 return result;
163#else
164 NOTREACHED();
165 return MOJO_RESULT_UNKNOWN;
166#endif // defined(OS_MACOSX)
167}
168
169MojoResult WrapAttachment(MessageAttachment* attachment,
170 mojo::Array<mojom::SerializedHandlePtr>* handles) {
171 mojom::SerializedHandlePtr serialized_handle;
172 MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle);
173 if (wrap_result != MOJO_RESULT_OK) {
174 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
175 return wrap_result;
176 }
177 handles->push_back(std::move(serialized_handle));
178 return MOJO_RESULT_OK;
179}
180
181MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle,
182 scoped_refptr<MessageAttachment>* attachment) {
183 if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) {
184 *attachment =
185 new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle));
186 return MOJO_RESULT_OK;
187 }
amistrycbdbf182016-06-09 04:08:12188 MojoPlatformHandle platform_handle = { sizeof(MojoPlatformHandle), 0, 0 };
189 MojoResult unwrap_result = MojoUnwrapPlatformHandle(
sammc57ed9f982016-03-10 06:28:35190 handle->the_handle.release().value(), &platform_handle);
191 if (unwrap_result != MOJO_RESULT_OK)
192 return unwrap_result;
amistry980a61b2016-06-09 02:51:20193#if defined(OS_POSIX)
amistrycbdbf182016-06-09 04:08:12194 if (handle->type == mojom::SerializedHandle::Type::PLATFORM_FILE) {
195 base::PlatformFile file = base::kInvalidPlatformFile;
196 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
197 file = static_cast<base::PlatformFile>(platform_handle.value);
198 *attachment = new internal::PlatformFileAttachment(file);
amistry980a61b2016-06-09 02:51:20199 return MOJO_RESULT_OK;
200 }
201#endif // defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35202#if defined(OS_MACOSX)
amistrycbdbf182016-06-09 04:08:12203 if (handle->type == mojom::SerializedHandle::Type::MACH_PORT) {
204 mach_port_t mach_port = MACH_PORT_NULL;
205 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
206 mach_port = static_cast<mach_port_t>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35207 *attachment = new internal::MachPortAttachmentMac(
amistrycbdbf182016-06-09 04:08:12208 mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35209 return MOJO_RESULT_OK;
210 }
211#endif // defined(OS_MACOSX)
212#if defined(OS_WIN)
213 if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) {
amistrycbdbf182016-06-09 04:08:12214 base::PlatformFile handle = base::kInvalidPlatformFile;
215 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
216 handle = reinterpret_cast<base::PlatformFile>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35217 *attachment = new internal::HandleAttachmentWin(
amistrycbdbf182016-06-09 04:08:12218 handle, internal::HandleAttachmentWin::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35219 return MOJO_RESULT_OK;
220 }
221#endif // defined(OS_WIN)
222 NOTREACHED();
223 return MOJO_RESULT_UNKNOWN;
224}
225
rockotdbb3bb6b2015-05-11 22:53:22226} // namespace
[email protected]64860882014-08-04 23:44:17227
228//------------------------------------------------------------------------------
229
[email protected]64860882014-08-04 23:44:17230// static
danakj03de39b22016-04-23 04:21:09231std::unique_ptr<ChannelMojo> ChannelMojo::Create(
sammc57ed9f982016-03-10 06:28:35232 mojo::ScopedMessagePipeHandle handle,
233 Mode mode,
234 Listener* listener) {
danakj03de39b22016-04-23 04:21:09235 return base::WrapUnique(new ChannelMojo(std::move(handle), mode, listener));
[email protected]64860882014-08-04 23:44:17236}
237
238// static
danakj03de39b22016-04-23 04:21:09239std::unique_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
sammc57ed9f982016-03-10 06:28:35240 mojo::ScopedMessagePipeHandle handle) {
danakj03de39b22016-04-23 04:21:09241 return base::WrapUnique(
sammc57ed9f982016-03-10 06:28:35242 new MojoChannelFactory(std::move(handle), Channel::MODE_SERVER));
[email protected]64860882014-08-04 23:44:17243}
244
morrita54f6f80c2014-09-23 21:16:00245// static
danakj03de39b22016-04-23 04:21:09246std::unique_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
sammc57ed9f982016-03-10 06:28:35247 mojo::ScopedMessagePipeHandle handle) {
danakj03de39b22016-04-23 04:21:09248 return base::WrapUnique(
sammc57ed9f982016-03-10 06:28:35249 new MojoChannelFactory(std::move(handle), Channel::MODE_CLIENT));
morrita54f6f80c2014-09-23 21:16:00250}
251
sammc57ed9f982016-03-10 06:28:35252ChannelMojo::ChannelMojo(mojo::ScopedMessagePipeHandle handle,
morrita3b41d6c2014-09-11 19:06:29253 Mode mode,
erikchen30dc2812015-09-24 03:26:38254 Listener* listener)
rockotc18f64f2016-03-25 04:49:18255 : pipe_(handle.get()),
rockot506f92fa22016-03-23 01:32:18256 listener_(listener),
257 waiting_connect_(true),
258 weak_factory_(this) {
morrita54f6f80c2014-09-23 21:16:00259 // Create MojoBootstrap after all members are set as it touches
260 // ChannelMojo from a different thread.
sammc57ed9f982016-03-10 06:28:35261 bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, this);
[email protected]64860882014-08-04 23:44:17262}
263
264ChannelMojo::~ChannelMojo() {
265 Close();
morritae9453ea2014-09-26 03:20:48266}
morrita54f6f80c2014-09-23 21:16:00267
[email protected]64860882014-08-04 23:44:17268bool ChannelMojo::Connect() {
erikchen90971902016-04-25 23:45:31269 WillConnect();
rockot68974392016-05-02 00:02:05270 {
271 base::AutoLock lock(lock_);
272 DCHECK(!task_runner_);
273 task_runner_ = base::ThreadTaskRunnerHandle::Get();
274 DCHECK(!message_reader_);
275 }
sammce4d0abd2016-03-07 22:38:04276 bootstrap_->Connect();
277 return true;
[email protected]64860882014-08-04 23:44:17278}
279
280void ChannelMojo::Close() {
danakj03de39b22016-04-23 04:21:09281 std::unique_ptr<internal::MessagePipeReader, ReaderDeleter> reader;
rockot506f92fa22016-03-23 01:32:18282 {
283 base::AutoLock lock(lock_);
284 if (!message_reader_)
285 return;
286 // The reader's destructor may re-enter Close, so we swap it out first to
287 // avoid deadlock when freeing it below.
288 std::swap(message_reader_, reader);
289
290 // We might Close() before we Connect().
291 waiting_connect_ = false;
292 }
293
294 reader.reset();
sammce4d0abd2016-03-07 22:38:04295}
morritab4472142015-04-20 21:20:12296
sammce4d0abd2016-03-07 22:38:04297// MojoBootstrap::Delegate implementation
298void ChannelMojo::OnPipesAvailable(
299 mojom::ChannelAssociatedPtrInfo send_channel,
300 mojom::ChannelAssociatedRequest receive_channel,
301 int32_t peer_pid) {
sammc57ed9f982016-03-10 06:28:35302 InitMessageReader(std::move(send_channel), std::move(receive_channel),
303 peer_pid);
[email protected]64860882014-08-04 23:44:17304}
305
morrita54f6f80c2014-09-23 21:16:00306void ChannelMojo::OnBootstrapError() {
307 listener_->OnChannelError();
308}
309
sammce4d0abd2016-03-07 22:38:04310void ChannelMojo::InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
sammc57ed9f982016-03-10 06:28:35311 mojom::ChannelAssociatedRequest receiver,
312 base::ProcessId peer_pid) {
313 mojom::ChannelAssociatedPtr sender_ptr;
314 sender_ptr.Bind(std::move(sender));
danakj03de39b22016-04-23 04:21:09315 std::unique_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>
316 reader(new internal::MessagePipeReader(
317 pipe_, std::move(sender_ptr), std::move(receiver), peer_pid, this));
morritab4472142015-04-20 21:20:12318
rockot506f92fa22016-03-23 01:32:18319 bool connected = true;
320 {
321 base::AutoLock lock(lock_);
322 for (size_t i = 0; i < pending_messages_.size(); ++i) {
323 if (!reader->Send(std::move(pending_messages_[i]))) {
324 LOG(ERROR) << "Failed to flush pending messages";
325 pending_messages_.clear();
326 connected = false;
327 break;
328 }
329 }
330
331 if (connected) {
332 // We set |message_reader_| here and won't get any |pending_messages_|
333 // hereafter. Although we might have some if there is an error, we don't
334 // care. They cannot be sent anyway.
335 message_reader_ = std::move(reader);
sammce4d0abd2016-03-07 22:38:04336 pending_messages_.clear();
rockot506f92fa22016-03-23 01:32:18337 waiting_connect_ = false;
morrita0a24cfc92014-09-16 03:20:48338 }
morritab4472142015-04-20 21:20:12339 }
[email protected]64860882014-08-04 23:44:17340
rockot506f92fa22016-03-23 01:32:18341 if (connected)
342 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID()));
343 else
344 OnPipeError();
[email protected]64860882014-08-04 23:44:17345}
346
rockot506f92fa22016-03-23 01:32:18347void ChannelMojo::OnPipeError() {
rockotc18f64f2016-03-25 04:49:18348 DCHECK(task_runner_);
rockot506f92fa22016-03-23 01:32:18349 if (task_runner_->RunsTasksOnCurrentThread()) {
350 listener_->OnChannelError();
351 } else {
352 task_runner_->PostTask(
353 FROM_HERE,
354 base::Bind(&ChannelMojo::OnPipeError, weak_factory_.GetWeakPtr()));
355 }
[email protected]64860882014-08-04 23:44:17356}
357
[email protected]64860882014-08-04 23:44:17358bool ChannelMojo::Send(Message* message) {
amistry1e355dd12016-07-11 21:33:28359 base::AutoLock lock(lock_);
360 if (!message_reader_) {
361 pending_messages_.push_back(base::WrapUnique(message));
362 // Counts as OK before the connection is established, but it's an
363 // error otherwise.
364 return waiting_connect_;
[email protected]64860882014-08-04 23:44:17365 }
366
amistry1e355dd12016-07-11 21:33:28367 // Comment copied from ipc_channel_posix.cc:
368 // We can't close the pipe here, because calling OnChannelError may destroy
369 // this object, and that would be bad if we are called from Send(). Instead,
370 // we return false and hope the caller will close the pipe. If they do not,
371 // the pipe will still be closed next time OnFileCanReadWithoutBlocking is
372 // called.
373 //
374 // With Mojo, there's no OnFileCanReadWithoutBlocking, but we expect the
375 // pipe's connection error handler will be invoked in its place.
376 return message_reader_->Send(base::WrapUnique(message));
rockot506f92fa22016-03-23 01:32:18377}
378
379bool ChannelMojo::IsSendThreadSafe() const {
rockotf14a8ae2016-06-16 19:28:41380 return false;
[email protected]64860882014-08-04 23:44:17381}
382
383base::ProcessId ChannelMojo::GetPeerPID() const {
rockot506f92fa22016-03-23 01:32:18384 base::AutoLock lock(lock_);
sammc57ed9f982016-03-10 06:28:35385 if (!message_reader_)
386 return base::kNullProcessId;
387
388 return message_reader_->GetPeerPid();
[email protected]64860882014-08-04 23:44:17389}
390
391base::ProcessId ChannelMojo::GetSelfPID() const {
morrita0bd20bd2015-02-25 20:11:27392 return bootstrap_->GetSelfPID();
[email protected]64860882014-08-04 23:44:17393}
394
sammce4d0abd2016-03-07 22:38:04395void ChannelMojo::OnMessageReceived(const Message& message) {
morrita7126b7a2014-12-17 19:01:40396 TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
397 "class", IPC_MESSAGE_ID_CLASS(message.type()),
398 "line", IPC_MESSAGE_ID_LINE(message.type()));
sammc57ed9f982016-03-10 06:28:35399 if (AttachmentBroker* broker = AttachmentBroker::GetGlobal()) {
400 if (broker->OnMessageReceived(message))
401 return;
402 }
[email protected]64860882014-08-04 23:44:17403 listener_->OnMessageReceived(message);
404 if (message.dispatch_error())
405 listener_->OnBadMessageReceived(message);
406}
407
amistrye309ea32016-06-06 03:20:49408#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
[email protected]64860882014-08-04 23:44:17409int ChannelMojo::GetClientFileDescriptor() const {
sammce4d0abd2016-03-07 22:38:04410 return -1;
[email protected]64860882014-08-04 23:44:17411}
412
morritaa409ccc2014-10-20 23:53:25413base::ScopedFD ChannelMojo::TakeClientFileDescriptor() {
sammce4d0abd2016-03-07 22:38:04414 return base::ScopedFD(GetClientFileDescriptor());
[email protected]64860882014-08-04 23:44:17415}
amistrye309ea32016-06-06 03:20:49416#endif // defined(OS_POSIX) && !defined(OS_NACL_SFI)
morrita3b41d6c2014-09-11 19:06:29417
418// static
morrita4b5c28e22015-01-14 21:17:06419MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
morrita96693852014-09-24 20:11:45420 Message* message,
sammc57ed9f982016-03-10 06:28:35421 mojo::Array<mojom::SerializedHandlePtr>* handles) {
morrita1aa788c2015-01-31 05:45:42422 if (message->HasAttachments()) {
morrita81b17e02015-02-06 00:58:30423 MessageAttachmentSet* set = message->attachment_set();
erikchenae6d3212015-10-10 02:43:49424 for (unsigned i = 0; i < set->num_non_brokerable_attachments(); ++i) {
sammc57ed9f982016-03-10 06:28:35425 MojoResult result = WrapAttachment(
426 set->GetNonBrokerableAttachmentAt(i).get(), handles);
427 if (result != MOJO_RESULT_OK) {
428 set->CommitAllDescriptors();
429 return result;
morrita81b17e02015-02-06 00:58:30430 }
morrita3b41d6c2014-09-11 19:06:29431 }
sammc57ed9f982016-03-10 06:28:35432 for (unsigned i = 0; i < set->num_brokerable_attachments(); ++i) {
433 MojoResult result =
434 WrapAttachment(set->GetBrokerableAttachmentAt(i).get(), handles);
435 if (result != MOJO_RESULT_OK) {
436 set->CommitAllDescriptors();
437 return result;
438 }
439 }
erikchenae6d3212015-10-10 02:43:49440 set->CommitAllDescriptors();
morrita3b41d6c2014-09-11 19:06:29441 }
morrita3b41d6c2014-09-11 19:06:29442 return MOJO_RESULT_OK;
443}
444
morrita81b17e02015-02-06 00:58:30445// static
446MojoResult ChannelMojo::WriteToMessageAttachmentSet(
sammc57ed9f982016-03-10 06:28:35447 mojo::Array<mojom::SerializedHandlePtr> handle_buffer,
morrita81b17e02015-02-06 00:58:30448 Message* message) {
449 for (size_t i = 0; i < handle_buffer.size(); ++i) {
sammc57ed9f982016-03-10 06:28:35450 scoped_refptr<MessageAttachment> unwrapped_attachment;
451 MojoResult unwrap_result = UnwrapAttachment(std::move(handle_buffer[i]),
452 &unwrapped_attachment);
453 if (unwrap_result != MOJO_RESULT_OK) {
454 LOG(WARNING) << "Pipe failed to unwrap handles. Closing: "
455 << unwrap_result;
456 return unwrap_result;
457 }
458 DCHECK(unwrapped_attachment);
459
morrita81b17e02015-02-06 00:58:30460 bool ok = message->attachment_set()->AddAttachment(
sammc57ed9f982016-03-10 06:28:35461 std::move(unwrapped_attachment));
morrita81b17e02015-02-06 00:58:30462 DCHECK(ok);
463 if (!ok) {
morritaa3889aa2015-03-16 22:40:51464 LOG(ERROR) << "Failed to add new Mojo handle.";
morrita81b17e02015-02-06 00:58:30465 return MOJO_RESULT_UNKNOWN;
466 }
467 }
morrita81b17e02015-02-06 00:58:30468 return MOJO_RESULT_OK;
469}
[email protected]64860882014-08-04 23:44:17470
471} // namespace IPC