Chromium Code Reviews| Index: ipc/mojo/ipc_mojo_bootstrap.cc |
| diff --git a/ipc/mojo/ipc_mojo_bootstrap.cc b/ipc/mojo/ipc_mojo_bootstrap.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..128134ecf0c4319ad4d8f5ebf0ccad0e80e29921 |
| --- /dev/null |
| +++ b/ipc/mojo/ipc_mojo_bootstrap.cc |
| @@ -0,0 +1,162 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "ipc/mojo/ipc_mojo_bootstrap.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/process/process_handle.h" |
| +#include "ipc/ipc_message_utils.h" |
| +#include "ipc/ipc_platform_file.h" |
| +#include "mojo/embedder/platform_channel_pair.h" |
| + |
| +namespace IPC { |
| + |
| +// MojoBootstrap |
| + |
| +// static |
| +scoped_ptr<MojoBootstrap> MojoBootstrap::Create(ChannelHandle handle, |
| + Channel::Mode mode, |
| + Delegate* delegate) { |
| + CHECK(mode == Channel::MODE_CLIENT || mode == Channel::MODE_SERVER); |
| + scoped_ptr<MojoBootstrap> self = |
| + mode == Channel::MODE_CLIENT |
| + ? scoped_ptr<MojoBootstrap>(new MojoClientBootstrap()) |
| + : scoped_ptr<MojoBootstrap>(new MojoServerBootstrap()); |
| + scoped_ptr<Channel> bootstrap_channel = |
| + Channel::Create(handle, mode, self.get()); |
| + self->Init(bootstrap_channel.Pass(), delegate); |
| + return self.Pass(); |
| +} |
| + |
| +MojoBootstrap::MojoBootstrap() : delegate_(NULL), state_(STATE_INITIALIZED) { |
| +} |
| + |
| +MojoBootstrap::~MojoBootstrap() { |
| +} |
| + |
| +void MojoBootstrap::Init(scoped_ptr<Channel> channel, Delegate* delegate) { |
| + channel_ = channel.Pass(); |
| + delegate_ = delegate; |
| +} |
| + |
| +bool MojoBootstrap::Connect() { |
| + return channel_->Connect(); |
| +} |
| + |
| +void MojoBootstrap::OnBadMessageReceived(const Message& message) { |
| + delegate_->OnBootstrapError(); |
| +} |
| + |
| +void MojoBootstrap::OnChannelError() { |
| + if (state_ == STATE_READY) |
| + return; |
| + DLOG(WARNING) << "Detected error on Mojo bootstrap channel."; |
| + delegate()->OnBootstrapError(); |
| +} |
| + |
| +bool MojoBootstrap::Send(Message* message) { |
| + return channel_->Send(message); |
| +} |
| + |
| +#if defined(OS_POSIX) && !defined(OS_NACL) |
| +int MojoBootstrap::GetClientFileDescriptor() const { |
| + return channel_->GetClientFileDescriptor(); |
| +} |
| + |
| +int MojoBootstrap::TakeClientFileDescriptor() { |
| + return channel_->TakeClientFileDescriptor(); |
| +} |
| +#endif // defined(OS_POSIX) && !defined(OS_NACL) |
| + |
| +// MojoServerBootstrap |
| + |
| +MojoServerBootstrap::MojoServerBootstrap() |
| + : client_process_(base::kNullProcessHandle), connected_(false) { |
| +} |
| + |
| +void MojoServerBootstrap::SendClientPipe() { |
| + DCHECK(state() == STATE_INITIALIZED); |
|
viettrungluu
2014/09/15 20:19:44
DCHECK_EQ
|
| + DCHECK(client_process_ != base::kNullProcessHandle); |
|
viettrungluu
2014/09/15 20:19:43
DCHECK_NE
Hajime Morrita
2014/09/15 22:01:37
Done.
|
| + |
|
viettrungluu
2014/09/15 20:19:43
DCHECK(connected_) also?
Hajime Morrita
2014/09/15 22:01:37
Done.
|
| + mojo::embedder::PlatformChannelPair channel_pair; |
| + server_pipe_ = channel_pair.PassServerHandle(); |
| + PlatformFileForTransit client_pipe = GetFileHandleForProcess( |
| + channel_pair.PassClientHandle().release().ToPlaformFile(), |
| + client_process_, |
| + true); |
| + CHECK(client_pipe != IPC::InvalidPlatformFileForTransit()); |
| + scoped_ptr<Message> message(new Message()); |
| + ParamTraits<PlatformFileForTransit>::Write(message.get(), client_pipe); |
| + Send(message.release()); |
| + |
| + set_state(STATE_WAITING_ACK); |
| +} |
| + |
| +void MojoServerBootstrap::SendClientPipeIfReady() { |
| + // Is the client launched? |
| + if (client_process_ == base::kNullProcessHandle) |
| + return; |
| + // Has the bootstrap channel made? |
|
viettrungluu
2014/09/15 20:19:43
"made" -> "been made"
Hajime Morrita
2014/09/15 22:01:37
Done.
|
| + if (!connected_) |
| + return; |
| + |
| + SendClientPipe(); |
| +} |
| + |
| +void MojoServerBootstrap::OnClientLaunched(base::ProcessHandle process) { |
| + DCHECK(state() == STATE_INITIALIZED); |
|
viettrungluu
2014/09/15 20:19:44
DCHECK_EQ
(etc.)
Hajime Morrita
2014/09/15 22:01:37
Done.
|
| + DCHECK(process != base::kNullProcessHandle); |
| + client_process_ = process; |
| + SendClientPipeIfReady(); |
| +} |
| + |
| +void MojoServerBootstrap::OnChannelConnected(int32 peer_pid) { |
| + DCHECK(state() == STATE_INITIALIZED); |
| + connected_ = true; |
| + SendClientPipeIfReady(); |
|
viettrungluu
2014/09/15 20:19:43
Is the order of OnClientLaunched and OnChannelConn
Hajime Morrita
2014/09/15 22:01:37
Unfortunately not. RenderHost launches the child p
|
| +} |
| + |
| +bool MojoServerBootstrap::OnMessageReceived(const Message&) { |
| + DCHECK(state() == STATE_WAITING_ACK); |
| + set_state(STATE_READY); |
| + |
| + delegate()->OnPipeAvailable( |
| + mojo::embedder::ScopedPlatformHandle(server_pipe_.release())); |
| + |
| + return true; |
| +} |
| + |
| +// MojoClientBootstrap |
| + |
| +MojoClientBootstrap::MojoClientBootstrap() { |
| +} |
| + |
| +bool MojoClientBootstrap::OnMessageReceived(const Message& message) { |
| + PlatformFileForTransit pipe; |
| + PickleIterator iter(message); |
| + if (!ParamTraits<PlatformFileForTransit>::Read(&message, &iter, &pipe)) { |
| + DLOG(WARNING) << "Failed to read a file handle from bootstrap channel."; |
| + message.set_dispatch_error(); |
| + return false; |
| + } |
| + |
| + // Sends ACK back. |
| + Send(new Message()); |
| + set_state(STATE_READY); |
| + delegate()->OnPipeAvailable( |
| + mojo::embedder::ScopedPlatformHandle(mojo::embedder::PlatformHandle( |
| + PlatformFileForTransitToPlatformFile(pipe)))); |
| + |
| + return true; |
| +} |
| + |
| +void MojoClientBootstrap::OnClientLaunched(base::ProcessHandle process) { |
| + // This notification should happen only on server processes. |
| + NOTREACHED(); |
| +} |
| + |
| +void MojoClientBootstrap::OnChannelConnected(int32 peer_pid) { |
| +} |
| + |
| +} // namespace IPC |