Make PlatformChannelPair "dumb".

Now it's just a helper that creates two "connected" PlatformHandles
(modelled after mojo::MessagePipe, mojo::DataPipe, etc.). Passing one
handle to the child is now done manually.

(I want to move it to //mojo/edk/platform and maybe rename it too, but
I'll do that separately.)

R=vardhan@google.com

Review URL: https://codereview.chromium.org/1651183003 .
diff --git a/mojo/edk/embedder/multiprocess_embedder_unittest.cc b/mojo/edk/embedder/multiprocess_embedder_unittest.cc
index e848df1..ae26a42 100644
--- a/mojo/edk/embedder/multiprocess_embedder_unittest.cc
+++ b/mojo/edk/embedder/multiprocess_embedder_unittest.cc
@@ -148,10 +148,10 @@
                                            test_io_watcher());
 
   PlatformChannelPair channel_pair;
-  ScopedTestChannel server_channel(channel_pair.PassServerHandle());
+  ScopedTestChannel server_channel(channel_pair.handle0.Pass());
   MojoHandle server_mp = server_channel.bootstrap_message_pipe();
   EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
-  ScopedTestChannel client_channel(channel_pair.PassClientHandle());
+  ScopedTestChannel client_channel(channel_pair.handle1.Pass());
   MojoHandle client_mp = client_channel.bootstrap_message_pipe();
   EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
 
@@ -194,10 +194,10 @@
                                            test_io_watcher());
 
   PlatformChannelPair channel_pair;
-  ScopedTestChannel server_channel(channel_pair.PassServerHandle());
+  ScopedTestChannel server_channel(channel_pair.handle0.Pass());
   MojoHandle server_mp = server_channel.bootstrap_message_pipe();
   EXPECT_NE(server_mp, MOJO_HANDLE_INVALID);
-  ScopedTestChannel client_channel(channel_pair.PassClientHandle());
+  ScopedTestChannel client_channel(channel_pair.handle1.Pass());
   MojoHandle client_mp = client_channel.bootstrap_message_pipe();
   EXPECT_NE(client_mp, MOJO_HANDLE_INVALID);
 
@@ -370,7 +370,7 @@
   for (size_t i = 0; i < kIterations; i++) {
     PlatformChannelPair channel_pair;
     std::unique_ptr<ScopedTestChannel> server_channel(
-        new ScopedTestChannel(channel_pair.PassServerHandle()));
+        new ScopedTestChannel(channel_pair.handle0.Pass()));
     server_channel->WaitForChannelCreationCompletion();
     server_channel->NoWaitOnShutdown();
 
diff --git a/mojo/edk/embedder/platform_channel_pair.cc b/mojo/edk/embedder/platform_channel_pair.cc
index 2a143b6..43b6e28 100644
--- a/mojo/edk/embedder/platform_channel_pair.cc
+++ b/mojo/edk/embedder/platform_channel_pair.cc
@@ -10,36 +10,14 @@
 #include <unistd.h>
 
 #include "base/logging.h"
-#include "base/posix/global_descriptors.h"
 #include "build/build_config.h"
 #include "mojo/edk/platform/platform_handle.h"
-#include "mojo/edk/util/string_number_conversions.h"
 
 using mojo::platform::PlatformHandle;
-using mojo::platform::ScopedPlatformHandle;
-using mojo::util::NumberToString;
-using mojo::util::StringToNumberWithError;
 
 namespace mojo {
 namespace embedder {
 
-namespace {
-
-bool IsTargetDescriptorUsed(
-    const base::FileHandleMappingVector& file_handle_mapping,
-    int target_fd) {
-  for (size_t i = 0; i < file_handle_mapping.size(); i++) {
-    if (file_handle_mapping[i].second == target_fd)
-      return true;
-  }
-  return false;
-}
-
-}  // namespace
-
-const char PlatformChannelPair::kMojoPlatformChannelHandleSwitch[] =
-    "mojo-platform-channel-handle";
-
 PlatformChannelPair::PlatformChannelPair() {
   // Create the Unix domain socket and set the ends to nonblocking.
   int fds[2];
@@ -59,62 +37,13 @@
                     sizeof(no_sigpipe)) == 0);
 #endif  // defined(OS_MACOSX)
 
-  server_handle_.reset(PlatformHandle(fds[0]));
-  DCHECK(server_handle_.is_valid());
-  client_handle_.reset(PlatformHandle(fds[1]));
-  DCHECK(client_handle_.is_valid());
+  handle0.reset(PlatformHandle(fds[0]));
+  DCHECK(handle0.is_valid());
+  handle1.reset(PlatformHandle(fds[1]));
+  DCHECK(handle1.is_valid());
 }
 
-PlatformChannelPair::~PlatformChannelPair() {
-}
-
-ScopedPlatformHandle PlatformChannelPair::PassServerHandle() {
-  return server_handle_.Pass();
-}
-
-ScopedPlatformHandle PlatformChannelPair::PassClientHandle() {
-  return client_handle_.Pass();
-}
-
-// static
-ScopedPlatformHandle PlatformChannelPair::PassClientHandleFromParentProcess(
-    const std::string& string_from_parent) {
-  int client_fd = -1;
-  if (!StringToNumberWithError<int>(string_from_parent, &client_fd)) {
-    LOG(ERROR) << "Missing or invalid --" << kMojoPlatformChannelHandleSwitch;
-    return ScopedPlatformHandle();
-  }
-
-  return ScopedPlatformHandle(PlatformHandle(client_fd));
-}
-
-void PlatformChannelPair::PrepareToPassClientHandleToChildProcess(
-    std::string* string_for_child,
-    HandlePassingInformation* handle_passing_info) const {
-  DCHECK(string_for_child);
-  DCHECK(handle_passing_info);
-  // This is an arbitrary sanity check. (Note that this guarantees that the loop
-  // below will terminate sanely.)
-  CHECK_LT(handle_passing_info->size(), 1000u);
-
-  DCHECK(client_handle_.is_valid());
-
-  // Find a suitable FD to map our client handle to in the child process.
-  // This has quadratic time complexity in the size of |*handle_passing_info|,
-  // but |*handle_passing_info| should be very small (usually/often empty).
-  int target_fd = base::GlobalDescriptors::kBaseDescriptor;
-  while (IsTargetDescriptorUsed(*handle_passing_info, target_fd))
-    target_fd++;
-
-  handle_passing_info->push_back(
-      std::pair<int, int>(client_handle_.get().fd, target_fd));
-  *string_for_child = NumberToString<int>(target_fd);
-}
-
-void PlatformChannelPair::ChildProcessLaunched() {
-  DCHECK(client_handle_.is_valid());
-  client_handle_.reset();
-}
+PlatformChannelPair::~PlatformChannelPair() {}
 
 }  // namespace embedder
 }  // namespace mojo
diff --git a/mojo/edk/embedder/platform_channel_pair.h b/mojo/edk/embedder/platform_channel_pair.h
index d1bdf74..c9927e8 100644
--- a/mojo/edk/embedder/platform_channel_pair.h
+++ b/mojo/edk/embedder/platform_channel_pair.h
@@ -5,34 +5,15 @@
 #ifndef MOJO_EDK_EMBEDDER_PLATFORM_CHANNEL_PAIR_H_
 #define MOJO_EDK_EMBEDDER_PLATFORM_CHANNEL_PAIR_H_
 
-#include <string>
-
-#include "base/process/launch.h"
 #include "mojo/edk/platform/scoped_platform_handle.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace embedder {
 
-// It would be nice to refactor base/process/launch.h to have a more platform-
-// independent way of representing handles that are passed to child processes.
-using HandlePassingInformation = base::FileHandleMappingVector;
-
-// This is used to create a pair of |PlatformHandle|s that are connected by a
-// suitable (platform-specific) bidirectional "pipe" (e.g., Unix domain socket).
-// The resulting handles can then be used in the same process (e.g., in tests)
-// or between processes. (The "server" handle is the one that will be used in
-// the process that created the pair, whereas the "client" handle is the one
-// that will be used in a different process.)
-//
-// This class provides facilities for passing the client handle to a child
-// process. The parent should call |PrepareToPassClientHandlelToChildProcess()|
-// to get the data needed to do this, spawn the child using that data, and then
-// call |ChildProcessLaunched()|.
-//
-// Note: |PlatformChannelPair()|, |PassClientHandleFromParentProcess()| and
-// |PrepareToPassClientHandleToChildProcess()| have platform-specific
-// implementations.
+// A helper class for creating a pair of |PlatformHandle|s that are connected by
+// a suitable (platform-specific) bidirectional "pipe" (e.g., Unix domain
+// socket). The resulting handles can then be used in the same process (e.g., in
+// tests) or between processes.
 //
 // Note: On POSIX platforms, to write to the "pipe", use
 // |PlatformChannel{Write,Writev}()| (from platform_channel_utils.h) instead of
@@ -43,40 +24,8 @@
   PlatformChannelPair();
   ~PlatformChannelPair();
 
-  platform::ScopedPlatformHandle PassServerHandle();
-
-  // For in-process use (e.g., in tests or to pass over another channel).
-  platform::ScopedPlatformHandle PassClientHandle();
-
-  // To be called in the child process, after the parent process called
-  // |PrepareToPassClientHandleToChildProcess()| and launched the child (using
-  // the provided data), to create a client handle connected to the server
-  // handle (in the parent process). |string_from_parent| should be the string
-  // that was produced (in the parent process) by
-  // |PrepareToPassClientHandleToChildProcess()|.
-  static platform::ScopedPlatformHandle PassClientHandleFromParentProcess(
-      const std::string& string_from_parent);
-
-  // Prepares to pass the client channel to a new child process, to be launched
-  // using |LaunchProcess()| (from base/launch.h). |*string_for_child| will be
-  // set to a string that should be passed to the child process and which should
-  // be given (in the child ) to |PassClientHandleFromParentProcess()|. Also
-  // modifies |*handle_passing_info| as needed.
-  void PrepareToPassClientHandleToChildProcess(
-      std::string* string_for_child,
-      HandlePassingInformation* handle_passing_info) const;
-
-  // To be called once the child process has been successfully launched, to do
-  // any cleanup necessary.
-  void ChildProcessLaunched();
-
- private:
-  static const char kMojoPlatformChannelHandleSwitch[];
-
-  platform::ScopedPlatformHandle server_handle_;
-  platform::ScopedPlatformHandle client_handle_;
-
-  MOJO_DISALLOW_COPY_AND_ASSIGN(PlatformChannelPair);
+  platform::ScopedPlatformHandle handle0;
+  platform::ScopedPlatformHandle handle1;
 };
 
 }  // namespace embedder
diff --git a/mojo/edk/embedder/platform_channel_pair_unittest.cc b/mojo/edk/embedder/platform_channel_pair_unittest.cc
index 15250aa..46c849f 100644
--- a/mojo/edk/embedder/platform_channel_pair_unittest.cc
+++ b/mojo/edk/embedder/platform_channel_pair_unittest.cc
@@ -67,8 +67,8 @@
 
 TEST_F(PlatformChannelPairTest, NoSigPipe) {
   PlatformChannelPair channel_pair;
-  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle();
-  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle();
+  ScopedPlatformHandle server_handle = channel_pair.handle0.Pass();
+  ScopedPlatformHandle client_handle = channel_pair.handle1.Pass();
 
   // Write to the client.
   static const char kHello[] = "hello";
@@ -108,8 +108,8 @@
 
 TEST_F(PlatformChannelPairTest, SendReceiveData) {
   PlatformChannelPair channel_pair;
-  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle();
-  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle();
+  ScopedPlatformHandle server_handle = channel_pair.handle0.Pass();
+  ScopedPlatformHandle client_handle = channel_pair.handle1.Pass();
 
   for (size_t i = 0; i < 10; i++) {
     std::string send_string(1 << i, 'A' + i);
@@ -136,8 +136,8 @@
   static const char kHello[] = "hello";
 
   PlatformChannelPair channel_pair;
-  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle();
-  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle();
+  ScopedPlatformHandle server_handle = channel_pair.handle0.Pass();
+  ScopedPlatformHandle client_handle = channel_pair.handle1.Pass();
 
 // Reduce the number of FDs opened on OS X to avoid test flake.
 #if defined(OS_MACOSX)
@@ -199,8 +199,8 @@
   static const char kHello[] = "hello";
 
   PlatformChannelPair channel_pair;
-  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle();
-  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle();
+  ScopedPlatformHandle server_handle = channel_pair.handle0.Pass();
+  ScopedPlatformHandle client_handle = channel_pair.handle1.Pass();
 
   const std::string file_contents("hello world");
 
diff --git a/mojo/edk/system/channel_manager_unittest.cc b/mojo/edk/system/channel_manager_unittest.cc
index ee51f21..f0e7085 100644
--- a/mojo/edk/system/channel_manager_unittest.cc
+++ b/mojo/edk/system/channel_manager_unittest.cc
@@ -69,7 +69,7 @@
 
   const ChannelId id = 1;
   RefPtr<MessagePipeDispatcher> d = channel_manager().CreateChannelOnIOThread(
-      id, channel_pair.PassServerHandle());
+      id, channel_pair.handle0.Pass());
 
   RefPtr<Channel> ch = channel_manager().GetChannel(id);
   EXPECT_TRUE(ch);
@@ -92,11 +92,11 @@
 
   const ChannelId id1 = 1;
   RefPtr<MessagePipeDispatcher> d1 = channel_manager().CreateChannelOnIOThread(
-      id1, channel_pair.PassServerHandle());
+      id1, channel_pair.handle0.Pass());
 
   const ChannelId id2 = 2;
   RefPtr<MessagePipeDispatcher> d2 = channel_manager().CreateChannelOnIOThread(
-      id2, channel_pair.PassClientHandle());
+      id2, channel_pair.handle1.Pass());
 
   RefPtr<Channel> ch1 = channel_manager().GetChannel(id1);
   EXPECT_TRUE(ch1);
@@ -171,7 +171,7 @@
 
   const ChannelId id = 1;
   RefPtr<MessagePipeDispatcher> d = channel_manager().CreateChannelOnIOThread(
-      id, channel_pair.PassServerHandle());
+      id, channel_pair.handle0.Pass());
 
   OtherThread thread(task_runner().Clone(), &channel_manager(), id,
                      [this]() { message_loop()->QuitNow(); });
diff --git a/mojo/edk/system/channel_test_base.cc b/mojo/edk/system/channel_test_base.cc
index cc35b63..67d0a56 100644
--- a/mojo/edk/system/channel_test_base.cc
+++ b/mojo/edk/system/channel_test_base.cc
@@ -64,8 +64,8 @@
   CHECK(io_thread()->IsCurrentAndRunning());
 
   embedder::PlatformChannelPair channel_pair;
-  raw_channels_[0] = RawChannel::Create(channel_pair.PassServerHandle());
-  raw_channels_[1] = RawChannel::Create(channel_pair.PassClientHandle());
+  raw_channels_[0] = RawChannel::Create(channel_pair.handle0.Pass());
+  raw_channels_[1] = RawChannel::Create(channel_pair.handle1.Pass());
 }
 
 }  // namespace test
diff --git a/mojo/edk/system/connection_manager_unittest.cc b/mojo/edk/system/connection_manager_unittest.cc
index 4bb10d8..4f1bb3d 100644
--- a/mojo/edk/system/connection_manager_unittest.cc
+++ b/mojo/edk/system/connection_manager_unittest.cc
@@ -198,11 +198,10 @@
       SlaveConnectionManager* slave,
       const std::string& slave_name) {
     embedder::PlatformChannelPair platform_channel_pair;
-    ProcessIdentifier slave_process_identifier =
-        master->AddSlave(new TestSlaveInfo(slave_name),
-                         platform_channel_pair.PassServerHandle());
+    ProcessIdentifier slave_process_identifier = master->AddSlave(
+        new TestSlaveInfo(slave_name), platform_channel_pair.handle0.Pass());
     slave->Init(task_runner().Clone(), slave_process_delegate,
-                platform_channel_pair.PassClientHandle());
+                platform_channel_pair.handle1.Pass());
     return slave_process_identifier;
   }
 
@@ -652,7 +651,7 @@
   SlaveConnectionManager slave(platform_support());
   embedder::PlatformChannelPair platform_channel_pair;
   ProcessIdentifier slave_id = master.AddSlave(
-      new TestSlaveInfo("slave"), platform_channel_pair.PassServerHandle());
+      new TestSlaveInfo("slave"), platform_channel_pair.handle0.Pass());
   master.Shutdown();
   EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
   // Since we never initialized |slave|, we don't have to shut it down.
@@ -665,7 +664,7 @@
   embedder::PlatformChannelPair platform_channel_pair;
   ConnectionIdentifier connection_id = master.GenerateConnectionIdentifier();
   ProcessIdentifier slave_id = master.AddSlaveAndBootstrap(
-      new TestSlaveInfo("slave"), platform_channel_pair.PassServerHandle(),
+      new TestSlaveInfo("slave"), platform_channel_pair.handle0.Pass(),
       connection_id);
   EXPECT_TRUE(IsValidSlaveProcessIdentifier(slave_id));
 
@@ -682,7 +681,7 @@
   MockSlaveProcessDelegate slave_process_delegate;
   SlaveConnectionManager slave(platform_support());
   slave.Init(task_runner().Clone(), &slave_process_delegate,
-             platform_channel_pair.PassClientHandle());
+             platform_channel_pair.handle1.Pass());
 
   ProcessIdentifier slave_peer = kInvalidProcessIdentifier;
   ScopedPlatformHandle h2;
diff --git a/mojo/edk/system/data_pipe_impl_unittest.cc b/mojo/edk/system/data_pipe_impl_unittest.cc
index 47b2703..f161f34 100644
--- a/mojo/edk/system/data_pipe_impl_unittest.cc
+++ b/mojo/edk/system/data_pipe_impl_unittest.cc
@@ -324,12 +324,12 @@
     channels_[0] = MakeRefCounted<Channel>(&platform_support_);
     channels_[0]->Init(io_thread_.task_runner().Clone(),
                        io_thread_.platform_handle_watcher(),
-                       RawChannel::Create(channel_pair.PassServerHandle()));
+                       RawChannel::Create(channel_pair.handle0.Pass()));
     channels_[0]->SetBootstrapEndpoint(std::move(ep0));
     channels_[1] = MakeRefCounted<Channel>(&platform_support_);
     channels_[1]->Init(io_thread_.task_runner().Clone(),
                        io_thread_.platform_handle_watcher(),
-                       RawChannel::Create(channel_pair.PassClientHandle()));
+                       RawChannel::Create(channel_pair.handle1.Pass()));
     channels_[1]->SetBootstrapEndpoint(std::move(ep1));
   }
 
diff --git a/mojo/edk/system/ipc_support_unittest.cc b/mojo/edk/system/ipc_support_unittest.cc
index e0757ac..0f46b2a 100644
--- a/mojo/edk/system/ipc_support_unittest.cc
+++ b/mojo/edk/system/ipc_support_unittest.cc
@@ -175,12 +175,12 @@
     embedder::PlatformChannelPair channel_pair;
     // Note: |ChannelId|s and |ProcessIdentifier|s are interchangeable.
     RefPtr<MessagePipeDispatcher> mp = master_ipc_support_->ConnectToSlave(
-        connection_id_, nullptr, channel_pair.PassServerHandle(),
+        connection_id_, nullptr, channel_pair.handle0.Pass(),
         [this]() { event_.Signal(); }, nullptr, &slave_id_);
     EXPECT_TRUE(mp);
     EXPECT_NE(slave_id_, kInvalidProcessIdentifier);
     EXPECT_NE(slave_id_, kMasterProcessIdentifier);
-    slave_platform_handle_ = channel_pair.PassClientHandle();
+    slave_platform_handle_ = channel_pair.handle1.Pass();
     return mp;
   }
 
@@ -579,7 +579,7 @@
   ProcessIdentifier slave_id = kInvalidProcessIdentifier;
   ScopedPlatformHandle master_second_platform_handle =
       master_ipc_support().ConnectToSlaveInternal(
-          connection_id, nullptr, channel_pair.PassServerHandle(), &slave_id);
+          connection_id, nullptr, channel_pair.handle0.Pass(), &slave_id);
   ASSERT_TRUE(master_second_platform_handle.is_valid());
   EXPECT_NE(slave_id, kInvalidProcessIdentifier);
   EXPECT_NE(slave_id, kMasterProcessIdentifier);
@@ -590,8 +590,7 @@
       &platform_support(), embedder::ProcessType::SLAVE,
       test_io_thread().task_runner().Clone(), &slave_process_delegate,
       test_io_thread().task_runner().Clone(),
-      test_io_thread().platform_handle_watcher(),
-      channel_pair.PassClientHandle());
+      test_io_thread().platform_handle_watcher(), channel_pair.handle1.Pass());
 
   ScopedPlatformHandle slave_second_platform_handle =
       slave_ipc_support.ConnectToMasterInternal(connection_id);
diff --git a/mojo/edk/system/master_connection_manager.cc b/mojo/edk/system/master_connection_manager.cc
index fcd6b99..caf19b5 100644
--- a/mojo/edk/system/master_connection_manager.cc
+++ b/mojo/edk/system/master_connection_manager.cc
@@ -632,11 +632,11 @@
           ProcessConnections::ConnectionStatus::RUNNING,
           ScopedPlatformHandle());
       embedder::PlatformChannelPair platform_channel_pair;
-      *platform_handle = platform_channel_pair.PassServerHandle();
+      *platform_handle = platform_channel_pair.handle0.Pass();
 
       connections_[peer_process_identifier]->AddConnection(
           process_identifier, ProcessConnections::ConnectionStatus::PENDING,
-          platform_channel_pair.PassClientHandle());
+          platform_channel_pair.handle1.Pass());
       break;
     }
     case ProcessConnections::ConnectionStatus::PENDING:
diff --git a/mojo/edk/system/raw_channel_unittest.cc b/mojo/edk/system/raw_channel_unittest.cc
index 01f8b0c..c5a35b2 100644
--- a/mojo/edk/system/raw_channel_unittest.cc
+++ b/mojo/edk/system/raw_channel_unittest.cc
@@ -81,8 +81,8 @@
 
   void SetUp() override {
     embedder::PlatformChannelPair channel_pair;
-    handles[0] = channel_pair.PassServerHandle();
-    handles[1] = channel_pair.PassClientHandle();
+    handles[0] = channel_pair.handle0.Pass();
+    handles[1] = channel_pair.handle1.Pass();
     io_thread_.Start();
   }
 
diff --git a/mojo/edk/system/remote_data_pipe_impl_unittest.cc b/mojo/edk/system/remote_data_pipe_impl_unittest.cc
index 9930da2..31c445b 100644
--- a/mojo/edk/system/remote_data_pipe_impl_unittest.cc
+++ b/mojo/edk/system/remote_data_pipe_impl_unittest.cc
@@ -91,12 +91,12 @@
     channels_[0] = MakeRefCounted<Channel>(&platform_support_);
     channels_[0]->Init(io_thread_.task_runner().Clone(),
                        io_thread_.platform_handle_watcher(),
-                       RawChannel::Create(channel_pair.PassServerHandle()));
+                       RawChannel::Create(channel_pair.handle0.Pass()));
     channels_[0]->SetBootstrapEndpoint(std::move(ep0));
     channels_[1] = MakeRefCounted<Channel>(&platform_support_);
     channels_[1]->Init(io_thread_.task_runner().Clone(),
                        io_thread_.platform_handle_watcher(),
-                       RawChannel::Create(channel_pair.PassClientHandle()));
+                       RawChannel::Create(channel_pair.handle1.Pass()));
     channels_[1]->SetBootstrapEndpoint(std::move(ep1));
   }
 
diff --git a/mojo/edk/system/remote_message_pipe_unittest.cc b/mojo/edk/system/remote_message_pipe_unittest.cc
index 6bfbad5..f251baf 100644
--- a/mojo/edk/system/remote_message_pipe_unittest.cc
+++ b/mojo/edk/system/remote_message_pipe_unittest.cc
@@ -100,8 +100,8 @@
     CHECK(io_thread()->IsCurrentAndRunning());
 
     embedder::PlatformChannelPair channel_pair;
-    platform_handles_[0] = channel_pair.PassServerHandle();
-    platform_handles_[1] = channel_pair.PassClientHandle();
+    platform_handles_[0] = channel_pair.handle0.Pass();
+    platform_handles_[1] = channel_pair.handle1.Pass();
   }
 
   void TearDownOnIOThread() {
diff --git a/mojo/edk/test/multiprocess_test_helper.cc b/mojo/edk/test/multiprocess_test_helper.cc
index 81df315..4819a46 100644
--- a/mojo/edk/test/multiprocess_test_helper.cc
+++ b/mojo/edk/test/multiprocess_test_helper.cc
@@ -6,19 +6,21 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/posix/global_descriptors.h"
 #include "base/test/test_timeouts.h"
 #include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/edk/platform/platform_handle.h"
+#include "mojo/edk/platform/scoped_platform_handle.h"
 
+using mojo::platform::PlatformHandle;
 using mojo::platform::ScopedPlatformHandle;
 
 namespace mojo {
 namespace test {
 
-const char kPlatformChannelHandleInfoSwitch[] = "platform-channel-handle-info";
-
 MultiprocessTestHelper::MultiprocessTestHelper()
     : platform_channel_pair_(new embedder::PlatformChannelPair()) {
-  server_platform_handle = platform_channel_pair_->PassServerHandle();
+  server_platform_handle = platform_channel_pair_->handle0.Pass();
 }
 
 MultiprocessTestHelper::~MultiprocessTestHelper() {
@@ -41,16 +43,8 @@
 
   std::string test_child_main = test_child_name + "TestChildMain";
 
-  std::string string_for_child;
-  embedder::HandlePassingInformation handle_passing_info;
-  platform_channel_pair_->PrepareToPassClientHandleToChildProcess(
-      &string_for_child, &handle_passing_info);
-
   base::CommandLine command_line(
       base::GetMultiProcessTestChildBaseCommandLine());
-  command_line.AppendSwitchASCII(kPlatformChannelHandleInfoSwitch,
-                                 string_for_child);
-
   if (!switch_string.empty()) {
     CHECK(!command_line.HasSwitch(switch_string));
     if (!switch_value.empty())
@@ -59,12 +53,16 @@
       command_line.AppendSwitch(switch_string);
   }
 
+  base::FileHandleMappingVector fds_to_remap;
+  fds_to_remap.push_back(
+      std::pair<int, int>(platform_channel_pair_->handle1.get().fd,
+                          base::GlobalDescriptors::kBaseDescriptor));
   base::LaunchOptions options;
-  options.fds_to_remap = &handle_passing_info;
+  options.fds_to_remap = &fds_to_remap;
 
   test_child_ =
       base::SpawnMultiProcessTestChild(test_child_main, command_line, options);
-  platform_channel_pair_->ChildProcessLaunched();
+  platform_channel_pair_->handle1.reset();
 
   CHECK(test_child_.IsValid());
 }
@@ -86,12 +84,8 @@
 // static
 void MultiprocessTestHelper::ChildSetup() {
   CHECK(base::CommandLine::InitializedForCurrentProcess());
-  const base::CommandLine& command_line =
-      *base::CommandLine::ForCurrentProcess();
-  client_platform_handle =
-      embedder::PlatformChannelPair::PassClientHandleFromParentProcess(
-          command_line.GetSwitchValueASCII(kPlatformChannelHandleInfoSwitch));
-  CHECK(client_platform_handle.is_valid());
+  client_platform_handle = ScopedPlatformHandle(
+      PlatformHandle(base::GlobalDescriptors::kBaseDescriptor));
 }
 
 // static
diff --git a/shell/child_main.cc b/shell/child_main.cc
index 1450542..1fdcd79 100644
--- a/shell/child_main.cc
+++ b/shell/child_main.cc
@@ -17,6 +17,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
+#include "base/posix/global_descriptors.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/thread_task_runner_handle.h"
@@ -29,6 +30,7 @@
 #include "mojo/edk/embedder/platform_channel_pair.h"
 #include "mojo/edk/embedder/simple_platform_support.h"
 #include "mojo/edk/embedder/slave_process_delegate.h"
+#include "mojo/edk/platform/platform_handle.h"
 #include "mojo/edk/platform/platform_handle_watcher.h"
 #include "mojo/edk/platform/scoped_platform_handle.h"
 #include "mojo/edk/platform/task_runner.h"
@@ -42,6 +44,7 @@
 #include "shell/init.h"
 #include "shell/native_application_support.h"
 
+using mojo::platform::PlatformHandle;
 using mojo::platform::PlatformHandleWatcher;
 using mojo::platform::ScopedPlatformHandle;
 using mojo::platform::TaskRunner;
@@ -315,13 +318,8 @@
       command_line.GetSwitchValueASCII(switches::kChildConnectionId);
   CHECK(!child_connection_id.empty());
 
-  std::string platform_channel_info =
-      command_line.GetSwitchValueASCII(switches::kPlatformChannelHandleInfo);
-  ScopedPlatformHandle platform_handle =
-      mojo::embedder::PlatformChannelPair::PassClientHandleFromParentProcess(
-          platform_channel_info);
-  CHECK(platform_handle.is_valid());
-
+  ScopedPlatformHandle platform_handle(
+      (PlatformHandle(base::GlobalDescriptors::kBaseDescriptor)));
   shell::AppContext app_context;
   app_context.Init(platform_handle.Pass());
 
diff --git a/shell/child_process_host.cc b/shell/child_process_host.cc
index 880d956..e4d1745 100644
--- a/shell/child_process_host.cc
+++ b/shell/child_process_host.cc
@@ -11,6 +11,7 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/posix/global_descriptors.h"
 #include "base/process/kill.h"
 #include "base/process/launch.h"
 #include "base/task_runner.h"
@@ -67,7 +68,7 @@
   // |base_edk::PlatformTaskRunnerImpl| for each instance. Instead, there should
   // be one per thread.
   mojo::ScopedMessagePipeHandle handle(mojo::embedder::ConnectToSlave(
-      nullptr, launch_data->platform_channel_pair.PassServerHandle(),
+      nullptr, launch_data->platform_channel_pair.handle0.Pass(),
       [this]() { DidConnectToSlave(); },
       MakeRefCounted<base_edk::PlatformTaskRunnerImpl>(
           base::ThreadTaskRunnerHandle::Get()),
@@ -143,15 +144,12 @@
   child_command_line.AppendSwitchASCII(switches::kChildConnectionId,
                                        launch_data->child_connection_id);
 
-  mojo::embedder::HandlePassingInformation handle_passing_info;
-  std::string platform_channel_info;
-  launch_data->platform_channel_pair.PrepareToPassClientHandleToChildProcess(
-      &platform_channel_info, &handle_passing_info);
-  child_command_line.AppendSwitchASCII(switches::kPlatformChannelHandleInfo,
-                                       platform_channel_info);
-
+  base::FileHandleMappingVector fds_to_remap;
+  fds_to_remap.push_back(
+      std::pair<int, int>(launch_data->platform_channel_pair.handle1.get().fd,
+                          base::GlobalDescriptors::kBaseDescriptor));
   base::LaunchOptions options;
-  options.fds_to_remap = &handle_passing_info;
+  options.fds_to_remap = &fds_to_remap;
 #if defined(OS_LINUX)
   options.allow_new_privs = launch_data->options.allow_new_privs;
 #endif
@@ -160,7 +158,7 @@
   base::Process child_process =
       base::LaunchProcess(child_command_line, options);
   if (child_process.IsValid())
-    launch_data->platform_channel_pair.ChildProcessLaunched();
+    launch_data->platform_channel_pair.handle1.reset();
   return child_process.Pass();
 }
 
diff --git a/shell/child_switches.cc b/shell/child_switches.cc
index ef47412..85f31c9 100644
--- a/shell/child_switches.cc
+++ b/shell/child_switches.cc
@@ -10,9 +10,4 @@
 // |ConnectToMaster()| for its |platform_connection_id| argument.
 const char kChildConnectionId[] = "child-connection-id";
 
-// The value of this switch is the string that was produced by
-// |PlatformChannelPair::PrepareToPassClientHandleToChildProcess()| and should
-// be given to |PlatformChannelPair::PassClientHandleFromParentProcess()|.
-const char kPlatformChannelHandleInfo[] = "platform-channel-handle-info";
-
 }  // namespace switches
diff --git a/shell/child_switches.h b/shell/child_switches.h
index 4a52243..e34379b 100644
--- a/shell/child_switches.h
+++ b/shell/child_switches.h
@@ -12,7 +12,6 @@
 // All switches in alphabetical order. The switches should be documented
 // alongside the definition of their values in the .cc file.
 extern const char kChildConnectionId[];
-extern const char kPlatformChannelHandleInfo[];
 
 }  // namespace switches