diff options
author | lhchavez <lhchavez@chromium.org> | 2016-02-01 13:09:20 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-01 21:12:29 +0000 |
commit | 47e4727b0c266ec0cb7d18716bd8ae8461e3c6d3 (patch) | |
tree | ae01d6e53b6392651046d91d1334201224cf7e2f | |
parent | cef0d43adb8f0c9303ac7179a65b9b4e24ade107 (diff) | |
download | chromium_src-47e4727b0c266ec0cb7d18716bd8ae8461e3c6d3.zip chromium_src-47e4727b0c266ec0cb7d18716bd8ae8461e3c6d3.tar.gz chromium_src-47e4727b0c266ec0cb7d18716bd8ae8461e3c6d3.tar.bz2 |
arc-bridge: Migrate ARC to new Mojo EDK
This does the expected initialization of the additional pipe needed by
the Broker.
BUG=573004
TEST=ARC works with the new EDK
Review URL: https://codereview.chromium.org/1583123002
Cr-Commit-Position: refs/heads/master@{#372762}
-rw-r--r-- | components/arc/arc_bridge_bootstrap.cc | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/components/arc/arc_bridge_bootstrap.cc b/components/arc/arc_bridge_bootstrap.cc index 204bf7c..1e826b3 100644 --- a/components/arc/arc_bridge_bootstrap.cc +++ b/components/arc/arc_bridge_bootstrap.cc @@ -12,6 +12,7 @@ #include "base/files/file_util.h" #include "base/location.h" #include "base/macros.h" +#include "base/posix/eintr_wrapper.h" #include "base/task_runner_util.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread_checker.h" @@ -20,20 +21,37 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager_client.h" #include "ipc/unix_domain_socket_util.h" +#include "mojo/edk/embedder/embedder.h" +#include "mojo/edk/embedder/platform_channel_pair.h" +#include "mojo/edk/embedder/platform_channel_utils_posix.h" +#include "mojo/edk/embedder/platform_handle_vector.h" +#include "mojo/edk/embedder/scoped_platform_handle.h" #include "mojo/public/cpp/bindings/binding.h" -#include "third_party/mojo/src/mojo/edk/embedder/embedder.h" -#include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h" -#include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h" namespace arc { namespace { +static void CallMessagePipeCallbackOnThread( + const base::Callback<void(mojo::ScopedMessagePipeHandle)>& callback, + scoped_refptr<base::TaskRunner> task_runner, + mojo::ScopedMessagePipeHandle pipe) { + task_runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&pipe))); +} + +// We do not know the PID of ARC, since Chrome does not create it directly. +// Since Mojo in POSIX does not use the child PID except as an unique +// identifier for the routing table, rather than doing a lot of plumbing in the +// whole system to get the correct PID, just use an arbitrary number that will +// never be used by a legitimate process. Chrome OS assigns unassigned PIDs +// sequentially until it reaches a certain maximum value (Chrome OS uses the +// default value of 32k), at which point it loops around to zero. An arbitrary +// number larger than the maximum should be safe. +const pid_t kArcPid = 0x3DE0EA7C; + const base::FilePath::CharType kArcBridgeSocketPath[] = FILE_PATH_LITERAL("/var/run/chrome/arc_bridge.sock"); -void OnChannelCreated(mojo::embedder::ChannelInfo* channel) {} - class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap { public: // The possible states of the bootstrap connection. In the normal flow, @@ -47,6 +65,8 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap { // StartArcInstance() -> OnInstanceStarted() -> // STARTED // AcceptInstanceConnection() -> OnInstanceConnected() -> + // CONNECTED + // CreateMessagePipe() -> OnMessagePipeCreated() -> // READY // // When Stop() is called from any state, either because an operation @@ -75,7 +95,10 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap { // The instance has started. Waiting for it to connect to the IPC bridge. STARTED, - // The instance has finished booting. + // The instance has begun the connection handshake. + CONNECTED, + + // The instance is fully connected. READY, // The request to shut down the instance has been sent. @@ -99,6 +122,7 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap { // connected socket's file descriptor. static base::ScopedFD AcceptInstanceConnection(base::ScopedFD socket_fd); void OnInstanceConnected(base::ScopedFD fd); + void OnMessagePipeCreated(mojo::ScopedMessagePipeHandle server_pipe); void SetState(State state); @@ -224,7 +248,24 @@ base::ScopedFD ArcBridgeBootstrapImpl::AcceptInstanceConnection( if (!IPC::ServerAcceptConnection(socket_fd.get(), &raw_fd)) { return base::ScopedFD(); } - return base::ScopedFD(raw_fd); + base::ScopedFD scoped_fd(raw_fd); + + mojo::edk::ScopedPlatformHandle child_handle = + mojo::edk::ChildProcessLaunched(kArcPid); + + mojo::edk::ScopedPlatformHandleVectorPtr handles( + new mojo::edk::PlatformHandleVector{child_handle.release()}); + + struct iovec iov = {const_cast<char*>(""), 1}; + ssize_t result = mojo::edk::PlatformChannelSendmsgWithHandles( + mojo::edk::PlatformHandle(scoped_fd.get()), &iov, 1, handles->data(), + handles->size()); + if (result == -1) { + PLOG(ERROR) << "sendmsg"; + return base::ScopedFD(); + } + + return scoped_fd; } void ArcBridgeBootstrapImpl::OnInstanceConnected(base::ScopedFD fd) { @@ -233,11 +274,31 @@ void ArcBridgeBootstrapImpl::OnInstanceConnected(base::ScopedFD fd) { VLOG(1) << "Stop() called when ARC is not running"; return; } + if (!fd.is_valid()) { + LOG(ERROR) << "Invalid handle"; + return; + } + SetState(State::CONNECTED); + mojo::edk::CreateMessagePipe( + mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(fd.release())), + base::Bind(&CallMessagePipeCallbackOnThread, + base::Bind(&ArcBridgeBootstrapImpl::OnMessagePipeCreated, + weak_factory_.GetWeakPtr()), + base::ThreadTaskRunnerHandle::Get())); +} + +void ArcBridgeBootstrapImpl::OnMessagePipeCreated( + mojo::ScopedMessagePipeHandle server_pipe) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (state_ != State::CONNECTED) { + VLOG(1) << "Stop() called when ARC is not running"; + return; + } + if (!server_pipe.is_valid()) { + LOG(ERROR) << "Invalid pipe"; + return; + } SetState(State::READY); - mojo::ScopedMessagePipeHandle server_pipe = mojo::embedder::CreateChannel( - mojo::embedder::ScopedPlatformHandle( - mojo::embedder::PlatformHandle(fd.release())), - base::Bind(&OnChannelCreated), base::ThreadTaskRunnerHandle::Get()); ArcBridgeInstancePtr instance; instance.Bind( mojo::InterfacePtrInfo<ArcBridgeInstance>(std::move(server_pipe), 0u)); |