blob: 9ce2e661bd145a204ca7f62dfa7e68b494c029ed [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
sammc57ed9f982016-03-10 06:28:3557 std::string GetName() const override { return ""; }
[email protected]64860882014-08-04 23:44:1758
danakj03de39b22016-04-23 04:21:0959 std::unique_ptr<Channel> BuildChannel(Listener* listener) override {
rockota34707ca2016-07-20 04:28:3260 return ChannelMojo::Create(
61 std::move(handle_), mode_, listener, ipc_task_runner_);
62 }
63
64 scoped_refptr<base::SingleThreadTaskRunner> GetIPCTaskRunner() override {
65 return ipc_task_runner_;
[email protected]64860882014-08-04 23:44:1766 }
67
68 private:
sammc57ed9f982016-03-10 06:28:3569 mojo::ScopedMessagePipeHandle handle_;
sammce4d0abd2016-03-07 22:38:0470 const Channel::Mode mode_;
rockota34707ca2016-07-20 04:28:3271 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
[email protected]64860882014-08-04 23:44:1772
sammce4d0abd2016-03-07 22:38:0473 DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory);
morritaf8f92dcd2014-10-27 20:10:2574};
75
sammc57ed9f982016-03-10 06:28:3576mojom::SerializedHandlePtr CreateSerializedHandle(
77 mojo::ScopedHandle handle,
78 mojom::SerializedHandle::Type type) {
79 mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New();
80 serialized_handle->the_handle = std::move(handle);
81 serialized_handle->type = type;
82 return serialized_handle;
83}
84
amistrycbdbf182016-06-09 04:08:1285MojoResult WrapPlatformHandle(base::PlatformFile handle,
sammc57ed9f982016-03-10 06:28:3586 mojom::SerializedHandle::Type type,
87 mojom::SerializedHandlePtr* serialized) {
amistrycbdbf182016-06-09 04:08:1288 mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformFile(handle);
89 if (!wrapped_handle.is_valid())
90 return MOJO_RESULT_UNKNOWN;
sammc57ed9f982016-03-10 06:28:3591
amistrycbdbf182016-06-09 04:08:1292 *serialized = CreateSerializedHandle(std::move(wrapped_handle), type);
sammc57ed9f982016-03-10 06:28:3593 return MOJO_RESULT_OK;
94}
95
amistrycbdbf182016-06-09 04:08:1296#if defined(OS_MACOSX)
97
98MojoResult WrapMachPort(mach_port_t mach_port,
99 mojom::SerializedHandlePtr* serialized) {
100 MojoPlatformHandle platform_handle = {
101 sizeof(MojoPlatformHandle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
102 static_cast<uint64_t>(mach_port)
103 };
104
105 MojoHandle wrapped_handle;
106 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &wrapped_handle);
107 if (result != MOJO_RESULT_OK)
108 return result;
109
110 *serialized = CreateSerializedHandle(
111 mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)),
112 mojom::SerializedHandle::Type::MACH_PORT);
113 return MOJO_RESULT_OK;
114}
115
116#endif
117
amistrye309ea32016-06-06 03:20:49118#if defined(OS_POSIX)
morrita98ac98f2015-02-25 02:55:04119
120base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
121 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile())
122 : base::ScopedFD(dup(attachment->file()));
123}
124
125#endif
126
sammc57ed9f982016-03-10 06:28:35127MojoResult WrapAttachmentImpl(MessageAttachment* attachment,
128 mojom::SerializedHandlePtr* serialized) {
129 if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) {
130 *serialized = CreateSerializedHandle(
131 static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(),
132 mojom::SerializedHandle::Type::MOJO_HANDLE);
133 return MOJO_RESULT_OK;
134 }
amistrye309ea32016-06-06 03:20:49135#if defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35136 if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) {
137 // We dup() the handles in IPC::Message to transmit.
138 // IPC::MessageAttachmentSet has intricate lifecycle semantics
139 // of FDs, so just to dup()-and-own them is the safest option.
140 base::ScopedFD file = TakeOrDupFile(
141 static_cast<IPC::internal::PlatformFileAttachment*>(attachment));
142 if (!file.is_valid()) {
143 DPLOG(WARNING) << "Failed to dup FD to transmit.";
144 return MOJO_RESULT_UNKNOWN;
145 }
146
amistrycbdbf182016-06-09 04:08:12147 return WrapPlatformHandle(file.release(),
amistry980a61b2016-06-09 02:51:20148 mojom::SerializedHandle::Type::PLATFORM_FILE,
sammc57ed9f982016-03-10 06:28:35149 serialized);
150 }
151#endif
152#if defined(OS_MACOSX)
153 DCHECK_EQ(attachment->GetType(),
154 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
155 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
156 BrokerableAttachment::MACH_PORT);
157 internal::MachPortAttachmentMac& mach_port_attachment =
158 static_cast<internal::MachPortAttachmentMac&>(*attachment);
amistrycbdbf182016-06-09 04:08:12159 MojoResult result = WrapMachPort(mach_port_attachment.get_mach_port(),
160 serialized);
sammc57ed9f982016-03-10 06:28:35161 mach_port_attachment.reset_mach_port_ownership();
162 return result;
163#elif defined(OS_WIN)
164 DCHECK_EQ(attachment->GetType(),
165 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
166 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
167 BrokerableAttachment::WIN_HANDLE);
168 internal::HandleAttachmentWin& handle_attachment =
169 static_cast<internal::HandleAttachmentWin&>(*attachment);
170 MojoResult result = WrapPlatformHandle(
amistrycbdbf182016-06-09 04:08:12171 handle_attachment.get_handle(),
sammc57ed9f982016-03-10 06:28:35172 mojom::SerializedHandle::Type::WIN_HANDLE, serialized);
173 handle_attachment.reset_handle_ownership();
174 return result;
175#else
176 NOTREACHED();
177 return MOJO_RESULT_UNKNOWN;
178#endif // defined(OS_MACOSX)
179}
180
181MojoResult WrapAttachment(MessageAttachment* attachment,
benwells247f0e9a2016-08-01 05:36:47182 mojo::Array<mojom::SerializedHandlePtr>* handles) {
sammc57ed9f982016-03-10 06:28:35183 mojom::SerializedHandlePtr serialized_handle;
184 MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle);
185 if (wrap_result != MOJO_RESULT_OK) {
186 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
187 return wrap_result;
188 }
189 handles->push_back(std::move(serialized_handle));
190 return MOJO_RESULT_OK;
191}
192
193MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle,
194 scoped_refptr<MessageAttachment>* attachment) {
195 if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) {
196 *attachment =
197 new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle));
198 return MOJO_RESULT_OK;
199 }
amistrycbdbf182016-06-09 04:08:12200 MojoPlatformHandle platform_handle = { sizeof(MojoPlatformHandle), 0, 0 };
201 MojoResult unwrap_result = MojoUnwrapPlatformHandle(
sammc57ed9f982016-03-10 06:28:35202 handle->the_handle.release().value(), &platform_handle);
203 if (unwrap_result != MOJO_RESULT_OK)
204 return unwrap_result;
amistry980a61b2016-06-09 02:51:20205#if defined(OS_POSIX)
amistrycbdbf182016-06-09 04:08:12206 if (handle->type == mojom::SerializedHandle::Type::PLATFORM_FILE) {
207 base::PlatformFile file = base::kInvalidPlatformFile;
208 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
209 file = static_cast<base::PlatformFile>(platform_handle.value);
210 *attachment = new internal::PlatformFileAttachment(file);
amistry980a61b2016-06-09 02:51:20211 return MOJO_RESULT_OK;
212 }
213#endif // defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35214#if defined(OS_MACOSX)
amistrycbdbf182016-06-09 04:08:12215 if (handle->type == mojom::SerializedHandle::Type::MACH_PORT) {
216 mach_port_t mach_port = MACH_PORT_NULL;
217 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
218 mach_port = static_cast<mach_port_t>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35219 *attachment = new internal::MachPortAttachmentMac(
amistrycbdbf182016-06-09 04:08:12220 mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35221 return MOJO_RESULT_OK;
222 }
223#endif // defined(OS_MACOSX)
224#if defined(OS_WIN)
225 if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) {
amistrycbdbf182016-06-09 04:08:12226 base::PlatformFile handle = base::kInvalidPlatformFile;
227 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
228 handle = reinterpret_cast<base::PlatformFile>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35229 *attachment = new internal::HandleAttachmentWin(
amistrycbdbf182016-06-09 04:08:12230 handle, internal::HandleAttachmentWin::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35231 return MOJO_RESULT_OK;
232 }
233#endif // defined(OS_WIN)
234 NOTREACHED();
235 return MOJO_RESULT_UNKNOWN;
236}
237
rockotdbb3bb6b2015-05-11 22:53:22238} // namespace
[email protected]64860882014-08-04 23:44:17239
240//------------------------------------------------------------------------------
241
[email protected]64860882014-08-04 23:44:17242// static
danakj03de39b22016-04-23 04:21:09243std::unique_ptr<ChannelMojo> ChannelMojo::Create(
sammc57ed9f982016-03-10 06:28:35244 mojo::ScopedMessagePipeHandle handle,
245 Mode mode,
rockota34707ca2016-07-20 04:28:32246 Listener* listener,
247 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
248 return base::WrapUnique(
249 new ChannelMojo(std::move(handle), mode, listener, ipc_task_runner));
[email protected]64860882014-08-04 23:44:17250}
251
252// static
danakj03de39b22016-04-23 04:21:09253std::unique_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
rockota34707ca2016-07-20 04:28:32254 mojo::ScopedMessagePipeHandle handle,
255 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
256 return base::WrapUnique(new MojoChannelFactory(
257 std::move(handle), Channel::MODE_SERVER, ipc_task_runner));
[email protected]64860882014-08-04 23:44:17258}
259
morrita54f6f80c2014-09-23 21:16:00260// static
danakj03de39b22016-04-23 04:21:09261std::unique_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
rockota34707ca2016-07-20 04:28:32262 mojo::ScopedMessagePipeHandle handle,
263 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
264 return base::WrapUnique(new MojoChannelFactory(
265 std::move(handle), Channel::MODE_CLIENT, ipc_task_runner));
morrita54f6f80c2014-09-23 21:16:00266}
267
rockota34707ca2016-07-20 04:28:32268ChannelMojo::ChannelMojo(
269 mojo::ScopedMessagePipeHandle handle,
270 Mode mode,
271 Listener* listener,
272 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
rockot0e4de5f2016-07-22 21:18:07273 : pipe_(handle.get()), listener_(listener), weak_factory_(this) {
morrita54f6f80c2014-09-23 21:16:00274 // Create MojoBootstrap after all members are set as it touches
275 // ChannelMojo from a different thread.
rockot0e4de5f2016-07-22 21:18:07276 bootstrap_ =
277 MojoBootstrap::Create(std::move(handle), mode, this, ipc_task_runner);
[email protected]64860882014-08-04 23:44:17278}
279
280ChannelMojo::~ChannelMojo() {
281 Close();
morritae9453ea62014-09-26 03:20:48282}
morrita54f6f80c2014-09-23 21:16:00283
[email protected]64860882014-08-04 23:44:17284bool ChannelMojo::Connect() {
erikchen90971902016-04-25 23:45:31285 WillConnect();
rockot0e4de5f2016-07-22 21:18:07286
287 DCHECK(!task_runner_);
288 task_runner_ = base::ThreadTaskRunnerHandle::Get();
289 DCHECK(!message_reader_);
290
sammce4d0abd2016-03-07 22:38:04291 bootstrap_->Connect();
292 return true;
[email protected]64860882014-08-04 23:44:17293}
294
295void ChannelMojo::Close() {
rockot0e4de5f2016-07-22 21:18:07296 // NOTE: The MessagePipeReader's destructor may re-enter this function. Use
297 // caution when changing this method.
298 std::unique_ptr<internal::MessagePipeReader> reader =
299 std::move(message_reader_);
msramek5507fee2016-07-22 10:06:21300 reader.reset();
rockot0e4de5f2016-07-22 21:18:07301
302 base::AutoLock lock(associated_interface_lock_);
303 associated_interfaces_.clear();
sammce4d0abd2016-03-07 22:38:04304}
morritab4472142015-04-20 21:20:12305
sammce4d0abd2016-03-07 22:38:04306// MojoBootstrap::Delegate implementation
rockot0e4de5f2016-07-22 21:18:07307void ChannelMojo::OnPipesAvailable(mojom::ChannelAssociatedPtr sender,
308 mojom::ChannelAssociatedRequest receiver) {
309 sender->SetPeerPid(GetSelfPID());
310 message_reader_.reset(new internal::MessagePipeReader(
311 pipe_, std::move(sender), std::move(receiver), this));
[email protected]64860882014-08-04 23:44:17312}
313
rockot506f92fa22016-03-23 01:32:18314void ChannelMojo::OnPipeError() {
rockotc18f64f2016-03-25 04:49:18315 DCHECK(task_runner_);
rockot506f92fa22016-03-23 01:32:18316 if (task_runner_->RunsTasksOnCurrentThread()) {
317 listener_->OnChannelError();
318 } else {
319 task_runner_->PostTask(
320 FROM_HERE,
321 base::Bind(&ChannelMojo::OnPipeError, weak_factory_.GetWeakPtr()));
322 }
[email protected]64860882014-08-04 23:44:17323}
324
rockot0e4de5f2016-07-22 21:18:07325void ChannelMojo::OnAssociatedInterfaceRequest(
326 const std::string& name,
327 mojo::ScopedInterfaceEndpointHandle handle) {
328 GenericAssociatedInterfaceFactory factory;
329 {
330 base::AutoLock locker(associated_interface_lock_);
331 auto iter = associated_interfaces_.find(name);
332 if (iter != associated_interfaces_.end())
333 factory = iter->second;
msramek5507fee2016-07-22 10:06:21334 }
rockot508da2462016-07-22 03:53:59335
rockot0e4de5f2016-07-22 21:18:07336 if (!factory.is_null())
337 factory.Run(std::move(handle));
338}
339
340bool ChannelMojo::Send(Message* message) {
341 std::unique_ptr<Message> scoped_message = base::WrapUnique(message);
342 if (!message_reader_)
343 return false;
344
amistry1e355dd12016-07-11 21:33:28345 // Comment copied from ipc_channel_posix.cc:
346 // We can't close the pipe here, because calling OnChannelError may destroy
347 // this object, and that would be bad if we are called from Send(). Instead,
348 // we return false and hope the caller will close the pipe. If they do not,
349 // the pipe will still be closed next time OnFileCanReadWithoutBlocking is
350 // called.
351 //
352 // With Mojo, there's no OnFileCanReadWithoutBlocking, but we expect the
353 // pipe's connection error handler will be invoked in its place.
rockot0e4de5f2016-07-22 21:18:07354 return message_reader_->Send(std::move(scoped_message));
rockot506f92fa22016-03-23 01:32:18355}
356
357bool ChannelMojo::IsSendThreadSafe() const {
rockotf14a8ae2016-06-16 19:28:41358 return false;
[email protected]64860882014-08-04 23:44:17359}
360
361base::ProcessId ChannelMojo::GetPeerPID() const {
sammc57ed9f982016-03-10 06:28:35362 if (!message_reader_)
363 return base::kNullProcessId;
sammc57ed9f982016-03-10 06:28:35364 return message_reader_->GetPeerPid();
[email protected]64860882014-08-04 23:44:17365}
366
367base::ProcessId ChannelMojo::GetSelfPID() const {
rockot0e4de5f2016-07-22 21:18:07368#if defined(OS_LINUX)
369 if (int global_pid = GetGlobalPid())
370 return global_pid;
371#endif // OS_LINUX
372#if defined(OS_NACL)
373 return -1;
374#else
375 return base::GetCurrentProcId();
376#endif // defined(OS_NACL)
[email protected]64860882014-08-04 23:44:17377}
378
rockot7c6bf952016-07-14 00:34:11379Channel::AssociatedInterfaceSupport*
380ChannelMojo::GetAssociatedInterfaceSupport() { return this; }
381
rockot0e4de5f2016-07-22 21:18:07382void ChannelMojo::OnPeerPidReceived() {
383 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID()));
384}
385
sammce4d0abd2016-03-07 22:38:04386void ChannelMojo::OnMessageReceived(const Message& message) {
morrita7126b7a2014-12-17 19:01:40387 TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
388 "class", IPC_MESSAGE_ID_CLASS(message.type()),
389 "line", IPC_MESSAGE_ID_LINE(message.type()));
sammc57ed9f982016-03-10 06:28:35390 if (AttachmentBroker* broker = AttachmentBroker::GetGlobal()) {
391 if (broker->OnMessageReceived(message))
392 return;
393 }
[email protected]64860882014-08-04 23:44:17394 listener_->OnMessageReceived(message);
395 if (message.dispatch_error())
396 listener_->OnBadMessageReceived(message);
397}
398
amistrye309ea32016-06-06 03:20:49399#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
[email protected]64860882014-08-04 23:44:17400int ChannelMojo::GetClientFileDescriptor() const {
sammce4d0abd2016-03-07 22:38:04401 return -1;
[email protected]64860882014-08-04 23:44:17402}
403
morritaa409ccc2014-10-20 23:53:25404base::ScopedFD ChannelMojo::TakeClientFileDescriptor() {
sammce4d0abd2016-03-07 22:38:04405 return base::ScopedFD(GetClientFileDescriptor());
[email protected]64860882014-08-04 23:44:17406}
amistrye309ea32016-06-06 03:20:49407#endif // defined(OS_POSIX) && !defined(OS_NACL_SFI)
morrita3b41d6c2014-09-11 19:06:29408
409// static
morrita4b5c28e22015-01-14 21:17:06410MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
morrita96693852014-09-24 20:11:45411 Message* message,
benwells247f0e9a2016-08-01 05:36:47412 mojo::Array<mojom::SerializedHandlePtr>* handles) {
413 if (message->HasAttachments()) {
414 MessageAttachmentSet* set = message->attachment_set();
415 for (unsigned i = 0; i < set->num_non_brokerable_attachments(); ++i) {
416 MojoResult result = WrapAttachment(
417 set->GetNonBrokerableAttachmentAt(i).get(), handles);
418 if (result != MOJO_RESULT_OK) {
419 set->CommitAllDescriptors();
420 return result;
421 }
422 }
423 for (unsigned i = 0; i < set->num_brokerable_attachments(); ++i) {
424 MojoResult result =
425 WrapAttachment(set->GetBrokerableAttachmentAt(i).get(), handles);
426 if (result != MOJO_RESULT_OK) {
427 set->CommitAllDescriptors();
428 return result;
429 }
430 }
431 set->CommitAllDescriptors();
morrita3b41d6c2014-09-11 19:06:29432 }
benwells247f0e9a2016-08-01 05:36:47433 return MOJO_RESULT_OK;
morrita3b41d6c2014-09-11 19:06:29434}
435
morrita81b17e02015-02-06 00:58:30436// static
437MojoResult ChannelMojo::WriteToMessageAttachmentSet(
benwells247f0e9a2016-08-01 05:36:47438 mojo::Array<mojom::SerializedHandlePtr> handle_buffer,
morrita81b17e02015-02-06 00:58:30439 Message* message) {
benwells247f0e9a2016-08-01 05:36:47440 for (size_t i = 0; i < handle_buffer.size(); ++i) {
sammc57ed9f982016-03-10 06:28:35441 scoped_refptr<MessageAttachment> unwrapped_attachment;
benwells247f0e9a2016-08-01 05:36:47442 MojoResult unwrap_result = UnwrapAttachment(std::move(handle_buffer[i]),
443 &unwrapped_attachment);
sammc57ed9f982016-03-10 06:28:35444 if (unwrap_result != MOJO_RESULT_OK) {
445 LOG(WARNING) << "Pipe failed to unwrap handles. Closing: "
446 << unwrap_result;
447 return unwrap_result;
448 }
449 DCHECK(unwrapped_attachment);
450
morrita81b17e02015-02-06 00:58:30451 bool ok = message->attachment_set()->AddAttachment(
sammc57ed9f982016-03-10 06:28:35452 std::move(unwrapped_attachment));
morrita81b17e02015-02-06 00:58:30453 DCHECK(ok);
454 if (!ok) {
morritaa3889aa2015-03-16 22:40:51455 LOG(ERROR) << "Failed to add new Mojo handle.";
morrita81b17e02015-02-06 00:58:30456 return MOJO_RESULT_UNKNOWN;
457 }
458 }
morrita81b17e02015-02-06 00:58:30459 return MOJO_RESULT_OK;
460}
[email protected]64860882014-08-04 23:44:17461
rockot7c6bf952016-07-14 00:34:11462mojo::AssociatedGroup* ChannelMojo::GetAssociatedGroup() {
463 DCHECK(bootstrap_);
464 return bootstrap_->GetAssociatedGroup();
465}
466
467void ChannelMojo::AddGenericAssociatedInterface(
468 const std::string& name,
469 const GenericAssociatedInterfaceFactory& factory) {
rockot0e4de5f2016-07-22 21:18:07470 base::AutoLock locker(associated_interface_lock_);
rockot7c6bf952016-07-14 00:34:11471 auto result = associated_interfaces_.insert({ name, factory });
472 DCHECK(result.second);
473}
474
475void ChannelMojo::GetGenericRemoteAssociatedInterface(
476 const std::string& name,
477 mojo::ScopedInterfaceEndpointHandle handle) {
rockot0e4de5f2016-07-22 21:18:07478 if (message_reader_)
479 message_reader_->GetRemoteInterface(name, std::move(handle));
rockot8d890f62016-07-14 16:37:14480}
481
[email protected]64860882014-08-04 23:44:17482} // namespace IPC