blob: 1e4b49997ca7d920b55adb702d6204292496e122 [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:
rockota34707ca2016-07-20 04:28:3248 MojoChannelFactory(
49 mojo::ScopedMessagePipeHandle handle,
50 Channel::Mode mode,
51 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
52 : handle_(std::move(handle)),
53 mode_(mode),
54 ipc_task_runner_(ipc_task_runner) {}
[email protected]64860882014-08-04 23:44:1755
sammc57ed9f982016-03-10 06:28:3556 std::string GetName() const override { return ""; }
[email protected]64860882014-08-04 23:44:1757
danakj03de39b22016-04-23 04:21:0958 std::unique_ptr<Channel> BuildChannel(Listener* listener) override {
rockota34707ca2016-07-20 04:28:3259 return ChannelMojo::Create(
60 std::move(handle_), mode_, listener, ipc_task_runner_);
61 }
62
63 scoped_refptr<base::SingleThreadTaskRunner> GetIPCTaskRunner() override {
64 return ipc_task_runner_;
[email protected]64860882014-08-04 23:44:1765 }
66
67 private:
sammc57ed9f982016-03-10 06:28:3568 mojo::ScopedMessagePipeHandle handle_;
sammce4d0abd2016-03-07 22:38:0469 const Channel::Mode mode_;
rockota34707ca2016-07-20 04:28:3270 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
[email protected]64860882014-08-04 23:44:1771
sammce4d0abd2016-03-07 22:38:0472 DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory);
morritaf8f92dcd2014-10-27 20:10:2573};
74
sammc57ed9f982016-03-10 06:28:3575mojom::SerializedHandlePtr CreateSerializedHandle(
76 mojo::ScopedHandle handle,
77 mojom::SerializedHandle::Type type) {
78 mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New();
79 serialized_handle->the_handle = std::move(handle);
80 serialized_handle->type = type;
81 return serialized_handle;
82}
83
amistrycbdbf182016-06-09 04:08:1284MojoResult WrapPlatformHandle(base::PlatformFile handle,
sammc57ed9f982016-03-10 06:28:3585 mojom::SerializedHandle::Type type,
86 mojom::SerializedHandlePtr* serialized) {
amistrycbdbf182016-06-09 04:08:1287 mojo::ScopedHandle wrapped_handle = mojo::WrapPlatformFile(handle);
88 if (!wrapped_handle.is_valid())
89 return MOJO_RESULT_UNKNOWN;
sammc57ed9f982016-03-10 06:28:3590
amistrycbdbf182016-06-09 04:08:1291 *serialized = CreateSerializedHandle(std::move(wrapped_handle), type);
sammc57ed9f982016-03-10 06:28:3592 return MOJO_RESULT_OK;
93}
94
amistrycbdbf182016-06-09 04:08:1295#if defined(OS_MACOSX)
96
97MojoResult WrapMachPort(mach_port_t mach_port,
98 mojom::SerializedHandlePtr* serialized) {
99 MojoPlatformHandle platform_handle = {
100 sizeof(MojoPlatformHandle), MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT,
101 static_cast<uint64_t>(mach_port)
102 };
103
104 MojoHandle wrapped_handle;
105 MojoResult result = MojoWrapPlatformHandle(&platform_handle, &wrapped_handle);
106 if (result != MOJO_RESULT_OK)
107 return result;
108
109 *serialized = CreateSerializedHandle(
110 mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)),
111 mojom::SerializedHandle::Type::MACH_PORT);
112 return MOJO_RESULT_OK;
113}
114
115#endif
116
amistrye309ea32016-06-06 03:20:49117#if defined(OS_POSIX)
morrita98ac98f2015-02-25 02:55:04118
119base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
120 return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile())
121 : base::ScopedFD(dup(attachment->file()));
122}
123
124#endif
125
sammc57ed9f982016-03-10 06:28:35126MojoResult WrapAttachmentImpl(MessageAttachment* attachment,
127 mojom::SerializedHandlePtr* serialized) {
128 if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) {
129 *serialized = CreateSerializedHandle(
130 static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(),
131 mojom::SerializedHandle::Type::MOJO_HANDLE);
132 return MOJO_RESULT_OK;
133 }
amistrye309ea32016-06-06 03:20:49134#if defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35135 if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) {
136 // We dup() the handles in IPC::Message to transmit.
137 // IPC::MessageAttachmentSet has intricate lifecycle semantics
138 // of FDs, so just to dup()-and-own them is the safest option.
139 base::ScopedFD file = TakeOrDupFile(
140 static_cast<IPC::internal::PlatformFileAttachment*>(attachment));
141 if (!file.is_valid()) {
142 DPLOG(WARNING) << "Failed to dup FD to transmit.";
143 return MOJO_RESULT_UNKNOWN;
144 }
145
amistrycbdbf182016-06-09 04:08:12146 return WrapPlatformHandle(file.release(),
amistry980a61b2016-06-09 02:51:20147 mojom::SerializedHandle::Type::PLATFORM_FILE,
sammc57ed9f982016-03-10 06:28:35148 serialized);
149 }
150#endif
151#if defined(OS_MACOSX)
152 DCHECK_EQ(attachment->GetType(),
153 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
154 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
155 BrokerableAttachment::MACH_PORT);
156 internal::MachPortAttachmentMac& mach_port_attachment =
157 static_cast<internal::MachPortAttachmentMac&>(*attachment);
amistrycbdbf182016-06-09 04:08:12158 MojoResult result = WrapMachPort(mach_port_attachment.get_mach_port(),
159 serialized);
sammc57ed9f982016-03-10 06:28:35160 mach_port_attachment.reset_mach_port_ownership();
161 return result;
162#elif defined(OS_WIN)
163 DCHECK_EQ(attachment->GetType(),
164 MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
165 DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
166 BrokerableAttachment::WIN_HANDLE);
167 internal::HandleAttachmentWin& handle_attachment =
168 static_cast<internal::HandleAttachmentWin&>(*attachment);
169 MojoResult result = WrapPlatformHandle(
amistrycbdbf182016-06-09 04:08:12170 handle_attachment.get_handle(),
sammc57ed9f982016-03-10 06:28:35171 mojom::SerializedHandle::Type::WIN_HANDLE, serialized);
172 handle_attachment.reset_handle_ownership();
173 return result;
174#else
175 NOTREACHED();
176 return MOJO_RESULT_UNKNOWN;
177#endif // defined(OS_MACOSX)
178}
179
180MojoResult WrapAttachment(MessageAttachment* attachment,
181 mojo::Array<mojom::SerializedHandlePtr>* handles) {
182 mojom::SerializedHandlePtr serialized_handle;
183 MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle);
184 if (wrap_result != MOJO_RESULT_OK) {
185 LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
186 return wrap_result;
187 }
188 handles->push_back(std::move(serialized_handle));
189 return MOJO_RESULT_OK;
190}
191
192MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle,
193 scoped_refptr<MessageAttachment>* attachment) {
194 if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) {
195 *attachment =
196 new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle));
197 return MOJO_RESULT_OK;
198 }
amistrycbdbf182016-06-09 04:08:12199 MojoPlatformHandle platform_handle = { sizeof(MojoPlatformHandle), 0, 0 };
200 MojoResult unwrap_result = MojoUnwrapPlatformHandle(
sammc57ed9f982016-03-10 06:28:35201 handle->the_handle.release().value(), &platform_handle);
202 if (unwrap_result != MOJO_RESULT_OK)
203 return unwrap_result;
amistry980a61b2016-06-09 02:51:20204#if defined(OS_POSIX)
amistrycbdbf182016-06-09 04:08:12205 if (handle->type == mojom::SerializedHandle::Type::PLATFORM_FILE) {
206 base::PlatformFile file = base::kInvalidPlatformFile;
207 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR)
208 file = static_cast<base::PlatformFile>(platform_handle.value);
209 *attachment = new internal::PlatformFileAttachment(file);
amistry980a61b2016-06-09 02:51:20210 return MOJO_RESULT_OK;
211 }
212#endif // defined(OS_POSIX)
sammc57ed9f982016-03-10 06:28:35213#if defined(OS_MACOSX)
amistrycbdbf182016-06-09 04:08:12214 if (handle->type == mojom::SerializedHandle::Type::MACH_PORT) {
215 mach_port_t mach_port = MACH_PORT_NULL;
216 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT)
217 mach_port = static_cast<mach_port_t>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35218 *attachment = new internal::MachPortAttachmentMac(
amistrycbdbf182016-06-09 04:08:12219 mach_port, internal::MachPortAttachmentMac::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35220 return MOJO_RESULT_OK;
221 }
222#endif // defined(OS_MACOSX)
223#if defined(OS_WIN)
224 if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) {
amistrycbdbf182016-06-09 04:08:12225 base::PlatformFile handle = base::kInvalidPlatformFile;
226 if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
227 handle = reinterpret_cast<base::PlatformFile>(platform_handle.value);
sammc57ed9f982016-03-10 06:28:35228 *attachment = new internal::HandleAttachmentWin(
amistrycbdbf182016-06-09 04:08:12229 handle, internal::HandleAttachmentWin::FROM_WIRE);
sammc57ed9f982016-03-10 06:28:35230 return MOJO_RESULT_OK;
231 }
232#endif // defined(OS_WIN)
233 NOTREACHED();
234 return MOJO_RESULT_UNKNOWN;
235}
236
rockotdbb3bb6b2015-05-11 22:53:22237} // namespace
[email protected]64860882014-08-04 23:44:17238
239//------------------------------------------------------------------------------
240
[email protected]64860882014-08-04 23:44:17241// static
danakj03de39b22016-04-23 04:21:09242std::unique_ptr<ChannelMojo> ChannelMojo::Create(
sammc57ed9f982016-03-10 06:28:35243 mojo::ScopedMessagePipeHandle handle,
244 Mode mode,
rockota34707ca2016-07-20 04:28:32245 Listener* listener,
246 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
247 return base::WrapUnique(
248 new ChannelMojo(std::move(handle), mode, listener, ipc_task_runner));
[email protected]64860882014-08-04 23:44:17249}
250
251// static
danakj03de39b22016-04-23 04:21:09252std::unique_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
rockota34707ca2016-07-20 04:28:32253 mojo::ScopedMessagePipeHandle handle,
254 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
255 return base::WrapUnique(new MojoChannelFactory(
256 std::move(handle), Channel::MODE_SERVER, ipc_task_runner));
[email protected]64860882014-08-04 23:44:17257}
258
morrita54f6f80c2014-09-23 21:16:00259// static
danakj03de39b22016-04-23 04:21:09260std::unique_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
rockota34707ca2016-07-20 04:28:32261 mojo::ScopedMessagePipeHandle handle,
262 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
263 return base::WrapUnique(new MojoChannelFactory(
264 std::move(handle), Channel::MODE_CLIENT, ipc_task_runner));
morrita54f6f80c2014-09-23 21:16:00265}
266
rockota34707ca2016-07-20 04:28:32267ChannelMojo::ChannelMojo(
268 mojo::ScopedMessagePipeHandle handle,
269 Mode mode,
270 Listener* listener,
271 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
rockotc18f64f2016-03-25 04:49:18272 : pipe_(handle.get()),
rockot506f92fa22016-03-23 01:32:18273 listener_(listener),
274 waiting_connect_(true),
275 weak_factory_(this) {
morrita54f6f80c2014-09-23 21:16:00276 // Create MojoBootstrap after all members are set as it touches
277 // ChannelMojo from a different thread.
sammc57ed9f982016-03-10 06:28:35278 bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, this);
[email protected]64860882014-08-04 23:44:17279}
280
281ChannelMojo::~ChannelMojo() {
282 Close();
morritae9453ea2014-09-26 03:20:48283}
morrita54f6f80c2014-09-23 21:16:00284
[email protected]64860882014-08-04 23:44:17285bool ChannelMojo::Connect() {
erikchen90971902016-04-25 23:45:31286 WillConnect();
rockot68974392016-05-02 00:02:05287 {
288 base::AutoLock lock(lock_);
289 DCHECK(!task_runner_);
290 task_runner_ = base::ThreadTaskRunnerHandle::Get();
291 DCHECK(!message_reader_);
292 }
sammce4d0abd2016-03-07 22:38:04293 bootstrap_->Connect();
294 return true;
[email protected]64860882014-08-04 23:44:17295}
296
297void ChannelMojo::Close() {
danakj03de39b22016-04-23 04:21:09298 std::unique_ptr<internal::MessagePipeReader, ReaderDeleter> reader;
rockot506f92fa22016-03-23 01:32:18299 {
300 base::AutoLock lock(lock_);
301 if (!message_reader_)
302 return;
303 // The reader's destructor may re-enter Close, so we swap it out first to
304 // avoid deadlock when freeing it below.
305 std::swap(message_reader_, reader);
306
307 // We might Close() before we Connect().
308 waiting_connect_ = false;
309 }
310
311 reader.reset();
sammce4d0abd2016-03-07 22:38:04312}
morritab4472142015-04-20 21:20:12313
sammce4d0abd2016-03-07 22:38:04314// MojoBootstrap::Delegate implementation
315void ChannelMojo::OnPipesAvailable(
316 mojom::ChannelAssociatedPtrInfo send_channel,
317 mojom::ChannelAssociatedRequest receive_channel,
318 int32_t peer_pid) {
sammc57ed9f982016-03-10 06:28:35319 InitMessageReader(std::move(send_channel), std::move(receive_channel),
320 peer_pid);
[email protected]64860882014-08-04 23:44:17321}
322
morrita54f6f80c2014-09-23 21:16:00323void ChannelMojo::OnBootstrapError() {
324 listener_->OnChannelError();
325}
326
rockot7c6bf952016-07-14 00:34:11327void ChannelMojo::OnAssociatedInterfaceRequest(
328 const std::string& name,
329 mojo::ScopedInterfaceEndpointHandle handle) {
330 auto iter = associated_interfaces_.find(name);
331 if (iter != associated_interfaces_.end())
332 iter->second.Run(std::move(handle));
333}
334
sammce4d0abd2016-03-07 22:38:04335void ChannelMojo::InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
sammc57ed9f982016-03-10 06:28:35336 mojom::ChannelAssociatedRequest receiver,
337 base::ProcessId peer_pid) {
338 mojom::ChannelAssociatedPtr sender_ptr;
339 sender_ptr.Bind(std::move(sender));
danakj03de39b22016-04-23 04:21:09340 std::unique_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>
341 reader(new internal::MessagePipeReader(
342 pipe_, std::move(sender_ptr), std::move(receiver), peer_pid, this));
morritab4472142015-04-20 21:20:12343
rockot506f92fa22016-03-23 01:32:18344 bool connected = true;
345 {
346 base::AutoLock lock(lock_);
347 for (size_t i = 0; i < pending_messages_.size(); ++i) {
348 if (!reader->Send(std::move(pending_messages_[i]))) {
349 LOG(ERROR) << "Failed to flush pending messages";
350 pending_messages_.clear();
351 connected = false;
352 break;
353 }
354 }
355
356 if (connected) {
357 // We set |message_reader_| here and won't get any |pending_messages_|
358 // hereafter. Although we might have some if there is an error, we don't
359 // care. They cannot be sent anyway.
360 message_reader_ = std::move(reader);
sammce4d0abd2016-03-07 22:38:04361 pending_messages_.clear();
rockot506f92fa22016-03-23 01:32:18362 waiting_connect_ = false;
morrita0a24cfc92014-09-16 03:20:48363 }
morritab4472142015-04-20 21:20:12364 }
[email protected]64860882014-08-04 23:44:17365
rockot506f92fa22016-03-23 01:32:18366 if (connected)
367 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID()));
368 else
369 OnPipeError();
[email protected]64860882014-08-04 23:44:17370}
371
rockot506f92fa22016-03-23 01:32:18372void ChannelMojo::OnPipeError() {
rockotc18f64f2016-03-25 04:49:18373 DCHECK(task_runner_);
rockot506f92fa22016-03-23 01:32:18374 if (task_runner_->RunsTasksOnCurrentThread()) {
375 listener_->OnChannelError();
376 } else {
377 task_runner_->PostTask(
378 FROM_HERE,
379 base::Bind(&ChannelMojo::OnPipeError, weak_factory_.GetWeakPtr()));
380 }
[email protected]64860882014-08-04 23:44:17381}
382
[email protected]64860882014-08-04 23:44:17383bool ChannelMojo::Send(Message* message) {
amistry1e355dd12016-07-11 21:33:28384 base::AutoLock lock(lock_);
385 if (!message_reader_) {
386 pending_messages_.push_back(base::WrapUnique(message));
387 // Counts as OK before the connection is established, but it's an
388 // error otherwise.
389 return waiting_connect_;
[email protected]64860882014-08-04 23:44:17390 }
391
amistry1e355dd12016-07-11 21:33:28392 // Comment copied from ipc_channel_posix.cc:
393 // We can't close the pipe here, because calling OnChannelError may destroy
394 // this object, and that would be bad if we are called from Send(). Instead,
395 // we return false and hope the caller will close the pipe. If they do not,
396 // the pipe will still be closed next time OnFileCanReadWithoutBlocking is
397 // called.
398 //
399 // With Mojo, there's no OnFileCanReadWithoutBlocking, but we expect the
400 // pipe's connection error handler will be invoked in its place.
401 return message_reader_->Send(base::WrapUnique(message));
rockot506f92fa22016-03-23 01:32:18402}
403
404bool ChannelMojo::IsSendThreadSafe() const {
rockotf14a8ae2016-06-16 19:28:41405 return false;
[email protected]64860882014-08-04 23:44:17406}
407
408base::ProcessId ChannelMojo::GetPeerPID() const {
rockot506f92fa22016-03-23 01:32:18409 base::AutoLock lock(lock_);
sammc57ed9f982016-03-10 06:28:35410 if (!message_reader_)
411 return base::kNullProcessId;
412
413 return message_reader_->GetPeerPid();
[email protected]64860882014-08-04 23:44:17414}
415
416base::ProcessId ChannelMojo::GetSelfPID() const {
morrita0bd20bd2015-02-25 20:11:27417 return bootstrap_->GetSelfPID();
[email protected]64860882014-08-04 23:44:17418}
419
rockot7c6bf952016-07-14 00:34:11420Channel::AssociatedInterfaceSupport*
421ChannelMojo::GetAssociatedInterfaceSupport() { return this; }
422
sammce4d0abd2016-03-07 22:38:04423void ChannelMojo::OnMessageReceived(const Message& message) {
morrita7126b7a2014-12-17 19:01:40424 TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
425 "class", IPC_MESSAGE_ID_CLASS(message.type()),
426 "line", IPC_MESSAGE_ID_LINE(message.type()));
sammc57ed9f982016-03-10 06:28:35427 if (AttachmentBroker* broker = AttachmentBroker::GetGlobal()) {
428 if (broker->OnMessageReceived(message))
429 return;
430 }
[email protected]64860882014-08-04 23:44:17431 listener_->OnMessageReceived(message);
432 if (message.dispatch_error())
433 listener_->OnBadMessageReceived(message);
434}
435
amistrye309ea32016-06-06 03:20:49436#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
[email protected]64860882014-08-04 23:44:17437int ChannelMojo::GetClientFileDescriptor() const {
sammce4d0abd2016-03-07 22:38:04438 return -1;
[email protected]64860882014-08-04 23:44:17439}
440
morritaa409ccc2014-10-20 23:53:25441base::ScopedFD ChannelMojo::TakeClientFileDescriptor() {
sammce4d0abd2016-03-07 22:38:04442 return base::ScopedFD(GetClientFileDescriptor());
[email protected]64860882014-08-04 23:44:17443}
amistrye309ea32016-06-06 03:20:49444#endif // defined(OS_POSIX) && !defined(OS_NACL_SFI)
morrita3b41d6c2014-09-11 19:06:29445
446// static
morrita4b5c28e22015-01-14 21:17:06447MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
morrita96693852014-09-24 20:11:45448 Message* message,
sammc57ed9f982016-03-10 06:28:35449 mojo::Array<mojom::SerializedHandlePtr>* handles) {
morrita1aa788c2015-01-31 05:45:42450 if (message->HasAttachments()) {
morrita81b17e02015-02-06 00:58:30451 MessageAttachmentSet* set = message->attachment_set();
erikchenae6d3212015-10-10 02:43:49452 for (unsigned i = 0; i < set->num_non_brokerable_attachments(); ++i) {
sammc57ed9f982016-03-10 06:28:35453 MojoResult result = WrapAttachment(
454 set->GetNonBrokerableAttachmentAt(i).get(), handles);
455 if (result != MOJO_RESULT_OK) {
456 set->CommitAllDescriptors();
457 return result;
morrita81b17e02015-02-06 00:58:30458 }
morrita3b41d6c2014-09-11 19:06:29459 }
sammc57ed9f982016-03-10 06:28:35460 for (unsigned i = 0; i < set->num_brokerable_attachments(); ++i) {
461 MojoResult result =
462 WrapAttachment(set->GetBrokerableAttachmentAt(i).get(), handles);
463 if (result != MOJO_RESULT_OK) {
464 set->CommitAllDescriptors();
465 return result;
466 }
467 }
erikchenae6d3212015-10-10 02:43:49468 set->CommitAllDescriptors();
morrita3b41d6c2014-09-11 19:06:29469 }
morrita3b41d6c2014-09-11 19:06:29470 return MOJO_RESULT_OK;
471}
472
morrita81b17e02015-02-06 00:58:30473// static
474MojoResult ChannelMojo::WriteToMessageAttachmentSet(
sammc57ed9f982016-03-10 06:28:35475 mojo::Array<mojom::SerializedHandlePtr> handle_buffer,
morrita81b17e02015-02-06 00:58:30476 Message* message) {
477 for (size_t i = 0; i < handle_buffer.size(); ++i) {
sammc57ed9f982016-03-10 06:28:35478 scoped_refptr<MessageAttachment> unwrapped_attachment;
479 MojoResult unwrap_result = UnwrapAttachment(std::move(handle_buffer[i]),
480 &unwrapped_attachment);
481 if (unwrap_result != MOJO_RESULT_OK) {
482 LOG(WARNING) << "Pipe failed to unwrap handles. Closing: "
483 << unwrap_result;
484 return unwrap_result;
485 }
486 DCHECK(unwrapped_attachment);
487
morrita81b17e02015-02-06 00:58:30488 bool ok = message->attachment_set()->AddAttachment(
sammc57ed9f982016-03-10 06:28:35489 std::move(unwrapped_attachment));
morrita81b17e02015-02-06 00:58:30490 DCHECK(ok);
491 if (!ok) {
morritaa3889aa2015-03-16 22:40:51492 LOG(ERROR) << "Failed to add new Mojo handle.";
morrita81b17e02015-02-06 00:58:30493 return MOJO_RESULT_UNKNOWN;
494 }
495 }
morrita81b17e02015-02-06 00:58:30496 return MOJO_RESULT_OK;
497}
[email protected]64860882014-08-04 23:44:17498
rockot7c6bf952016-07-14 00:34:11499mojo::AssociatedGroup* ChannelMojo::GetAssociatedGroup() {
500 DCHECK(bootstrap_);
501 return bootstrap_->GetAssociatedGroup();
502}
503
504void ChannelMojo::AddGenericAssociatedInterface(
505 const std::string& name,
506 const GenericAssociatedInterfaceFactory& factory) {
507 auto result = associated_interfaces_.insert({ name, factory });
508 DCHECK(result.second);
509}
510
511void ChannelMojo::GetGenericRemoteAssociatedInterface(
512 const std::string& name,
513 mojo::ScopedInterfaceEndpointHandle handle) {
514 DCHECK(message_reader_);
515 message_reader_->GetRemoteInterface(name, std::move(handle));
516}
517
rockot8d890f62016-07-14 16:37:14518void ChannelMojo::SetProxyTaskRunner(
519 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
520 DCHECK(bootstrap_);
521 bootstrap_->SetProxyTaskRunner(task_runner);
522}
523
[email protected]64860882014-08-04 23:44:17524} // namespace IPC