summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlhchavez <lhchavez@chromium.org>2016-02-01 13:09:20 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-01 21:12:29 +0000
commit47e4727b0c266ec0cb7d18716bd8ae8461e3c6d3 (patch)
treeae01d6e53b6392651046d91d1334201224cf7e2f
parentcef0d43adb8f0c9303ac7179a65b9b4e24ade107 (diff)
downloadchromium_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.cc83
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));