Clone of chromium aad1ce808763f59c7a3753e08f1500a104ecc6fd refs/remotes/origin/HEAD
diff --git a/tools/android/forwarder2/command.cc b/tools/android/forwarder2/command.cc
new file mode 100644
index 0000000..9b0aa24
--- /dev/null
+++ b/tools/android/forwarder2/command.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/command.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "base/logging.h"
+#include "base/safe_strerror_posix.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "tools/android/forwarder2/socket.h"
+
+using base::StringPiece;
+
+namespace {
+
+
+// Command format:
+//      <port>:<type>
+//
+// Where:
+//   <port> is a 5-chars zero-padded ASCII decimal integer
+//          matching the target port for the command (e.g.
+//          '08080' for port 8080)
+//   <type> is a 3-char zero-padded ASCII decimal integer
+//          matching a command::Type value (e.g. 002 for
+//          ACK).
+// The column (:) is used as a separator for easier reading.
+const int kPortStringSize = 5;
+const int kCommandTypeStringSize = 2;
+// Command string size also includes the ':' separator char.
+const int kCommandStringSize = kPortStringSize + kCommandTypeStringSize + 1;
+
+}  // namespace
+
+namespace forwarder2 {
+
+bool ReadCommand(Socket* socket,
+                 int* port_out,
+                 command::Type* command_type_out) {
+  char command_buffer[kCommandStringSize + 1];
+  // To make logging easier.
+  command_buffer[kCommandStringSize] = '\0';
+
+  int bytes_read = socket->ReadNumBytes(command_buffer, kCommandStringSize);
+  if (bytes_read != kCommandStringSize) {
+    if (bytes_read < 0)
+      LOG(ERROR) << "Read() error: " << safe_strerror(errno);
+    else if (!bytes_read)
+      LOG(ERROR) << "Read() error, endpoint was unexpectedly closed.";
+    else
+      LOG(ERROR) << "Read() error, not enough data received from the socket.";
+    return false;
+  }
+
+  StringPiece port_str(command_buffer, kPortStringSize);
+  if (!StringToInt(port_str, port_out)) {
+    LOG(ERROR) << "Could not parse the command port string: "
+               << port_str;
+    return false;
+  }
+
+  StringPiece command_type_str(
+      &command_buffer[kPortStringSize + 1], kCommandTypeStringSize);
+  int command_type;
+  if (!StringToInt(command_type_str, &command_type)) {
+    LOG(ERROR) << "Could not parse the command type string: "
+               << command_type_str;
+    return false;
+  }
+  *command_type_out = static_cast<command::Type>(command_type);
+  return true;
+}
+
+bool SendCommand(command::Type command, int port, Socket* socket) {
+  char buffer[kCommandStringSize + 1];
+  int len = snprintf(buffer, sizeof(buffer), "%05d:%02d", port, command);
+  CHECK_EQ(len, kCommandStringSize);
+  // Write the full command minus the leading \0 char.
+  return socket->WriteNumBytes(buffer, len) == len;
+}
+
+bool ReceivedCommand(command::Type command, Socket* socket) {
+  int port;
+  command::Type received_command;
+  if (!ReadCommand(socket, &port, &received_command))
+    return false;
+  return received_command == command;
+}
+
+}  // namespace forwarder
diff --git a/tools/android/forwarder2/command.h b/tools/android/forwarder2/command.h
new file mode 100644
index 0000000..8e222ef
--- /dev/null
+++ b/tools/android/forwarder2/command.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_COMMAND_H_
+#define TOOLS_ANDROID_FORWARDER2_COMMAND_H_
+
+#include "base/basictypes.h"
+
+namespace forwarder2 {
+
+class Socket;
+
+namespace command {
+
+enum Type {
+  ACCEPT_ERROR = 0,
+  ACCEPT_SUCCESS,
+  ACK,
+  ADB_DATA_SOCKET_ERROR,
+  ADB_DATA_SOCKET_SUCCESS,
+  BIND_ERROR,
+  BIND_SUCCESS,
+  DATA_CONNECTION,
+  HOST_SERVER_ERROR,
+  HOST_SERVER_SUCCESS,
+  KILL_ALL_LISTENERS,
+  LISTEN,
+  UNLISTEN,
+  UNLISTEN_ERROR,
+  UNLISTEN_SUCCESS,
+};
+
+}  // namespace command
+
+bool ReadCommand(Socket* socket,
+                 int* port_out,
+                 command::Type* command_type_out);
+
+// Helper function to read the command from the |socket| and return true if the
+// |command| is equal to the given command parameter.
+bool ReceivedCommand(command::Type command, Socket* socket);
+
+bool SendCommand(command::Type command, int port, Socket* socket);
+
+}  // namespace forwarder
+
+#endif  // TOOLS_ANDROID_FORWARDER2_COMMAND_H_
diff --git a/tools/android/forwarder2/common.cc b/tools/android/forwarder2/common.cc
new file mode 100644
index 0000000..3b7387d
--- /dev/null
+++ b/tools/android/forwarder2/common.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/common.h"
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/safe_strerror_posix.h"
+
+namespace forwarder2 {
+
+void PError(const char* msg) {
+  LOG(ERROR) << msg << ": " << safe_strerror(errno);
+}
+
+void CloseFD(int fd) {
+  const int errno_copy = errno;
+  if (IGNORE_EINTR(close(fd)) < 0) {
+    PError("close");
+    errno = errno_copy;
+  }
+}
+
+}  // namespace forwarder2
diff --git a/tools/android/forwarder2/common.h b/tools/android/forwarder2/common.h
new file mode 100644
index 0000000..43de57b
--- /dev/null
+++ b/tools/android/forwarder2/common.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2012 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.
+
+// Common helper functions/classes used both in the host and device forwarder.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_COMMON_H_
+#define TOOLS_ANDROID_FORWARDER2_COMMON_H_
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+
+// Preserving errno for Close() is important because the function is very often
+// used in cleanup code, after an error occurred, and it is very easy to pass an
+// invalid file descriptor to close() in this context, or more rarely, a
+// spurious signal might make close() return -1 + setting errno to EINTR,
+// masking the real reason for the original error. This leads to very unpleasant
+// debugging sessions.
+#define PRESERVE_ERRNO_HANDLE_EINTR(Func)                     \
+  do {                                                        \
+    int local_errno = errno;                                  \
+    (void) HANDLE_EINTR(Func);                                \
+    errno = local_errno;                                      \
+  } while (false);
+
+// Wrapper around RAW_LOG() which is signal-safe. The only purpose of this macro
+// is to avoid documenting uses of RawLog().
+#define SIGNAL_SAFE_LOG(Level, Msg) \
+  RAW_LOG(Level, Msg);
+
+namespace forwarder2 {
+
+// Note that the two following functions are not signal-safe.
+
+// Chromium logging-aware implementation of libc's perror().
+void PError(const char* msg);
+
+// Closes the provided file descriptor and logs an error if it failed.
+void CloseFD(int fd);
+
+// Helps build a formatted C-string allocated in a fixed-size array. This is
+// useful in signal handlers where base::StringPrintf() can't be used safely
+// (due to its use of LOG()).
+template <int BufferSize>
+class FixedSizeStringBuilder {
+ public:
+  FixedSizeStringBuilder() {
+    Reset();
+  }
+
+  const char* buffer() const { return buffer_; }
+
+  void Reset() {
+    buffer_[0] = 0;
+    write_ptr_ = buffer_;
+  }
+
+  // Returns the number of bytes appended to the underlying buffer or -1 if it
+  // failed.
+  int Append(const char* format, ...) PRINTF_FORMAT(/* + 1 for 'this' */ 2, 3) {
+    if (write_ptr_ >= buffer_ + BufferSize)
+      return -1;
+    va_list ap;
+    va_start(ap, format);
+    const int bytes_written = vsnprintf(
+        write_ptr_, BufferSize - (write_ptr_ - buffer_), format, ap);
+    va_end(ap);
+    if (bytes_written > 0)
+      write_ptr_ += bytes_written;
+    return bytes_written;
+  }
+
+ private:
+  char* write_ptr_;
+  char buffer_[BufferSize];
+
+  COMPILE_ASSERT(BufferSize >= 1, Size_of_buffer_must_be_at_least_one);
+  DISALLOW_COPY_AND_ASSIGN(FixedSizeStringBuilder);
+};
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_COMMON_H_
diff --git a/tools/android/forwarder2/daemon.cc b/tools/android/forwarder2/daemon.cc
new file mode 100644
index 0000000..19a1054
--- /dev/null
+++ b/tools/android/forwarder2/daemon.cc
@@ -0,0 +1,290 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/daemon.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/safe_strerror_posix.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "tools/android/forwarder2/common.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+namespace {
+
+const int kBufferSize = 256;
+
+// Timeout constant used for polling when connecting to the daemon's Unix Domain
+// Socket and also when waiting for its death when it is killed.
+const int kNumTries = 100;
+const int kIdleTimeMSec = 20;
+
+void InitLoggingForDaemon(const std::string& log_file) {
+  logging::LoggingSettings settings;
+  settings.logging_dest =
+      log_file.empty() ?
+      logging::LOG_TO_SYSTEM_DEBUG_LOG : logging::LOG_TO_FILE;
+  settings.log_file = log_file.c_str();
+  settings.lock_log = logging::DONT_LOCK_LOG_FILE;
+  CHECK(logging::InitLogging(settings));
+}
+
+bool RunServerAcceptLoop(const std::string& welcome_message,
+                         Socket* server_socket,
+                         Daemon::ServerDelegate* server_delegate) {
+  bool failed = false;
+  for (;;) {
+    scoped_ptr<Socket> client_socket(new Socket());
+    if (!server_socket->Accept(client_socket.get())) {
+      if (server_socket->DidReceiveEvent())
+        break;
+      PError("Accept()");
+      failed = true;
+      break;
+    }
+    if (!client_socket->Write(welcome_message.c_str(),
+                              welcome_message.length() + 1)) {
+      PError("Write()");
+      failed = true;
+      continue;
+    }
+    server_delegate->OnClientConnected(client_socket.Pass());
+  }
+  return !failed;
+}
+
+void SigChildHandler(int signal_number) {
+  DCHECK_EQ(signal_number, SIGCHLD);
+  int status;
+  pid_t child_pid = waitpid(-1 /* any child */, &status, WNOHANG);
+  if (child_pid < 0) {
+    PError("waitpid");
+    return;
+  }
+  if (child_pid == 0)
+    return;
+  if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+    return;
+  // Avoid using StringAppendF() since it's unsafe in a signal handler due to
+  // its use of LOG().
+  FixedSizeStringBuilder<256> string_builder;
+  string_builder.Append("Daemon (pid=%d) died unexpectedly with ", child_pid);
+  if (WIFEXITED(status))
+    string_builder.Append("status %d.", WEXITSTATUS(status));
+  else if (WIFSIGNALED(status))
+    string_builder.Append("signal %d.", WTERMSIG(status));
+  else
+    string_builder.Append("unknown reason.");
+  SIGNAL_SAFE_LOG(ERROR, string_builder.buffer());
+}
+
+// Note that 0 is written to |lock_owner_pid| in case the file is not locked.
+bool GetFileLockOwnerPid(int fd, pid_t* lock_owner_pid) {
+  struct flock lock_info = {};
+  lock_info.l_type = F_WRLCK;
+  lock_info.l_whence = SEEK_CUR;
+  const int ret = HANDLE_EINTR(fcntl(fd, F_GETLK, &lock_info));
+  if (ret < 0) {
+    if (errno == EBADF) {
+      // Assume that the provided file descriptor corresponding to the PID file
+      // was valid until the daemon removed this file.
+      *lock_owner_pid = 0;
+      return true;
+    }
+    PError("fcntl");
+    return false;
+  }
+  if (lock_info.l_type == F_UNLCK) {
+    *lock_owner_pid = 0;
+    return true;
+  }
+  CHECK_EQ(F_WRLCK /* exclusive lock */, lock_info.l_type);
+  *lock_owner_pid = lock_info.l_pid;
+  return true;
+}
+
+scoped_ptr<Socket> ConnectToUnixDomainSocket(
+    const std::string& socket_name,
+    int tries_count,
+    int idle_time_msec,
+    const std::string& expected_welcome_message) {
+  for (int i = 0; i < tries_count; ++i) {
+    scoped_ptr<Socket> socket(new Socket());
+    if (!socket->ConnectUnix(socket_name)) {
+      if (idle_time_msec)
+        usleep(idle_time_msec * 1000);
+      continue;
+    }
+    char buf[kBufferSize];
+    DCHECK(expected_welcome_message.length() + 1 <= sizeof(buf));
+    memset(buf, 0, sizeof(buf));
+    if (socket->Read(buf, expected_welcome_message.length() + 1) < 0) {
+      perror("read");
+      continue;
+    }
+    if (expected_welcome_message != buf) {
+      LOG(ERROR) << "Unexpected message read from daemon: " << buf;
+      break;
+    }
+    return socket.Pass();
+  }
+  return scoped_ptr<Socket>();
+}
+
+}  // namespace
+
+Daemon::Daemon(const std::string& log_file_path,
+               const std::string& identifier,
+               ClientDelegate* client_delegate,
+               ServerDelegate* server_delegate,
+               GetExitNotifierFDCallback get_exit_fd_callback)
+  : log_file_path_(log_file_path),
+    identifier_(identifier),
+    client_delegate_(client_delegate),
+    server_delegate_(server_delegate),
+    get_exit_fd_callback_(get_exit_fd_callback) {
+  DCHECK(client_delegate_);
+  DCHECK(server_delegate_);
+  DCHECK(get_exit_fd_callback_);
+}
+
+Daemon::~Daemon() {}
+
+bool Daemon::SpawnIfNeeded() {
+  const int kSingleTry = 1;
+  const int kNoIdleTime = 0;
+  scoped_ptr<Socket> client_socket = ConnectToUnixDomainSocket(
+      identifier_, kSingleTry, kNoIdleTime, identifier_);
+  if (!client_socket) {
+    switch (fork()) {
+      case -1:
+        PError("fork()");
+        return false;
+      // Child.
+      case 0: {
+        if (setsid() < 0) {  // Detach the child process from its parent.
+          PError("setsid()");
+          exit(1);
+        }
+        InitLoggingForDaemon(log_file_path_);
+        CloseFD(STDIN_FILENO);
+        CloseFD(STDOUT_FILENO);
+        CloseFD(STDERR_FILENO);
+        const int null_fd = open("/dev/null", O_RDWR);
+        CHECK_EQ(null_fd, STDIN_FILENO);
+        CHECK_EQ(dup(null_fd), STDOUT_FILENO);
+        CHECK_EQ(dup(null_fd), STDERR_FILENO);
+        Socket command_socket;
+        if (!command_socket.BindUnix(identifier_)) {
+          scoped_ptr<Socket> client_socket = ConnectToUnixDomainSocket(
+              identifier_, kSingleTry, kNoIdleTime, identifier_);
+          if (client_socket.get()) {
+            // The daemon was spawned by a concurrent process.
+            exit(0);
+          }
+          PError("bind()");
+          exit(1);
+        }
+        server_delegate_->Init();
+        command_socket.AddEventFd(get_exit_fd_callback_());
+        return RunServerAcceptLoop(
+            identifier_, &command_socket, server_delegate_);
+      }
+      default:
+        break;
+    }
+  }
+  // Parent.
+  // Install the custom SIGCHLD handler.
+  sigset_t blocked_signals_set;
+  if (sigprocmask(0 /* first arg ignored */, NULL, &blocked_signals_set) < 0) {
+    PError("sigprocmask()");
+    return false;
+  }
+  struct sigaction old_action;
+  struct sigaction new_action;
+  memset(&new_action, 0, sizeof(new_action));
+  new_action.sa_handler = SigChildHandler;
+  new_action.sa_flags = SA_NOCLDSTOP;
+  sigemptyset(&new_action.sa_mask);
+  if (sigaction(SIGCHLD, &new_action, &old_action) < 0) {
+    PError("sigaction()");
+    return false;
+  }
+  // Connect to the daemon's Unix Domain Socket.
+  bool failed = false;
+  if (!client_socket) {
+    client_socket = ConnectToUnixDomainSocket(
+        identifier_, kNumTries, kIdleTimeMSec, identifier_);
+    if (!client_socket) {
+      LOG(ERROR) << "Could not connect to daemon's Unix Daemon socket";
+      failed = true;
+    }
+  }
+  if (!failed)
+    client_delegate_->OnDaemonReady(client_socket.get());
+  // Restore the previous signal action for SIGCHLD.
+  if (sigaction(SIGCHLD, &old_action, NULL) < 0) {
+    PError("sigaction");
+    failed = true;
+  }
+  return !failed;
+}
+
+bool Daemon::Kill() {
+  pid_t daemon_pid = Socket::GetUnixDomainSocketProcessOwner(identifier_);
+  if (daemon_pid < 0) {
+    LOG(ERROR) << "No forwarder daemon seems to be running";
+    return true;
+  }
+  if (kill(daemon_pid, SIGTERM) < 0) {
+    if (errno == ESRCH /* invalid PID */) {
+      // The daemon exited for some reason (e.g. kill by a process other than
+      // us) right before the call to kill() above.
+      LOG(ERROR) << "Could not kill daemon with PID " << daemon_pid;
+      return true;
+    }
+    PError("kill");
+    return false;
+  }
+  for (int i = 0; i < kNumTries; ++i) {
+    const pid_t previous_pid = daemon_pid;
+    daemon_pid = Socket::GetUnixDomainSocketProcessOwner(identifier_);
+    if (daemon_pid < 0)
+      return true;
+    // Since we are polling we might not see the 'daemon exited' event if
+    // another daemon was spawned during our idle period.
+    if (daemon_pid != previous_pid) {
+      LOG(WARNING) << "Daemon (pid=" << previous_pid
+                   << ") was successfully killed but a new daemon (pid="
+                   << daemon_pid << ") seems to be running now.";
+      return true;
+    }
+    usleep(kIdleTimeMSec * 1000);
+  }
+  LOG(ERROR) << "Timed out while killing daemon. "
+                "It might still be tearing down.";
+  return false;
+}
+
+}  // namespace forwarder2
diff --git a/tools/android/forwarder2/daemon.h b/tools/android/forwarder2/daemon.h
new file mode 100644
index 0000000..4b05ea4
--- /dev/null
+++ b/tools/android/forwarder2/daemon.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_DAEMON_H_
+#define TOOLS_ANDROID_FORWARDER2_DAEMON_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace forwarder2 {
+
+class Socket;
+
+// Provides a way to spawn a daemon and communicate with it.
+class Daemon {
+ public:
+  // Callback used by the daemon to shutdown properly. See pipe_notifier.h for
+  // more details.
+  typedef int (*GetExitNotifierFDCallback)();
+
+  class ClientDelegate {
+   public:
+    virtual ~ClientDelegate() {}
+
+    // Called after the daemon is ready to receive commands.
+    virtual void OnDaemonReady(Socket* daemon_socket) = 0;
+  };
+
+  class ServerDelegate {
+   public:
+    virtual ~ServerDelegate() {}
+
+    // Called after the daemon bound its Unix Domain Socket. This can be used to
+    // setup signal handlers or perform global initialization.
+    virtual void Init() = 0;
+
+    virtual void OnClientConnected(scoped_ptr<Socket> client_socket) = 0;
+  };
+
+  // |identifier| should be a unique string identifier. It is used to
+  // bind/connect the underlying Unix Domain Socket.
+  // Note that this class does not take ownership of |client_delegate| and
+  // |server_delegate|.
+  Daemon(const std::string& log_file_path,
+         const std::string& identifier,
+         ClientDelegate* client_delegate,
+         ServerDelegate* server_delegate,
+         GetExitNotifierFDCallback get_exit_fd_callback);
+
+  ~Daemon();
+
+  // Returns whether the daemon was successfully spawned. Note that this does
+  // not necessarily mean that the current process was forked in case the daemon
+  // is already running.
+  bool SpawnIfNeeded();
+
+  // Kills the daemon and blocks until it exited. Returns whether it succeeded.
+  bool Kill();
+
+ private:
+  const std::string log_file_path_;
+  const std::string identifier_;
+  ClientDelegate* const client_delegate_;
+  ServerDelegate* const server_delegate_;
+  const GetExitNotifierFDCallback get_exit_fd_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(Daemon);
+};
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_DAEMON_H_
diff --git a/tools/android/forwarder2/device_controller.cc b/tools/android/forwarder2/device_controller.cc
new file mode 100644
index 0000000..a4cb9c7
--- /dev/null
+++ b/tools/android/forwarder2/device_controller.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/device_controller.h"
+
+#include <utility>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/single_thread_task_runner.h"
+#include "tools/android/forwarder2/command.h"
+#include "tools/android/forwarder2/device_listener.h"
+#include "tools/android/forwarder2/socket.h"
+#include "tools/android/forwarder2/util.h"
+
+namespace forwarder2 {
+
+// static
+scoped_ptr<DeviceController> DeviceController::Create(
+    const std::string& adb_unix_socket,
+    int exit_notifier_fd) {
+  scoped_ptr<DeviceController> device_controller;
+  scoped_ptr<Socket> host_socket(new Socket());
+  if (!host_socket->BindUnix(adb_unix_socket)) {
+    PLOG(ERROR) << "Could not BindAndListen DeviceController socket on port "
+                << adb_unix_socket << ": ";
+    return device_controller.Pass();
+  }
+  LOG(INFO) << "Listening on Unix Domain Socket " << adb_unix_socket;
+  device_controller.reset(
+      new DeviceController(host_socket.Pass(), exit_notifier_fd));
+  return device_controller.Pass();
+}
+
+DeviceController::~DeviceController() {
+  DCHECK(construction_task_runner_->RunsTasksOnCurrentThread());
+}
+
+void DeviceController::Start() {
+  AcceptHostCommandSoon();
+}
+
+DeviceController::DeviceController(scoped_ptr<Socket> host_socket,
+                                   int exit_notifier_fd)
+    : host_socket_(host_socket.Pass()),
+      exit_notifier_fd_(exit_notifier_fd),
+      construction_task_runner_(base::MessageLoopProxy::current()),
+      weak_ptr_factory_(this) {
+  host_socket_->AddEventFd(exit_notifier_fd);
+}
+
+void DeviceController::AcceptHostCommandSoon() {
+  base::MessageLoopProxy::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&DeviceController::AcceptHostCommandInternal,
+                 base::Unretained(this)));
+}
+
+void DeviceController::AcceptHostCommandInternal() {
+  scoped_ptr<Socket> socket(new Socket);
+  if (!host_socket_->Accept(socket.get())) {
+    if (!host_socket_->DidReceiveEvent())
+      PLOG(ERROR) << "Could not Accept DeviceController socket";
+    else
+      LOG(INFO) << "Received exit notification";
+    return;
+  }
+  base::ScopedClosureRunner accept_next_client(
+      base::Bind(&DeviceController::AcceptHostCommandSoon,
+                 base::Unretained(this)));
+  // So that |socket| doesn't block on read if it has notifications.
+  socket->AddEventFd(exit_notifier_fd_);
+  int port;
+  command::Type command;
+  if (!ReadCommand(socket.get(), &port, &command)) {
+    LOG(ERROR) << "Invalid command received.";
+    return;
+  }
+  const ListenersMap::iterator listener_it = listeners_.find(port);
+  DeviceListener* const listener = listener_it == listeners_.end()
+      ? static_cast<DeviceListener*>(NULL) : listener_it->second.get();
+  switch (command) {
+    case command::LISTEN: {
+      if (listener != NULL) {
+        LOG(WARNING) << "Already forwarding port " << port
+                     << ". Attempting to restart the listener.\n";
+        DeleteRefCountedValueInMapFromIterator(listener_it, &listeners_);
+      }
+      scoped_ptr<DeviceListener> new_listener(
+          DeviceListener::Create(
+              socket.Pass(), port,
+              base::Bind(&DeviceController::DeleteListenerOnError,
+                         weak_ptr_factory_.GetWeakPtr())));
+      if (!new_listener)
+        return;
+      new_listener->Start();
+      // |port| can be zero, to allow dynamically allocated port, so instead, we
+      // call DeviceListener::listener_port() to retrieve the currently
+      // allocated port to this new listener.
+      const int listener_port = new_listener->listener_port();
+      listeners_.insert(
+          std::make_pair(listener_port,
+                         linked_ptr<DeviceListener>(new_listener.release())));
+      LOG(INFO) << "Forwarding device port " << listener_port << " to host.";
+      break;
+    }
+    case command::DATA_CONNECTION:
+      if (listener == NULL) {
+        LOG(ERROR) << "Data Connection command received, but "
+                   << "listener has not been set up yet for port " << port;
+        // After this point it is assumed that, once we close our Adb Data
+        // socket, the Adb forwarder command will propagate the closing of
+        // sockets all the way to the host side.
+        break;
+      }
+      listener->SetAdbDataSocket(socket.Pass());
+      break;
+    case command::UNLISTEN:
+      LOG(INFO) << "Unmapping port " << port;
+      if (!listener) {
+        LOG(ERROR) << "No listener found for port " << port;
+        SendCommand(command::UNLISTEN_ERROR, port, socket.get());
+        break;
+      }
+      DeleteRefCountedValueInMapFromIterator(listener_it, &listeners_);
+      SendCommand(command::UNLISTEN_SUCCESS, port, socket.get());
+      break;
+    default:
+      // TODO(felipeg): add a KillAllListeners command.
+      LOG(ERROR) << "Invalid command received. Port: " << port
+                 << " Command: " << command;
+  }
+}
+
+// static
+void DeviceController::DeleteListenerOnError(
+      const base::WeakPtr<DeviceController>& device_controller_ptr,
+      scoped_ptr<DeviceListener> device_listener) {
+  DeviceListener* const listener = device_listener.release();
+  DeviceController* const controller = device_controller_ptr.get();
+  if (!controller) {
+    // |listener| was already deleted by the controller that did have its
+    // ownership.
+    return;
+  }
+  DCHECK(controller->construction_task_runner_->RunsTasksOnCurrentThread());
+  bool listener_did_exist = DeleteRefCountedValueInMap(
+      listener->listener_port(), &controller->listeners_);
+  DCHECK(listener_did_exist);
+  // Note that |listener| was deleted by DeleteRefCountedValueInMap().
+}
+
+}  // namespace forwarder
diff --git a/tools/android/forwarder2/device_controller.h b/tools/android/forwarder2/device_controller.h
new file mode 100644
index 0000000..567a08d
--- /dev/null
+++ b/tools/android/forwarder2/device_controller.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_DEVICE_CONTROLLER_H_
+#define TOOLS_ANDROID_FORWARDER2_DEVICE_CONTROLLER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/containers/hash_tables.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace forwarder2 {
+
+class DeviceListener;
+
+// There is a single DeviceController per device_forwarder process, and it is in
+// charge of managing all active redirections on the device side (one
+// DeviceListener each).
+class DeviceController {
+ public:
+  static scoped_ptr<DeviceController> Create(const std::string& adb_unix_socket,
+                                             int exit_notifier_fd);
+  ~DeviceController();
+
+  void Start();
+
+ private:
+  typedef base::hash_map<
+      int /* port */, linked_ptr<DeviceListener> > ListenersMap;
+
+  DeviceController(scoped_ptr<Socket> host_socket, int exit_notifier_fd);
+
+  void AcceptHostCommandSoon();
+  void AcceptHostCommandInternal();
+
+  // Note that this can end up being called after the DeviceController is
+  // destroyed which is why a weak pointer is used.
+  static void DeleteListenerOnError(
+      const base::WeakPtr<DeviceController>& device_controller_ptr,
+      scoped_ptr<DeviceListener> device_listener);
+
+  const scoped_ptr<Socket> host_socket_;
+  // Used to notify the controller to exit.
+  const int exit_notifier_fd_;
+  // Lets ensure DeviceListener instances are deleted on the thread they were
+  // created on.
+  const scoped_refptr<base::SingleThreadTaskRunner> construction_task_runner_;
+  ListenersMap listeners_;
+
+  //WeakPtrFactory's documentation says:
+  // Member variables should appear before the WeakPtrFactory, to ensure
+  // that any WeakPtrs to Controller are invalidated before its members
+  // variable's destructors are executed, rendering them invalid.
+  base::WeakPtrFactory<DeviceController> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceController);
+};
+
+}  // namespace forwarder
+
+#endif  // TOOLS_ANDROID_FORWARDER2_DEVICE_CONTROLLER_H_
diff --git a/tools/android/forwarder2/device_forwarder_main.cc b/tools/android/forwarder2/device_forwarder_main.cc
new file mode 100644
index 0000000..cad46f4
--- /dev/null
+++ b/tools/android/forwarder2/device_forwarder_main.cc
@@ -0,0 +1,169 @@
+// Copyright (c) 2012 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 <signal.h>
+#include <stdlib.h>
+
+#include <iostream>
+#include <string>
+
+#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/thread.h"
+#include "tools/android/forwarder2/common.h"
+#include "tools/android/forwarder2/daemon.h"
+#include "tools/android/forwarder2/device_controller.h"
+#include "tools/android/forwarder2/pipe_notifier.h"
+
+namespace forwarder2 {
+namespace {
+
+// Leaky global instance, accessed from the signal handler.
+forwarder2::PipeNotifier* g_notifier = NULL;
+
+const int kBufSize = 256;
+
+const char kUnixDomainSocketPath[] = "chrome_device_forwarder";
+const char kDaemonIdentifier[] = "chrome_device_forwarder_daemon";
+
+void KillHandler(int /* unused */) {
+  CHECK(g_notifier);
+  if (!g_notifier->Notify())
+    exit(1);
+}
+
+// Lets the daemon fetch the exit notifier file descriptor.
+int GetExitNotifierFD() {
+  DCHECK(g_notifier);
+  return g_notifier->receiver_fd();
+}
+
+class ServerDelegate : public Daemon::ServerDelegate {
+ public:
+  ServerDelegate() : initialized_(false) {}
+
+  virtual ~ServerDelegate() {
+    if (!controller_thread_.get())
+      return;
+    // The DeviceController instance, if any, is constructed on the controller
+    // thread. Make sure that it gets deleted on that same thread. Note that
+    // DeleteSoon() is not used here since it would imply reading |controller_|
+    // from the main thread while it's set on the internal thread.
+    controller_thread_->message_loop_proxy()->PostTask(
+        FROM_HERE,
+        base::Bind(&ServerDelegate::DeleteControllerOnInternalThread,
+                   base::Unretained(this)));
+  }
+
+  void DeleteControllerOnInternalThread() {
+    DCHECK(
+        controller_thread_->message_loop_proxy()->RunsTasksOnCurrentThread());
+    controller_.reset();
+  }
+
+  // Daemon::ServerDelegate:
+  virtual void Init() OVERRIDE {
+    DCHECK(!g_notifier);
+    g_notifier = new forwarder2::PipeNotifier();
+    signal(SIGTERM, KillHandler);
+    signal(SIGINT, KillHandler);
+    controller_thread_.reset(new base::Thread("controller_thread"));
+    controller_thread_->Start();
+  }
+
+  virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
+    if (initialized_) {
+      client_socket->WriteString("OK");
+      return;
+    }
+    controller_thread_->message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&ServerDelegate::StartController, base::Unretained(this),
+                   GetExitNotifierFD(), base::Passed(&client_socket)));
+    initialized_ = true;
+  }
+
+ private:
+  void StartController(int exit_notifier_fd, scoped_ptr<Socket> client_socket) {
+    DCHECK(!controller_.get());
+    scoped_ptr<DeviceController> controller(
+        DeviceController::Create(kUnixDomainSocketPath, exit_notifier_fd));
+    if (!controller.get()) {
+      client_socket->WriteString(
+          base::StringPrintf("ERROR: Could not initialize device controller "
+                             "with ADB socket path: %s",
+                             kUnixDomainSocketPath));
+      return;
+    }
+    controller_.swap(controller);
+    controller_->Start();
+    client_socket->WriteString("OK");
+    client_socket->Close();
+  }
+
+  scoped_ptr<DeviceController> controller_;
+  scoped_ptr<base::Thread> controller_thread_;
+  bool initialized_;
+};
+
+class ClientDelegate : public Daemon::ClientDelegate {
+ public:
+  ClientDelegate() : has_failed_(false) {}
+
+  bool has_failed() const { return has_failed_; }
+
+  // Daemon::ClientDelegate:
+  virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
+    char buf[kBufSize];
+    const int bytes_read = daemon_socket->Read(
+        buf, sizeof(buf) - 1 /* leave space for null terminator */);
+    CHECK_GT(bytes_read, 0);
+    DCHECK(bytes_read < sizeof(buf));
+    buf[bytes_read] = 0;
+    base::StringPiece msg(buf, bytes_read);
+    if (msg.starts_with("ERROR")) {
+      LOG(ERROR) << msg;
+      has_failed_ = true;
+      return;
+    }
+  }
+
+ private:
+  bool has_failed_;
+};
+
+int RunDeviceForwarder(int argc, char** argv) {
+  CommandLine::Init(argc, argv);  // Needed by logging.
+  const bool kill_server = CommandLine::ForCurrentProcess()->HasSwitch(
+      "kill-server");
+  if ((kill_server && argc != 2) || (!kill_server && argc != 1)) {
+    std::cerr << "Usage: device_forwarder [--kill-server]" << std::endl;
+    return 1;
+  }
+  base::AtExitManager at_exit_manager;  // Used by base::Thread.
+  ClientDelegate client_delegate;
+  ServerDelegate daemon_delegate;
+  const char kLogFilePath[] = "";  // Log to logcat.
+  Daemon daemon(kLogFilePath, kDaemonIdentifier, &client_delegate,
+                &daemon_delegate, &GetExitNotifierFD);
+
+  if (kill_server)
+    return !daemon.Kill();
+
+  if (!daemon.SpawnIfNeeded())
+    return 1;
+  return client_delegate.has_failed();
+}
+
+}  // namespace
+}  // namespace forwarder2
+
+int main(int argc, char** argv) {
+  return forwarder2::RunDeviceForwarder(argc, argv);
+}
diff --git a/tools/android/forwarder2/device_listener.cc b/tools/android/forwarder2/device_listener.cc
new file mode 100644
index 0000000..b48a746
--- /dev/null
+++ b/tools/android/forwarder2/device_listener.cc
@@ -0,0 +1,130 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/device_listener.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/single_thread_task_runner.h"
+#include "tools/android/forwarder2/command.h"
+#include "tools/android/forwarder2/forwarder.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+// static
+scoped_ptr<DeviceListener> DeviceListener::Create(
+    scoped_ptr<Socket> host_socket,
+    int listener_port,
+    const ErrorCallback& error_callback) {
+  scoped_ptr<Socket> listener_socket(new Socket());
+  scoped_ptr<DeviceListener> device_listener;
+  if (!listener_socket->BindTcp("", listener_port)) {
+    LOG(ERROR) << "Device could not bind and listen to local port "
+               << listener_port;
+    SendCommand(command::BIND_ERROR, listener_port, host_socket.get());
+    return device_listener.Pass();
+  }
+  // In case the |listener_port_| was zero, GetPort() will return the
+  // currently (non-zero) allocated port for this socket.
+  listener_port = listener_socket->GetPort();
+  SendCommand(command::BIND_SUCCESS, listener_port, host_socket.get());
+  device_listener.reset(
+      new DeviceListener(listener_socket.Pass(), host_socket.Pass(),
+                         listener_port, error_callback));
+  return device_listener.Pass();
+}
+
+DeviceListener::~DeviceListener() {
+  DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread());
+  deletion_notifier_.Notify();
+}
+
+void DeviceListener::Start() {
+  thread_.Start();
+  AcceptNextClientSoon();
+}
+
+void DeviceListener::SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket) {
+  thread_.message_loop_proxy()->PostTask(
+      FROM_HERE,
+      base::Bind(&DeviceListener::OnAdbDataSocketReceivedOnInternalThread,
+                 base::Unretained(this), base::Passed(&adb_data_socket)));
+}
+
+DeviceListener::DeviceListener(scoped_ptr<Socket> listener_socket,
+                               scoped_ptr<Socket> host_socket,
+                               int port,
+                               const ErrorCallback& error_callback)
+    : self_deleter_helper_(this, error_callback),
+      listener_socket_(listener_socket.Pass()),
+      host_socket_(host_socket.Pass()),
+      listener_port_(port),
+      deletion_task_runner_(base::MessageLoopProxy::current()),
+      thread_("DeviceListener") {
+  CHECK(host_socket_.get());
+  DCHECK(deletion_task_runner_.get());
+  host_socket_->AddEventFd(deletion_notifier_.receiver_fd());
+  listener_socket_->AddEventFd(deletion_notifier_.receiver_fd());
+}
+
+void DeviceListener::AcceptNextClientSoon() {
+  thread_.message_loop_proxy()->PostTask(
+      FROM_HERE,
+      base::Bind(&DeviceListener::AcceptClientOnInternalThread,
+                 base::Unretained(this)));
+}
+
+void DeviceListener::AcceptClientOnInternalThread() {
+  device_data_socket_.reset(new Socket());
+  if (!listener_socket_->Accept(device_data_socket_.get())) {
+    if (listener_socket_->DidReceiveEvent()) {
+      LOG(INFO) << "Received exit notification, stopped accepting clients.";
+      OnInternalThreadError();
+      return;
+    }
+    LOG(WARNING) << "Could not Accept in ListenerSocket.";
+    SendCommand(command::ACCEPT_ERROR, listener_port_, host_socket_.get());
+    OnInternalThreadError();
+    return;
+  }
+  SendCommand(command::ACCEPT_SUCCESS, listener_port_, host_socket_.get());
+  if (!ReceivedCommand(command::HOST_SERVER_SUCCESS,
+                       host_socket_.get())) {
+    SendCommand(command::ACK, listener_port_, host_socket_.get());
+    LOG(ERROR) << "Host could not connect to server.";
+    device_data_socket_->Close();
+    if (host_socket_->has_error()) {
+      LOG(ERROR) << "Adb Control connection lost. "
+                 << "Listener port: " << listener_port_;
+      OnInternalThreadError();
+      return;
+    }
+    // It can continue if the host forwarder could not connect to the host
+    // server but the control connection is still alive (no errors). The device
+    // acknowledged that (above), and it can re-try later.
+    AcceptNextClientSoon();
+    return;
+  }
+}
+
+void DeviceListener::OnAdbDataSocketReceivedOnInternalThread(
+    scoped_ptr<Socket> adb_data_socket) {
+  DCHECK(adb_data_socket);
+  SendCommand(command::ADB_DATA_SOCKET_SUCCESS, listener_port_,
+              host_socket_.get());
+  forwarders_manager_.CreateAndStartNewForwarder(
+      device_data_socket_.Pass(), adb_data_socket.Pass());
+  AcceptNextClientSoon();
+}
+
+void DeviceListener::OnInternalThreadError() {
+  self_deleter_helper_.MaybeSelfDeleteSoon();
+}
+
+}  // namespace forwarder
diff --git a/tools/android/forwarder2/device_listener.h b/tools/android/forwarder2/device_listener.h
new file mode 100644
index 0000000..c7724f4
--- /dev/null
+++ b/tools/android/forwarder2/device_listener.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_
+#define TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread.h"
+#include "tools/android/forwarder2/forwarders_manager.h"
+#include "tools/android/forwarder2/pipe_notifier.h"
+#include "tools/android/forwarder2/self_deleter_helper.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace forwarder2 {
+
+class Forwarder;
+
+// A DeviceListener instance is used in the device_forwarder program to bind to
+// a specific device-side |port| and wait for client connections. When a
+// connection happens, it informs the corresponding HostController instance
+// running on the host, through |host_socket|. Then the class expects a call to
+// its SetAdbDataSocket() method (performed by the device controller) once the
+// host opened a new connection to the device. When this happens, a new internal
+// Forwarder instance is started.
+// Note that instances of this class are owned by the device controller which
+// creates and destroys them on the same thread. In case an internal error
+// happens on the DeviceListener's internal thread, the DeviceListener
+// can also self-delete by executing the user-provided callback on the thread
+// the DeviceListener was created on.
+// Note that the DeviceListener's destructor joins its internal thread (i.e.
+// waits for its completion) which means that the internal thread is guaranteed
+// not to be running anymore once the object is deleted.
+class DeviceListener {
+ public:
+  // Callback that is used for self-deletion on error to let the device
+  // controller perform some additional cleanup work (e.g. removing the device
+  // listener instance from its internal map before deleting it).
+  typedef base::Callback<void (scoped_ptr<DeviceListener>)> ErrorCallback;
+
+  static scoped_ptr<DeviceListener> Create(scoped_ptr<Socket> host_socket,
+                                           int port,
+                                           const ErrorCallback& error_callback);
+
+  ~DeviceListener();
+
+  void Start();
+
+  void SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket);
+
+  int listener_port() const { return listener_port_; }
+
+ private:
+  DeviceListener(scoped_ptr<Socket> listener_socket,
+                 scoped_ptr<Socket> host_socket,
+                 int port,
+                 const ErrorCallback& error_callback);
+
+  // Pushes an AcceptClientOnInternalThread() task to the internal thread's
+  // message queue in order to wait for a new client soon.
+  void AcceptNextClientSoon();
+
+  void AcceptClientOnInternalThread();
+
+  void OnAdbDataSocketReceivedOnInternalThread(
+      scoped_ptr<Socket> adb_data_socket);
+
+  void OnInternalThreadError();
+
+  SelfDeleterHelper<DeviceListener> self_deleter_helper_;
+  // Used for the listener thread to be notified on destruction. We have one
+  // notifier per Listener thread since each Listener thread may be requested to
+  // exit for different reasons independently from each other and independent
+  // from the main program, ex. when the host requests to forward/listen the
+  // same port again.  Both the |host_socket_| and |listener_socket_| must share
+  // the same receiver file descriptor from |deletion_notifier_| and it is set
+  // in the constructor.
+  PipeNotifier deletion_notifier_;
+  // The local device listener socket for accepting connections from the local
+  // port (listener_port_).
+  const scoped_ptr<Socket> listener_socket_;
+  // The listener socket for sending control commands.
+  const scoped_ptr<Socket> host_socket_;
+  scoped_ptr<Socket> device_data_socket_;
+  const int listener_port_;
+  // Task runner used for deletion set at construction time (i.e. the object is
+  // deleted on the same thread it is created on).
+  scoped_refptr<base::SingleThreadTaskRunner> deletion_task_runner_;
+  base::Thread thread_;
+  ForwardersManager forwarders_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceListener);
+};
+
+}  // namespace forwarder
+
+#endif  // TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_
diff --git a/tools/android/forwarder2/forwarder.cc b/tools/android/forwarder2/forwarder.cc
new file mode 100644
index 0000000..1e0bcd0
--- /dev/null
+++ b/tools/android/forwarder2/forwarder.cc
@@ -0,0 +1,255 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/forwarder.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+namespace {
+
+const int kBufferSize = 32 * 1024;
+
+}  // namespace
+
+
+// Helper class to buffer reads and writes from one socket to another.
+// Each implements a small buffer connected two one input socket, and
+// one output socket.
+//
+//   socket_from_ ---> [BufferedCopier] ---> socket_to_
+//
+// These objects are used in a pair to handle duplex traffic, as in:
+//
+//                    ------> [BufferedCopier_1] --->
+//                  /                                \
+//      socket_1   *                                  * socket_2
+//                  \                                /
+//                   <------ [BufferedCopier_2] <----
+//
+// When a BufferedCopier is in the READING state (see below), it only listens
+// to events on its input socket, and won't detect when its output socket
+// disconnects. To work around this, its peer will call its Close() method
+// when that happens.
+
+class Forwarder::BufferedCopier {
+ public:
+  // Possible states:
+  //    READING - Empty buffer and Waiting for input.
+  //    WRITING - Data in buffer, and waiting for output.
+  //    CLOSING - Like WRITING, but do not try to read after that.
+  //    CLOSED  - Completely closed.
+  //
+  // State transitions are:
+  //
+  //   T01:  READING ---[receive data]---> WRITING
+  //   T02:  READING ---[error on input socket]---> CLOSED
+  //   T03:  READING ---[Close() call]---> CLOSED
+  //
+  //   T04:  WRITING ---[write partial data]---> WRITING
+  //   T05:  WRITING ---[write all data]----> READING
+  //   T06:  WRITING ---[error on output socket]----> CLOSED
+  //   T07:  WRITING ---[Close() call]---> CLOSING
+  //
+  //   T08:  CLOSING ---[write partial data]---> CLOSING
+  //   T09:  CLOSING ---[write all data]----> CLOSED
+  //   T10:  CLOSING ---[Close() call]---> CLOSING
+  //   T11:  CLOSING ---[error on output socket] ---> CLOSED
+  //
+  enum State {
+    STATE_READING = 0,
+    STATE_WRITING = 1,
+    STATE_CLOSING = 2,
+    STATE_CLOSED = 3,
+  };
+
+  // Does NOT own the pointers.
+  BufferedCopier(Socket* socket_from, Socket* socket_to)
+      : socket_from_(socket_from),
+        socket_to_(socket_to),
+        bytes_read_(0),
+        write_offset_(0),
+        peer_(NULL),
+        state_(STATE_READING) {}
+
+  // Sets the 'peer_' field pointing to the other BufferedCopier in a pair.
+  void SetPeer(BufferedCopier* peer) {
+    DCHECK(!peer_);
+    peer_ = peer;
+  }
+
+  bool is_closed() const { return state_ == STATE_CLOSED; }
+
+  // Gently asks to close a buffer. Called either by the peer or the forwarder.
+  void Close() {
+    switch (state_) {
+      case STATE_READING:
+        state_ = STATE_CLOSED;  // T03
+        break;
+      case STATE_WRITING:
+        state_ = STATE_CLOSING;  // T07
+        break;
+      case STATE_CLOSING:
+        break;  // T10
+      case STATE_CLOSED:
+        ;
+    }
+  }
+
+  // Call this before select(). This updates |read_fds|,
+  // |write_fds| and |max_fd| appropriately *if* the buffer isn't closed.
+  void PrepareSelect(fd_set* read_fds, fd_set* write_fds, int* max_fd) {
+    int fd;
+    switch (state_) {
+      case STATE_READING:
+        DCHECK(bytes_read_ == 0);
+        DCHECK(write_offset_ == 0);
+        fd = socket_from_->fd();
+        if (fd < 0) {
+          ForceClose();  // T02
+          return;
+        }
+        FD_SET(fd, read_fds);
+        break;
+
+      case STATE_WRITING:
+      case STATE_CLOSING:
+        DCHECK(bytes_read_ > 0);
+        DCHECK(write_offset_ < bytes_read_);
+        fd = socket_to_->fd();
+        if (fd < 0) {
+          ForceClose();  // T06
+          return;
+        }
+        FD_SET(fd, write_fds);
+        break;
+
+      case STATE_CLOSED:
+        return;
+    }
+    *max_fd = std::max(*max_fd, fd);
+  }
+
+  // Call this after a select() call to operate over the buffer.
+  void ProcessSelect(const fd_set& read_fds, const fd_set& write_fds) {
+    int fd, ret;
+    switch (state_) {
+      case STATE_READING:
+        fd = socket_from_->fd();
+        if (fd < 0) {
+          state_ = STATE_CLOSED;  // T02
+          return;
+        }
+        if (!FD_ISSET(fd, &read_fds))
+          return;
+
+        ret = socket_from_->NonBlockingRead(buffer_, kBufferSize);
+        if (ret <= 0) {
+          ForceClose();  // T02
+          return;
+        }
+        bytes_read_ = ret;
+        write_offset_ = 0;
+        state_ = STATE_WRITING;  // T01
+        break;
+
+      case STATE_WRITING:
+      case STATE_CLOSING:
+        fd = socket_to_->fd();
+        if (fd < 0) {
+          ForceClose();  // T06 + T11
+          return;
+        }
+        if (!FD_ISSET(fd, &write_fds))
+          return;
+
+        ret = socket_to_->NonBlockingWrite(buffer_ + write_offset_,
+                                           bytes_read_ - write_offset_);
+        if (ret <= 0) {
+          ForceClose();  // T06 + T11
+          return;
+        }
+
+        write_offset_ += ret;
+        if (write_offset_ < bytes_read_)
+          return;  // T08 + T04
+
+        write_offset_ = 0;
+        bytes_read_ = 0;
+        if (state_ == STATE_CLOSING) {
+          ForceClose();  // T09
+          return;
+        }
+        state_ = STATE_READING;  // T05
+        break;
+
+      case STATE_CLOSED:
+        ;
+    }
+  }
+
+ private:
+  // Internal method used to close the buffer and notify the peer, if any.
+  void ForceClose() {
+    if (peer_) {
+      peer_->Close();
+      peer_ = NULL;
+    }
+    state_ = STATE_CLOSED;
+  }
+
+  // Not owned.
+  Socket* socket_from_;
+  Socket* socket_to_;
+
+  int bytes_read_;
+  int write_offset_;
+  BufferedCopier* peer_;
+  State state_;
+  char buffer_[kBufferSize];
+
+  DISALLOW_COPY_AND_ASSIGN(BufferedCopier);
+};
+
+Forwarder::Forwarder(scoped_ptr<Socket> socket1,
+                     scoped_ptr<Socket> socket2)
+    : socket1_(socket1.Pass()),
+      socket2_(socket2.Pass()),
+      buffer1_(new BufferedCopier(socket1_.get(), socket2_.get())),
+      buffer2_(new BufferedCopier(socket2_.get(), socket1_.get())) {
+  buffer1_->SetPeer(buffer2_.get());
+  buffer2_->SetPeer(buffer1_.get());
+}
+
+Forwarder::~Forwarder() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void Forwarder::RegisterFDs(fd_set* read_fds, fd_set* write_fds, int* max_fd) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  buffer1_->PrepareSelect(read_fds, write_fds, max_fd);
+  buffer2_->PrepareSelect(read_fds, write_fds, max_fd);
+}
+
+void Forwarder::ProcessEvents(const fd_set& read_fds, const fd_set& write_fds) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  buffer1_->ProcessSelect(read_fds, write_fds);
+  buffer2_->ProcessSelect(read_fds, write_fds);
+}
+
+bool Forwarder::IsClosed() const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return buffer1_->is_closed() && buffer2_->is_closed();
+}
+
+void Forwarder::Shutdown() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  buffer1_->Close();
+  buffer2_->Close();
+}
+
+}  // namespace forwarder2
diff --git a/tools/android/forwarder2/forwarder.gyp b/tools/android/forwarder2/forwarder.gyp
new file mode 100644
index 0000000..fbf5eba
--- /dev/null
+++ b/tools/android/forwarder2/forwarder.gyp
@@ -0,0 +1,70 @@
+# Copyright (c) 2012 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'forwarder2',
+      'type': 'none',
+      'dependencies': [
+        'device_forwarder',
+        'host_forwarder#host',
+      ],
+      # For the component build, ensure dependent shared libraries are stripped
+      # and put alongside forwarder to simplify pushing to the device.
+      'variables': {
+         'output_dir': '<(PRODUCT_DIR)/forwarder_dist/',
+         'native_binary': '<(PRODUCT_DIR)/device_forwarder',
+      },
+      'includes': ['../../../build/android/native_app_dependencies.gypi'],
+    },
+    {
+      'target_name': 'device_forwarder',
+      'type': 'executable',
+      'toolsets': ['target'],
+      'dependencies': [
+        '../../../base/base.gyp:base',
+        '../common/common.gyp:android_tools_common',
+      ],
+      'include_dirs': [
+        '../../..',
+      ],
+      'sources': [
+        'command.cc',
+        'common.cc',
+        'daemon.cc',
+        'device_controller.cc',
+        'device_forwarder_main.cc',
+        'device_listener.cc',
+        'forwarder.cc',
+        'forwarders_manager.cc',
+        'pipe_notifier.cc',
+        'socket.cc',
+      ],
+    },
+    {
+      'target_name': 'host_forwarder',
+      'type': 'executable',
+      'toolsets': ['host'],
+      'dependencies': [
+        '../../../base/base.gyp:base',
+        '../common/common.gyp:android_tools_common',
+      ],
+      'include_dirs': [
+        '../../..',
+      ],
+      'sources': [
+        'command.cc',
+        'common.cc',
+        'daemon.cc',
+        'forwarder.cc',
+        'forwarders_manager.cc',
+        'host_controller.cc',
+        'host_forwarder_main.cc',
+        'pipe_notifier.cc',
+        'socket.cc',
+      ],
+    },
+  ],
+}
diff --git a/tools/android/forwarder2/forwarder.h b/tools/android/forwarder2/forwarder.h
new file mode 100644
index 0000000..0be86fc
--- /dev/null
+++ b/tools/android/forwarder2/forwarder.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_FORWARDER_H_
+#define TOOLS_ANDROID_FORWARDER2_FORWARDER_H_
+
+#include <sys/select.h>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+
+namespace forwarder2 {
+
+class Socket;
+
+// Internal class that forwards traffic between |socket1| and |socket2|. Note
+// that this class is not thread-safe.
+class Forwarder {
+ public:
+  Forwarder(scoped_ptr<Socket> socket1, scoped_ptr<Socket> socket2);
+
+  ~Forwarder();
+
+  void RegisterFDs(fd_set* read_fds, fd_set* write_fds, int* max_fd);
+
+  void ProcessEvents(const fd_set& read_fds, const fd_set& write_fds);
+
+  bool IsClosed() const;
+
+  void Shutdown();
+
+ private:
+  class BufferedCopier;
+
+  base::ThreadChecker thread_checker_;
+  const scoped_ptr<Socket> socket1_;
+  const scoped_ptr<Socket> socket2_;
+  // Copies data from socket1 to socket2.
+  const scoped_ptr<BufferedCopier> buffer1_;
+  // Copies data from socket2 to socket1.
+  const scoped_ptr<BufferedCopier> buffer2_;
+};
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_FORWARDER_H_
diff --git a/tools/android/forwarder2/forwarders_manager.cc b/tools/android/forwarder2/forwarders_manager.cc
new file mode 100644
index 0000000..1795cb5
--- /dev/null
+++ b/tools/android/forwarder2/forwarders_manager.cc
@@ -0,0 +1,132 @@
+// Copyright 2013 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 "tools/android/forwarder2/forwarders_manager.h"
+
+#include <sys/select.h>
+#include <unistd.h>
+
+#include <algorithm>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/posix/eintr_wrapper.h"
+#include "tools/android/forwarder2/forwarder.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+ForwardersManager::ForwardersManager() : thread_("ForwardersManagerThread") {
+  thread_.Start();
+  WaitForEventsOnInternalThreadSoon();
+}
+
+
+ForwardersManager::~ForwardersManager() {
+  deletion_notifier_.Notify();
+}
+
+void ForwardersManager::CreateAndStartNewForwarder(scoped_ptr<Socket> socket1,
+                                                   scoped_ptr<Socket> socket2) {
+  // Note that the internal Forwarder vector is populated on the internal thread
+  // which is the only thread from which it's accessed.
+  thread_.message_loop_proxy()->PostTask(
+      FROM_HERE,
+      base::Bind(&ForwardersManager::CreateNewForwarderOnInternalThread,
+                 base::Unretained(this), base::Passed(&socket1),
+                 base::Passed(&socket2)));
+
+  // Guarantees that the CreateNewForwarderOnInternalThread callback posted to
+  // the internal thread gets executed immediately.
+  wakeup_notifier_.Notify();
+}
+
+void ForwardersManager::CreateNewForwarderOnInternalThread(
+    scoped_ptr<Socket> socket1,
+    scoped_ptr<Socket> socket2) {
+  DCHECK(thread_.message_loop_proxy()->RunsTasksOnCurrentThread());
+  forwarders_.push_back(new Forwarder(socket1.Pass(), socket2.Pass()));
+}
+
+void ForwardersManager::WaitForEventsOnInternalThreadSoon() {
+  thread_.message_loop_proxy()->PostTask(
+      FROM_HERE,
+      base::Bind(&ForwardersManager::WaitForEventsOnInternalThread,
+                 base::Unretained(this)));
+}
+
+void ForwardersManager::WaitForEventsOnInternalThread() {
+  DCHECK(thread_.message_loop_proxy()->RunsTasksOnCurrentThread());
+  fd_set read_fds;
+  fd_set write_fds;
+
+  FD_ZERO(&read_fds);
+  FD_ZERO(&write_fds);
+
+  // Populate the file descriptor sets.
+  int max_fd = -1;
+  for (ScopedVector<Forwarder>::iterator it = forwarders_.begin();
+       it != forwarders_.end(); ++it) {
+    Forwarder* const forwarder = *it;
+    forwarder->RegisterFDs(&read_fds, &write_fds, &max_fd);
+  }
+
+  const int notifier_fds[] = {
+    wakeup_notifier_.receiver_fd(),
+    deletion_notifier_.receiver_fd(),
+  };
+
+  for (int i = 0; i < arraysize(notifier_fds); ++i) {
+    const int notifier_fd = notifier_fds[i];
+    DCHECK_GT(notifier_fd, -1);
+    FD_SET(notifier_fd, &read_fds);
+    max_fd = std::max(max_fd, notifier_fd);
+  }
+
+  const int ret = HANDLE_EINTR(
+      select(max_fd + 1, &read_fds, &write_fds, NULL, NULL));
+  if (ret < 0) {
+    PLOG(ERROR) << "select";
+    return;
+  }
+
+  const bool must_shutdown = FD_ISSET(
+      deletion_notifier_.receiver_fd(), &read_fds);
+  if (must_shutdown && forwarders_.empty())
+    return;
+
+  base::ScopedClosureRunner wait_for_events_soon(
+      base::Bind(&ForwardersManager::WaitForEventsOnInternalThreadSoon,
+                 base::Unretained(this)));
+
+  if (FD_ISSET(wakeup_notifier_.receiver_fd(), &read_fds)) {
+    // Note that the events on FDs other than the wakeup notifier one, if any,
+    // will be processed upon the next select().
+    wakeup_notifier_.Reset();
+    return;
+  }
+
+  // Notify the Forwarder instances and remove the ones that are closed.
+  for (size_t i = 0; i < forwarders_.size(); ) {
+    Forwarder* const forwarder = forwarders_[i];
+    forwarder->ProcessEvents(read_fds, write_fds);
+
+    if (must_shutdown)
+      forwarder->Shutdown();
+
+    if (!forwarder->IsClosed()) {
+      ++i;
+      continue;
+    }
+
+    std::swap(forwarders_[i], forwarders_.back());
+    forwarders_.pop_back();
+  }
+}
+
+}  // namespace forwarder2
diff --git a/tools/android/forwarder2/forwarders_manager.h b/tools/android/forwarder2/forwarders_manager.h
new file mode 100644
index 0000000..4c6dea6
--- /dev/null
+++ b/tools/android/forwarder2/forwarders_manager.h
@@ -0,0 +1,45 @@
+// Copyright 2013 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_FORWARDERS_MANAGER_H_
+#define TOOLS_ANDROID_FORWARDER2_FORWARDERS_MANAGER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/threading/thread.h"
+#include "tools/android/forwarder2/pipe_notifier.h"
+
+namespace forwarder2 {
+
+class Forwarder;
+class Socket;
+
+// Creates, owns and notifies Forwarder instances on its own internal thread.
+class ForwardersManager {
+ public:
+  ForwardersManager();
+
+  // Must be called on the thread the constructor was called on.
+  ~ForwardersManager();
+
+  // Can be called on any thread.
+  void CreateAndStartNewForwarder(scoped_ptr<Socket> socket1,
+                                  scoped_ptr<Socket> socket2);
+
+ private:
+  void CreateNewForwarderOnInternalThread(scoped_ptr<Socket> socket1,
+                                          scoped_ptr<Socket> socket2);
+
+  void WaitForEventsOnInternalThreadSoon();
+  void WaitForEventsOnInternalThread();
+
+  ScopedVector<Forwarder> forwarders_;
+  PipeNotifier deletion_notifier_;
+  PipeNotifier wakeup_notifier_;
+  base::Thread thread_;
+};
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_FORWARDERS_MANAGER_H_
diff --git a/tools/android/forwarder2/host_controller.cc b/tools/android/forwarder2/host_controller.cc
new file mode 100644
index 0000000..94e63ec
--- /dev/null
+++ b/tools/android/forwarder2/host_controller.cc
@@ -0,0 +1,170 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/host_controller.h"
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "tools/android/forwarder2/command.h"
+#include "tools/android/forwarder2/forwarder.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+// static
+scoped_ptr<HostController> HostController::Create(
+    int device_port,
+    int host_port,
+    int adb_port,
+    int exit_notifier_fd,
+    const ErrorCallback& error_callback) {
+  scoped_ptr<HostController> host_controller;
+  scoped_ptr<PipeNotifier> delete_controller_notifier(new PipeNotifier());
+  scoped_ptr<Socket> adb_control_socket(new Socket());
+  adb_control_socket->AddEventFd(exit_notifier_fd);
+  adb_control_socket->AddEventFd(delete_controller_notifier->receiver_fd());
+  if (!adb_control_socket->ConnectTcp(std::string(), adb_port)) {
+    LOG(ERROR) << "Could not connect HostController socket on port: "
+               << adb_port;
+    return host_controller.Pass();
+  }
+  // Send the command to the device start listening to the "device_forward_port"
+  bool send_command_success = SendCommand(
+      command::LISTEN, device_port, adb_control_socket.get());
+  CHECK(send_command_success);
+  int device_port_allocated;
+  command::Type command;
+  if (!ReadCommand(
+          adb_control_socket.get(), &device_port_allocated, &command) ||
+      command != command::BIND_SUCCESS) {
+    LOG(ERROR) << "Device binding error using port " << device_port;
+    return host_controller.Pass();
+  }
+  host_controller.reset(
+      new HostController(
+          device_port_allocated, host_port, adb_port, exit_notifier_fd,
+          error_callback, adb_control_socket.Pass(),
+          delete_controller_notifier.Pass()));
+  return host_controller.Pass();
+}
+
+HostController::~HostController() {
+  DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread());
+  delete_controller_notifier_->Notify();
+}
+
+void HostController::Start() {
+  thread_.Start();
+  ReadNextCommandSoon();
+}
+
+HostController::HostController(
+    int device_port,
+    int host_port,
+    int adb_port,
+    int exit_notifier_fd,
+    const ErrorCallback& error_callback,
+    scoped_ptr<Socket> adb_control_socket,
+    scoped_ptr<PipeNotifier> delete_controller_notifier)
+    : self_deleter_helper_(this, error_callback),
+      device_port_(device_port),
+      host_port_(host_port),
+      adb_port_(adb_port),
+      global_exit_notifier_fd_(exit_notifier_fd),
+      adb_control_socket_(adb_control_socket.Pass()),
+      delete_controller_notifier_(delete_controller_notifier.Pass()),
+      deletion_task_runner_(base::MessageLoopProxy::current()),
+      thread_("HostControllerThread") {
+}
+
+void HostController::ReadNextCommandSoon() {
+  thread_.message_loop_proxy()->PostTask(
+      FROM_HERE,
+      base::Bind(&HostController::ReadCommandOnInternalThread,
+                 base::Unretained(this)));
+}
+
+void HostController::ReadCommandOnInternalThread() {
+  if (!ReceivedCommand(command::ACCEPT_SUCCESS, adb_control_socket_.get())) {
+    LOG(ERROR) << "Did not receive ACCEPT_SUCCESS for port: "
+               << host_port_;
+    OnInternalThreadError();
+    return;
+  }
+  // Try to connect to host server.
+  scoped_ptr<Socket> host_server_data_socket(new Socket());
+  if (!host_server_data_socket->ConnectTcp(std::string(), host_port_)) {
+    LOG(ERROR) << "Could not Connect HostServerData socket on port: "
+               << host_port_;
+    SendCommand(
+        command::HOST_SERVER_ERROR, device_port_, adb_control_socket_.get());
+    if (ReceivedCommand(command::ACK, adb_control_socket_.get())) {
+      // It can continue if the host forwarder could not connect to the host
+      // server but the device acknowledged that, so that the device could
+      // re-try later.
+      ReadNextCommandSoon();
+      return;
+    }
+    OnInternalThreadError();
+    return;
+  }
+  LOG(INFO) << "Will send HOST_SERVER_SUCCESS: " << host_port_;
+  SendCommand(
+      command::HOST_SERVER_SUCCESS, device_port_, adb_control_socket_.get());
+  StartForwarder(host_server_data_socket.Pass());
+  ReadNextCommandSoon();
+}
+
+void HostController::StartForwarder(
+    scoped_ptr<Socket> host_server_data_socket) {
+  scoped_ptr<Socket> adb_data_socket(new Socket());
+  if (!adb_data_socket->ConnectTcp("", adb_port_)) {
+    LOG(ERROR) << "Could not connect AdbDataSocket on port: " << adb_port_;
+    OnInternalThreadError();
+    return;
+  }
+  // Open the Adb data connection, and send a command with the
+  // |device_forward_port| as a way for the device to identify the connection.
+  SendCommand(command::DATA_CONNECTION, device_port_, adb_data_socket.get());
+
+  // Check that the device received the new Adb Data Connection. Note that this
+  // check is done through the |adb_control_socket_| that is handled in the
+  // DeviceListener thread just after the call to WaitForAdbDataSocket().
+  if (!ReceivedCommand(command::ADB_DATA_SOCKET_SUCCESS,
+                       adb_control_socket_.get())) {
+    LOG(ERROR) << "Device could not handle the new Adb Data Connection.";
+    OnInternalThreadError();
+    return;
+  }
+  forwarders_manager_.CreateAndStartNewForwarder(
+      host_server_data_socket.Pass(), adb_data_socket.Pass());
+}
+
+void HostController::OnInternalThreadError() {
+  UnmapPortOnDevice();
+  self_deleter_helper_.MaybeSelfDeleteSoon();
+}
+
+void HostController::UnmapPortOnDevice() {
+  Socket socket;
+  if (!socket.ConnectTcp("", adb_port_)) {
+    LOG(ERROR) << "Could not connect to device on port " << adb_port_;
+    return;
+  }
+  if (!SendCommand(command::UNLISTEN, device_port_, &socket)) {
+    LOG(ERROR) << "Could not send unmap command for port " << device_port_;
+    return;
+  }
+  if (!ReceivedCommand(command::UNLISTEN_SUCCESS, &socket)) {
+    LOG(ERROR) << "Unamp command failed for port " << device_port_;
+    return;
+  }
+}
+
+}  // namespace forwarder2
diff --git a/tools/android/forwarder2/host_controller.h b/tools/android/forwarder2/host_controller.h
new file mode 100644
index 0000000..d228bcc
--- /dev/null
+++ b/tools/android/forwarder2/host_controller.h
@@ -0,0 +1,96 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_HOST_CONTROLLER_H_
+#define TOOLS_ANDROID_FORWARDER2_HOST_CONTROLLER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread.h"
+#include "tools/android/forwarder2/forwarders_manager.h"
+#include "tools/android/forwarder2/pipe_notifier.h"
+#include "tools/android/forwarder2/self_deleter_helper.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+// This class partners with DeviceController and has the same lifetime and
+// threading characteristics as DeviceListener. In a nutshell, this class
+// operates on its own thread and is destroyed on the thread it was constructed
+// on. The class' deletion can happen in two different ways:
+// - Its destructor was called by its owner (HostControllersManager).
+// - Its internal thread requested self-deletion after an error happened. In
+//   this case the owner (HostControllersManager) is notified on the
+//   construction thread through the provided ErrorCallback invoked with the
+//   HostController instance. When this callback is invoked, it's up to the
+//   owner to delete the instance.
+class HostController {
+ public:
+  // Callback used for self-deletion when an error happens so that the client
+  // can perform some cleanup work before deleting the HostController instance.
+  typedef base::Callback<void (scoped_ptr<HostController>)> ErrorCallback;
+
+  // If |device_port| is zero then a dynamic port is allocated (and retrievable
+  // through device_port() below).
+  static scoped_ptr<HostController> Create(int device_port,
+                                           int host_port,
+                                           int adb_port,
+                                           int exit_notifier_fd,
+                                           const ErrorCallback& error_callback);
+
+  ~HostController();
+
+  // Starts the internal controller thread.
+  void Start();
+
+  int adb_port() const { return adb_port_; }
+
+  int device_port() const { return device_port_; }
+
+ private:
+  HostController(int device_port,
+                 int host_port,
+                 int adb_port,
+                 int exit_notifier_fd,
+                 const ErrorCallback& error_callback,
+                 scoped_ptr<Socket> adb_control_socket,
+                 scoped_ptr<PipeNotifier> delete_controller_notifier);
+
+  void ReadNextCommandSoon();
+  void ReadCommandOnInternalThread();
+
+  void StartForwarder(scoped_ptr<Socket> host_server_data_socket);
+
+  // Note that this gets also called when ~HostController() is invoked.
+  void OnInternalThreadError();
+
+  void UnmapPortOnDevice();
+
+  SelfDeleterHelper<HostController> self_deleter_helper_;
+  const int device_port_;
+  const int host_port_;
+  const int adb_port_;
+  // Used to notify the controller when the process is killed.
+  const int global_exit_notifier_fd_;
+  scoped_ptr<Socket> adb_control_socket_;
+  // Used to cancel the pending blocking IO operations when the host controller
+  // instance is deleted.
+  scoped_ptr<PipeNotifier> delete_controller_notifier_;
+  // Task runner used for deletion set at deletion time (i.e. the object is
+  // deleted on the same thread it is created on).
+  const scoped_refptr<base::SingleThreadTaskRunner> deletion_task_runner_;
+  base::Thread thread_;
+  ForwardersManager forwarders_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(HostController);
+};
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_HOST_CONTROLLER_H_
diff --git a/tools/android/forwarder2/host_forwarder_main.cc b/tools/android/forwarder2/host_forwarder_main.cc
new file mode 100644
index 0000000..59571b6
--- /dev/null
+++ b/tools/android/forwarder2/host_forwarder_main.cc
@@ -0,0 +1,460 @@
+// Copyright (c) 2012 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 <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <cstdio>
+#include <iostream>
+#include <limits>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/at_exit.h"
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "base/containers/hash_tables.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
+#include "base/pickle.h"
+#include "base/safe_strerror_posix.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/task_runner.h"
+#include "base/threading/thread.h"
+#include "tools/android/forwarder2/common.h"
+#include "tools/android/forwarder2/daemon.h"
+#include "tools/android/forwarder2/host_controller.h"
+#include "tools/android/forwarder2/pipe_notifier.h"
+#include "tools/android/forwarder2/socket.h"
+#include "tools/android/forwarder2/util.h"
+
+namespace forwarder2 {
+namespace {
+
+const char kLogFilePath[] = "/tmp/host_forwarder_log";
+const char kDaemonIdentifier[] = "chrome_host_forwarder_daemon";
+
+const char kKillServerCommand[] = "kill-server";
+const char kForwardCommand[] = "forward";
+
+const int kBufSize = 256;
+
+// Needs to be global to be able to be accessed from the signal handler.
+PipeNotifier* g_notifier = NULL;
+
+// Lets the daemon fetch the exit notifier file descriptor.
+int GetExitNotifierFD() {
+  DCHECK(g_notifier);
+  return g_notifier->receiver_fd();
+}
+
+void KillHandler(int signal_number) {
+  char buf[kBufSize];
+  if (signal_number != SIGTERM && signal_number != SIGINT) {
+    snprintf(buf, sizeof(buf), "Ignoring unexpected signal %d.", signal_number);
+    SIGNAL_SAFE_LOG(WARNING, buf);
+    return;
+  }
+  snprintf(buf, sizeof(buf), "Received signal %d.", signal_number);
+  SIGNAL_SAFE_LOG(WARNING, buf);
+  static int s_kill_handler_count = 0;
+  CHECK(g_notifier);
+  // If for some reason the forwarder get stuck in any socket waiting forever,
+  // we can send a SIGKILL or SIGINT three times to force it die
+  // (non-nicely). This is useful when debugging.
+  ++s_kill_handler_count;
+  if (!g_notifier->Notify() || s_kill_handler_count > 2)
+    exit(1);
+}
+
+// Manages HostController instances. There is one HostController instance for
+// each connection being forwarded. Note that forwarding can happen with many
+// devices (identified with a serial id).
+class HostControllersManager {
+ public:
+  HostControllersManager()
+      : weak_ptr_factory_(this),
+        controllers_(new HostControllerMap()),
+        has_failed_(false) {
+  }
+
+  ~HostControllersManager() {
+    if (!thread_.get())
+      return;
+    // Delete the controllers on the thread they were created on.
+    thread_->message_loop_proxy()->DeleteSoon(
+        FROM_HERE, controllers_.release());
+  }
+
+  void HandleRequest(const std::string& device_serial,
+                     int device_port,
+                     int host_port,
+                     scoped_ptr<Socket> client_socket) {
+    // Lazy initialize so that the CLI process doesn't get this thread created.
+    InitOnce();
+    thread_->message_loop_proxy()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            &HostControllersManager::HandleRequestOnInternalThread,
+            base::Unretained(this), device_serial, device_port, host_port,
+            base::Passed(&client_socket)));
+  }
+
+  bool has_failed() const { return has_failed_; }
+
+ private:
+  typedef base::hash_map<
+      std::string, linked_ptr<HostController> > HostControllerMap;
+
+  static std::string MakeHostControllerMapKey(int adb_port, int device_port) {
+    return base::StringPrintf("%d:%d", adb_port, device_port);
+  }
+
+  void InitOnce() {
+    if (thread_.get())
+      return;
+    at_exit_manager_.reset(new base::AtExitManager());
+    thread_.reset(new base::Thread("HostControllersManagerThread"));
+    thread_->Start();
+  }
+
+  // Invoked when a HostController instance reports an error (e.g. due to a
+  // device connectivity issue). Note that this could be called after the
+  // controller manager was destroyed which is why a weak pointer is used.
+  static void DeleteHostController(
+      const base::WeakPtr<HostControllersManager>& manager_ptr,
+      scoped_ptr<HostController> host_controller) {
+    HostController* const controller = host_controller.release();
+    HostControllersManager* const manager = manager_ptr.get();
+    if (!manager) {
+      // Note that |controller| is not leaked in this case since the host
+      // controllers manager owns the controllers. If the manager was deleted
+      // then all the controllers (including |controller|) were also deleted.
+      return;
+    }
+    DCHECK(manager->thread_->message_loop_proxy()->RunsTasksOnCurrentThread());
+    // Note that this will delete |controller| which is owned by the map.
+    DeleteRefCountedValueInMap(
+        MakeHostControllerMapKey(
+            controller->adb_port(), controller->device_port()),
+        manager->controllers_.get());
+  }
+
+  void HandleRequestOnInternalThread(const std::string& device_serial,
+                                     int device_port,
+                                     int host_port,
+                                     scoped_ptr<Socket> client_socket) {
+    const int adb_port = GetAdbPortForDevice(device_serial);
+    if (adb_port < 0) {
+      SendMessage(
+          "ERROR: could not get adb port for device. You might need to add "
+          "'adb' to your PATH or provide the device serial id.",
+          client_socket.get());
+      return;
+    }
+    if (device_port < 0) {
+      // Remove the previously created host controller.
+      const std::string controller_key = MakeHostControllerMapKey(
+          adb_port, -device_port);
+      const bool controller_did_exist = DeleteRefCountedValueInMap(
+          controller_key, controllers_.get());
+      SendMessage(
+          !controller_did_exist ? "ERROR: could not unmap port" : "OK",
+          client_socket.get());
+
+      RemoveAdbPortForDeviceIfNeeded(device_serial);
+      return;
+    }
+    if (host_port < 0) {
+      SendMessage("ERROR: missing host port", client_socket.get());
+      return;
+    }
+    const bool use_dynamic_port_allocation = device_port == 0;
+    if (!use_dynamic_port_allocation) {
+      const std::string controller_key = MakeHostControllerMapKey(
+          adb_port, device_port);
+      if (controllers_->find(controller_key) != controllers_->end()) {
+        LOG(INFO) << "Already forwarding device port " << device_port
+                  << " to host port " << host_port;
+        SendMessage(base::StringPrintf("%d:%d", device_port, host_port),
+                    client_socket.get());
+        return;
+      }
+    }
+    // Create a new host controller.
+    scoped_ptr<HostController> host_controller(
+        HostController::Create(
+            device_port, host_port, adb_port, GetExitNotifierFD(),
+            base::Bind(&HostControllersManager::DeleteHostController,
+                       weak_ptr_factory_.GetWeakPtr())));
+    if (!host_controller.get()) {
+      has_failed_ = true;
+      SendMessage("ERROR: Connection to device failed.", client_socket.get());
+      return;
+    }
+    // Get the current allocated port.
+    device_port = host_controller->device_port();
+    LOG(INFO) << "Forwarding device port " << device_port << " to host port "
+              << host_port;
+    const std::string msg = base::StringPrintf("%d:%d", device_port, host_port);
+    if (!SendMessage(msg, client_socket.get()))
+      return;
+    host_controller->Start();
+    controllers_->insert(
+        std::make_pair(MakeHostControllerMapKey(adb_port, device_port),
+                       linked_ptr<HostController>(host_controller.release())));
+  }
+
+  void RemoveAdbPortForDeviceIfNeeded(const std::string& device_serial) {
+    base::hash_map<std::string, int>::const_iterator it =
+        device_serial_to_adb_port_map_.find(device_serial);
+    if (it == device_serial_to_adb_port_map_.end())
+      return;
+
+    int port = it->second;
+    const std::string prefix = base::StringPrintf("%d:", port);
+    for (HostControllerMap::const_iterator others = controllers_->begin();
+         others != controllers_->end(); ++others) {
+      if (others->first.find(prefix) == 0U)
+        return;
+    }
+    // No other port is being forwarded to this device:
+    // - Remove it from our internal serial -> adb port map.
+    // - Remove from "adb forward" command.
+    LOG(INFO) << "Device " << device_serial << " has no more ports.";
+    device_serial_to_adb_port_map_.erase(device_serial);
+    const std::string serial_part = device_serial.empty() ?
+        std::string() : std::string("-s ") + device_serial;
+    const std::string command = base::StringPrintf(
+        "adb %s forward --remove tcp:%d",
+        serial_part.c_str(),
+        port);
+    const int ret = system(command.c_str());
+    LOG(INFO) << command << " ret: " << ret;
+    // Wait for the socket to be fully unmapped.
+    const std::string port_mapped_cmd = base::StringPrintf(
+        "lsof -nPi:%d",
+        port);
+    const int poll_interval_us = 500 * 1000;
+    int retries = 3;
+    while (retries) {
+      const int port_unmapped = system(port_mapped_cmd.c_str());
+      LOG(INFO) << "Device " << device_serial << " port " << port << " unmap "
+                << port_unmapped;
+      if (port_unmapped)
+        break;
+      --retries;
+      usleep(poll_interval_us);
+    }
+  }
+
+  int GetAdbPortForDevice(const std::string& device_serial) {
+    base::hash_map<std::string, int>::const_iterator it =
+        device_serial_to_adb_port_map_.find(device_serial);
+    if (it != device_serial_to_adb_port_map_.end())
+      return it->second;
+    Socket bind_socket;
+    CHECK(bind_socket.BindTcp("127.0.0.1", 0));
+    const int port = bind_socket.GetPort();
+    bind_socket.Close();
+    const std::string serial_part = device_serial.empty() ?
+        std::string() : std::string("-s ") + device_serial;
+    const std::string command = base::StringPrintf(
+        "adb %s forward tcp:%d localabstract:chrome_device_forwarder",
+        serial_part.c_str(),
+        port);
+    LOG(INFO) << command;
+    const int ret = system(command.c_str());
+    if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
+      return -1;
+    device_serial_to_adb_port_map_[device_serial] = port;
+    return port;
+  }
+
+  bool SendMessage(const std::string& msg, Socket* client_socket) {
+    bool result = client_socket->WriteString(msg);
+    DCHECK(result);
+    if (!result)
+      has_failed_ = true;
+    return result;
+  }
+
+  base::WeakPtrFactory<HostControllersManager> weak_ptr_factory_;
+  base::hash_map<std::string, int> device_serial_to_adb_port_map_;
+  scoped_ptr<HostControllerMap> controllers_;
+  bool has_failed_;
+  scoped_ptr<base::AtExitManager> at_exit_manager_;  // Needed by base::Thread.
+  scoped_ptr<base::Thread> thread_;
+};
+
+class ServerDelegate : public Daemon::ServerDelegate {
+ public:
+  ServerDelegate() : has_failed_(false) {}
+
+  bool has_failed() const {
+    return has_failed_ || controllers_manager_.has_failed();
+  }
+
+  // Daemon::ServerDelegate:
+  virtual void Init() OVERRIDE {
+    LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")";
+    DCHECK(!g_notifier);
+    g_notifier = new PipeNotifier();
+    signal(SIGTERM, KillHandler);
+    signal(SIGINT, KillHandler);
+  }
+
+  virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
+    char buf[kBufSize];
+    const int bytes_read = client_socket->Read(buf, sizeof(buf));
+    if (bytes_read <= 0) {
+      if (client_socket->DidReceiveEvent())
+        return;
+      PError("Read()");
+      has_failed_ = true;
+      return;
+    }
+    const Pickle command_pickle(buf, bytes_read);
+    PickleIterator pickle_it(command_pickle);
+    std::string device_serial;
+    CHECK(pickle_it.ReadString(&device_serial));
+    int device_port;
+    if (!pickle_it.ReadInt(&device_port)) {
+      client_socket->WriteString("ERROR: missing device port");
+      return;
+    }
+    int host_port;
+    if (!pickle_it.ReadInt(&host_port))
+      host_port = -1;
+    controllers_manager_.HandleRequest(
+        device_serial, device_port, host_port, client_socket.Pass());
+  }
+
+ private:
+  bool has_failed_;
+  HostControllersManager controllers_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServerDelegate);
+};
+
+class ClientDelegate : public Daemon::ClientDelegate {
+ public:
+  ClientDelegate(const Pickle& command_pickle)
+      : command_pickle_(command_pickle),
+        has_failed_(false) {
+  }
+
+  bool has_failed() const { return has_failed_; }
+
+  // Daemon::ClientDelegate:
+  virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
+    // Send the forward command to the daemon.
+    CHECK_EQ(command_pickle_.size(),
+             daemon_socket->WriteNumBytes(command_pickle_.data(),
+                                          command_pickle_.size()));
+    char buf[kBufSize];
+    const int bytes_read = daemon_socket->Read(
+        buf, sizeof(buf) - 1 /* leave space for null terminator */);
+    CHECK_GT(bytes_read, 0);
+    DCHECK(bytes_read < sizeof(buf));
+    buf[bytes_read] = 0;
+    base::StringPiece msg(buf, bytes_read);
+    if (msg.starts_with("ERROR")) {
+      LOG(ERROR) << msg;
+      has_failed_ = true;
+      return;
+    }
+    printf("%s\n", buf);
+  }
+
+ private:
+  const Pickle command_pickle_;
+  bool has_failed_;
+};
+
+void ExitWithUsage() {
+  std::cerr << "Usage: host_forwarder [options]\n\n"
+               "Options:\n"
+               "  --serial-id=[0-9A-Z]{16}]\n"
+               "  --map DEVICE_PORT HOST_PORT\n"
+               "  --unmap DEVICE_PORT\n"
+               "  --kill-server\n";
+  exit(1);
+}
+
+int PortToInt(const std::string& s) {
+  int value;
+  // Note that 0 is a valid port (used for dynamic port allocation).
+  if (!base::StringToInt(s, &value) || value < 0 ||
+      value > std::numeric_limits<uint16>::max()) {
+    LOG(ERROR) << "Could not convert string " << s << " to port";
+    ExitWithUsage();
+  }
+  return value;
+}
+
+int RunHostForwarder(int argc, char** argv) {
+  CommandLine::Init(argc, argv);
+  const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
+  bool kill_server = false;
+
+  Pickle pickle;
+  pickle.WriteString(
+      cmd_line.HasSwitch("serial-id") ?
+          cmd_line.GetSwitchValueASCII("serial-id") : std::string());
+
+  const std::vector<std::string> args = cmd_line.GetArgs();
+  if (cmd_line.HasSwitch("kill-server")) {
+    kill_server = true;
+  } else if (cmd_line.HasSwitch("unmap")) {
+    if (args.size() != 1)
+      ExitWithUsage();
+    // Note the minus sign below.
+    pickle.WriteInt(-PortToInt(args[0]));
+  } else if (cmd_line.HasSwitch("map")) {
+    if (args.size() != 2)
+      ExitWithUsage();
+    pickle.WriteInt(PortToInt(args[0]));
+    pickle.WriteInt(PortToInt(args[1]));
+  } else {
+    ExitWithUsage();
+  }
+
+  if (kill_server && args.size() > 0)
+    ExitWithUsage();
+
+  ClientDelegate client_delegate(pickle);
+  ServerDelegate daemon_delegate;
+  Daemon daemon(
+      kLogFilePath, kDaemonIdentifier, &client_delegate, &daemon_delegate,
+      &GetExitNotifierFD);
+
+  if (kill_server)
+    return !daemon.Kill();
+  if (!daemon.SpawnIfNeeded())
+    return 1;
+
+  return client_delegate.has_failed() || daemon_delegate.has_failed();
+}
+
+}  // namespace
+}  // namespace forwarder2
+
+int main(int argc, char** argv) {
+  return forwarder2::RunHostForwarder(argc, argv);
+}
diff --git a/tools/android/forwarder2/pipe_notifier.cc b/tools/android/forwarder2/pipe_notifier.cc
new file mode 100644
index 0000000..02842bd
--- /dev/null
+++ b/tools/android/forwarder2/pipe_notifier.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/pipe_notifier.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/safe_strerror_posix.h"
+
+namespace forwarder2 {
+
+PipeNotifier::PipeNotifier() {
+  int pipe_fd[2];
+  int ret = pipe(pipe_fd);
+  CHECK_EQ(0, ret);
+  receiver_fd_ = pipe_fd[0];
+  sender_fd_ = pipe_fd[1];
+  fcntl(sender_fd_, F_SETFL, O_NONBLOCK);
+}
+
+PipeNotifier::~PipeNotifier() {
+  close(receiver_fd_);
+  close(sender_fd_);
+}
+
+bool PipeNotifier::Notify() {
+  CHECK_NE(-1, sender_fd_);
+  errno = 0;
+  int ret = HANDLE_EINTR(write(sender_fd_, "1", 1));
+  if (ret < 0) {
+    PLOG(ERROR) << "write";
+    return false;
+  }
+  return true;
+}
+
+void PipeNotifier::Reset() {
+  char c;
+  int ret = HANDLE_EINTR(read(receiver_fd_, &c, 1));
+  if (ret < 0) {
+    PLOG(ERROR) << "read";
+    return;
+  }
+  DCHECK_EQ(1, ret);
+  DCHECK_EQ('1', c);
+}
+
+}  // namespace forwarder
diff --git a/tools/android/forwarder2/pipe_notifier.h b/tools/android/forwarder2/pipe_notifier.h
new file mode 100644
index 0000000..aadb269
--- /dev/null
+++ b/tools/android/forwarder2/pipe_notifier.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_PIPE_NOTIFIER_H_
+#define TOOLS_ANDROID_FORWARDER2_PIPE_NOTIFIER_H_
+
+#include "base/basictypes.h"
+
+namespace forwarder2 {
+
+// Helper class used to create a unix pipe that sends notifications to the
+// |receiver_fd_| file descriptor when called |Notify()|.  This should be used
+// by the main thread to notify other threads that it must exit.
+// The |receiver_fd_| can be put into a fd_set and used in a select together
+// with a socket waiting to accept or read.
+class PipeNotifier {
+ public:
+  PipeNotifier();
+  ~PipeNotifier();
+
+  bool Notify();
+
+  int receiver_fd() const { return receiver_fd_; }
+
+  void Reset();
+
+ private:
+  int sender_fd_;
+  int receiver_fd_;
+
+  DISALLOW_COPY_AND_ASSIGN(PipeNotifier);
+};
+
+}  // namespace forwarder
+
+#endif  // TOOLS_ANDROID_FORWARDER2_PIPE_NOTIFIER_H_
diff --git a/tools/android/forwarder2/self_deleter_helper.h b/tools/android/forwarder2/self_deleter_helper.h
new file mode 100644
index 0000000..d96903d
--- /dev/null
+++ b/tools/android/forwarder2/self_deleter_helper.h
@@ -0,0 +1,141 @@
+// Copyright 2013 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
+#define TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+
+namespace base {
+
+class SingleThreadTaskRunner;
+
+}  // namespace base
+
+namespace forwarder2 {
+
+// Helper template class to be used in the following case:
+//   * T is the type of an object that implements some work through an internal
+//     or worker thread.
+//   * T wants the internal thread to invoke deletion of its own instance, on
+//     the thread where the instance was created.
+//
+// To make this easier, do something like:
+//   1) Add a SelfDeleteHelper<T> member to your class T, and default-initialize
+//      it in its constructor.
+//   2) In the internal thread, to trigger self-deletion, call the
+//      MaybeDeleteSoon() method on this member.
+//
+// MaybeDeleteSoon() posts a task on the message loop where the T instance was
+// created to delete it. The task will be safely ignored if the instance is
+// otherwise deleted.
+//
+// Usage example:
+// class Object {
+//  public:
+//   typedef base::Callback<void (scoped_ptr<Object>)> ErrorCallback;
+//
+//   Object(const ErrorCallback& error_callback)
+//       : self_deleter_helper_(this, error_callback) {
+//   }
+//
+//   void StartWork() {
+//     // Post a callback to DoSomethingOnWorkerThread() below to another
+//     // thread.
+//   }
+//
+//   void DoSomethingOnWorkerThread() {
+//     ...
+//     if (error_happened)
+//       self_deleter_helper_.MaybeDeleteSoon();
+//   }
+//
+//  private:
+//   SelfDeleterHelper<MySelfDeletingClass> self_deleter_helper_;
+// };
+//
+// class ObjectOwner {
+//  public:
+//   ObjectOwner()
+//      : object_(new Object(base::Bind(&ObjectOwner::DeleteObjectOnError,
+//                                      base::Unretained(this))) {
+//      // To keep this example simple base::Unretained(this) is used above but
+//      // note that in a real world scenario the client would have to make sure
+//      // that the ObjectOwner instance is still alive when
+//      // DeleteObjectOnError() gets called below. This can be achieved by
+//      // using a WeakPtr<ObjectOwner> for instance.
+//   }
+//
+//   void StartWork() {
+//     object_->StartWork();
+//   }
+//
+//  private:
+//   void DeleteObjectOnError(scoped_ptr<Object> object) {
+//     DCHECK(thread_checker_.CalledOnValidThread());
+//     DCHECK_EQ(object_, object);
+//     // Do some extra work with |object| before it gets deleted...
+//     object_.reset();
+//     ignore_result(object.release());
+//   }
+//
+//   base::ThreadChecker thread_checker_;
+//   scoped_ptr<Object> object_;
+// };
+//
+template <typename T>
+class SelfDeleterHelper {
+ public:
+  typedef base::Callback<void (scoped_ptr<T>)> DeletionCallback;
+
+  SelfDeleterHelper(T* self_deleting_object,
+                    const DeletionCallback& deletion_callback)
+      : construction_runner_(base::MessageLoopProxy::current()),
+        self_deleting_object_(self_deleting_object),
+        deletion_callback_(deletion_callback),
+        weak_ptr_factory_(this) {
+  }
+
+  ~SelfDeleterHelper() {
+    DCHECK(construction_runner_->RunsTasksOnCurrentThread());
+  }
+
+  void MaybeSelfDeleteSoon() {
+    DCHECK(!construction_runner_->RunsTasksOnCurrentThread());
+    construction_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&SelfDeleterHelper::SelfDelete,
+                   weak_ptr_factory_.GetWeakPtr()));
+  }
+
+ private:
+  void SelfDelete() {
+    DCHECK(construction_runner_->RunsTasksOnCurrentThread());
+    deletion_callback_.Run(make_scoped_ptr(self_deleting_object_));
+  }
+
+  const scoped_refptr<base::SingleThreadTaskRunner> construction_runner_;
+  T* const self_deleting_object_;
+  const DeletionCallback deletion_callback_;
+
+  //WeakPtrFactory's documentation says:
+  // Member variables should appear before the WeakPtrFactory, to ensure
+  // that any WeakPtrs to Controller are invalidated before its members
+  // variable's destructors are executed, rendering them invalid.
+  base::WeakPtrFactory<SelfDeleterHelper<T> > weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(SelfDeleterHelper);
+};
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_SELF_DELETER_HELPER_H_
diff --git a/tools/android/forwarder2/socket.cc b/tools/android/forwarder2/socket.cc
new file mode 100644
index 0000000..9feac84
--- /dev/null
+++ b/tools/android/forwarder2/socket.cc
@@ -0,0 +1,448 @@
+// Copyright (c) 2012 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 "tools/android/forwarder2/socket.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/safe_strerror_posix.h"
+#include "tools/android/common/net.h"
+#include "tools/android/forwarder2/common.h"
+
+namespace {
+const int kNoTimeout = -1;
+const int kConnectTimeOut = 10;  // Seconds.
+
+bool FamilyIsTCP(int family) {
+  return family == AF_INET || family == AF_INET6;
+}
+}  // namespace
+
+namespace forwarder2 {
+
+bool Socket::BindUnix(const std::string& path) {
+  errno = 0;
+  if (!InitUnixSocket(path) || !BindAndListen()) {
+    Close();
+    return false;
+  }
+  return true;
+}
+
+bool Socket::BindTcp(const std::string& host, int port) {
+  errno = 0;
+  if (!InitTcpSocket(host, port) || !BindAndListen()) {
+    Close();
+    return false;
+  }
+  return true;
+}
+
+bool Socket::ConnectUnix(const std::string& path) {
+  errno = 0;
+  if (!InitUnixSocket(path) || !Connect()) {
+    Close();
+    return false;
+  }
+  return true;
+}
+
+bool Socket::ConnectTcp(const std::string& host, int port) {
+  errno = 0;
+  if (!InitTcpSocket(host, port) || !Connect()) {
+    Close();
+    return false;
+  }
+  return true;
+}
+
+Socket::Socket()
+    : socket_(-1),
+      port_(0),
+      socket_error_(false),
+      family_(AF_INET),
+      addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)),
+      addr_len_(sizeof(sockaddr)) {
+  memset(&addr_, 0, sizeof(addr_));
+}
+
+Socket::~Socket() {
+  Close();
+}
+
+void Socket::Shutdown() {
+  if (!IsClosed()) {
+    PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR));
+  }
+}
+
+void Socket::Close() {
+  if (!IsClosed()) {
+    CloseFD(socket_);
+    socket_ = -1;
+  }
+}
+
+bool Socket::InitSocketInternal() {
+  socket_ = socket(family_, SOCK_STREAM, 0);
+  if (socket_ < 0) {
+    PLOG(ERROR) << "socket";
+    return false;
+  }
+  tools::DisableNagle(socket_);
+  int reuse_addr = 1;
+  setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
+             sizeof(reuse_addr));
+  if (!SetNonBlocking())
+    return false;
+  return true;
+}
+
+bool Socket::SetNonBlocking() {
+  const int flags = fcntl(socket_, F_GETFL);
+  if (flags < 0) {
+    PLOG(ERROR) << "fcntl";
+    return false;
+  }
+  if (flags & O_NONBLOCK)
+    return true;
+  if (fcntl(socket_, F_SETFL, flags | O_NONBLOCK) < 0) {
+    PLOG(ERROR) << "fcntl";
+    return false;
+  }
+  return true;
+}
+
+bool Socket::InitUnixSocket(const std::string& path) {
+  static const size_t kPathMax = sizeof(addr_.addr_un.sun_path);
+  // For abstract sockets we need one extra byte for the leading zero.
+  if (path.size() + 2 /* '\0' */ > kPathMax) {
+    LOG(ERROR) << "The provided path is too big to create a unix "
+               << "domain socket: " << path;
+    return false;
+  }
+  family_ = PF_UNIX;
+  addr_.addr_un.sun_family = family_;
+  // Copied from net/socket/unix_domain_socket_posix.cc
+  // Convert the path given into abstract socket name. It must start with
+  // the '\0' character, so we are adding it. |addr_len| must specify the
+  // length of the structure exactly, as potentially the socket name may
+  // have '\0' characters embedded (although we don't support this).
+  // Note that addr_.addr_un.sun_path is already zero initialized.
+  memcpy(addr_.addr_un.sun_path + 1, path.c_str(), path.size());
+  addr_len_ = path.size() + offsetof(struct sockaddr_un, sun_path) + 1;
+  addr_ptr_ = reinterpret_cast<sockaddr*>(&addr_.addr_un);
+  return InitSocketInternal();
+}
+
+bool Socket::InitTcpSocket(const std::string& host, int port) {
+  port_ = port;
+  if (host.empty()) {
+    // Use localhost: INADDR_LOOPBACK
+    family_ = AF_INET;
+    addr_.addr4.sin_family = family_;
+    addr_.addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  } else if (!Resolve(host)) {
+    return false;
+  }
+  CHECK(FamilyIsTCP(family_)) << "Invalid socket family.";
+  if (family_ == AF_INET) {
+    addr_.addr4.sin_port = htons(port_);
+    addr_ptr_ = reinterpret_cast<sockaddr*>(&addr_.addr4);
+    addr_len_ = sizeof(addr_.addr4);
+  } else if (family_ == AF_INET6) {
+    addr_.addr6.sin6_port = htons(port_);
+    addr_ptr_ = reinterpret_cast<sockaddr*>(&addr_.addr6);
+    addr_len_ = sizeof(addr_.addr6);
+  }
+  return InitSocketInternal();
+}
+
+bool Socket::BindAndListen() {
+  errno = 0;
+  if (HANDLE_EINTR(bind(socket_, addr_ptr_, addr_len_)) < 0 ||
+      HANDLE_EINTR(listen(socket_, SOMAXCONN)) < 0) {
+    PLOG(ERROR) << "bind/listen";
+    SetSocketError();
+    return false;
+  }
+  if (port_ == 0 && FamilyIsTCP(family_)) {
+    SockAddr addr;
+    memset(&addr, 0, sizeof(addr));
+    socklen_t addrlen = 0;
+    sockaddr* addr_ptr = NULL;
+    uint16* port_ptr = NULL;
+    if (family_ == AF_INET) {
+      addr_ptr = reinterpret_cast<sockaddr*>(&addr.addr4);
+      port_ptr = &addr.addr4.sin_port;
+      addrlen = sizeof(addr.addr4);
+    } else if (family_ == AF_INET6) {
+      addr_ptr = reinterpret_cast<sockaddr*>(&addr.addr6);
+      port_ptr = &addr.addr6.sin6_port;
+      addrlen = sizeof(addr.addr6);
+    }
+    errno = 0;
+    if (getsockname(socket_, addr_ptr, &addrlen) != 0) {
+      PLOG(ERROR) << "getsockname";
+      SetSocketError();
+      return false;
+    }
+    port_ = ntohs(*port_ptr);
+  }
+  return true;
+}
+
+bool Socket::Accept(Socket* new_socket) {
+  DCHECK(new_socket != NULL);
+  if (!WaitForEvent(READ, kNoTimeout)) {
+    SetSocketError();
+    return false;
+  }
+  errno = 0;
+  int new_socket_fd = HANDLE_EINTR(accept(socket_, NULL, NULL));
+  if (new_socket_fd < 0) {
+    SetSocketError();
+    return false;
+  }
+  tools::DisableNagle(new_socket_fd);
+  new_socket->socket_ = new_socket_fd;
+  if (!new_socket->SetNonBlocking())
+    return false;
+  return true;
+}
+
+bool Socket::Connect() {
+  DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
+  errno = 0;
+  if (HANDLE_EINTR(connect(socket_, addr_ptr_, addr_len_)) < 0 &&
+      errno != EINPROGRESS) {
+    SetSocketError();
+    return false;
+  }
+  // Wait for connection to complete, or receive a notification.
+  if (!WaitForEvent(WRITE, kConnectTimeOut)) {
+    SetSocketError();
+    return false;
+  }
+  int socket_errno;
+  socklen_t opt_len = sizeof(socket_errno);
+  if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &socket_errno, &opt_len) < 0) {
+    PLOG(ERROR) << "getsockopt()";
+    SetSocketError();
+    return false;
+  }
+  if (socket_errno != 0) {
+    LOG(ERROR) << "Could not connect to host: " << safe_strerror(socket_errno);
+    SetSocketError();
+    return false;
+  }
+  return true;
+}
+
+bool Socket::Resolve(const std::string& host) {
+  struct addrinfo hints;
+  struct addrinfo* res;
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags |= AI_CANONNAME;
+
+  int errcode = getaddrinfo(host.c_str(), NULL, &hints, &res);
+  if (errcode != 0) {
+    errno = 0;
+    SetSocketError();
+    freeaddrinfo(res);
+    return false;
+  }
+  family_ = res->ai_family;
+  switch (res->ai_family) {
+    case AF_INET:
+      memcpy(&addr_.addr4,
+             reinterpret_cast<sockaddr_in*>(res->ai_addr),
+             sizeof(sockaddr_in));
+      break;
+    case AF_INET6:
+      memcpy(&addr_.addr6,
+             reinterpret_cast<sockaddr_in6*>(res->ai_addr),
+             sizeof(sockaddr_in6));
+      break;
+  }
+  freeaddrinfo(res);
+  return true;
+}
+
+int Socket::GetPort() {
+  if (!FamilyIsTCP(family_)) {
+    LOG(ERROR) << "Can't call GetPort() on an unix domain socket.";
+    return 0;
+  }
+  return port_;
+}
+
+int Socket::ReadNumBytes(void* buffer, size_t num_bytes) {
+  int bytes_read = 0;
+  int ret = 1;
+  while (bytes_read < num_bytes && ret > 0) {
+    ret = Read(static_cast<char*>(buffer) + bytes_read, num_bytes - bytes_read);
+    if (ret >= 0)
+      bytes_read += ret;
+  }
+  return bytes_read;
+}
+
+void Socket::SetSocketError() {
+  socket_error_ = true;
+  DCHECK_NE(EAGAIN, errno);
+  DCHECK_NE(EWOULDBLOCK, errno);
+  Close();
+}
+
+int Socket::Read(void* buffer, size_t buffer_size) {
+  if (!WaitForEvent(READ, kNoTimeout)) {
+    SetSocketError();
+    return 0;
+  }
+  int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size));
+  if (ret < 0) {
+    PLOG(ERROR) << "read";
+    SetSocketError();
+  }
+  return ret;
+}
+
+int Socket::NonBlockingRead(void* buffer, size_t buffer_size) {
+  DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
+  int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size));
+  if (ret < 0) {
+    PLOG(ERROR) << "read";
+    SetSocketError();
+  }
+  return ret;
+}
+
+int Socket::Write(const void* buffer, size_t count) {
+  if (!WaitForEvent(WRITE, kNoTimeout)) {
+    SetSocketError();
+    return 0;
+  }
+  int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL));
+  if (ret < 0) {
+    PLOG(ERROR) << "send";
+    SetSocketError();
+  }
+  return ret;
+}
+
+int Socket::NonBlockingWrite(const void* buffer, size_t count) {
+  DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
+  int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL));
+  if (ret < 0) {
+    PLOG(ERROR) << "send";
+    SetSocketError();
+  }
+  return ret;
+}
+
+int Socket::WriteString(const std::string& buffer) {
+  return WriteNumBytes(buffer.c_str(), buffer.size());
+}
+
+void Socket::AddEventFd(int event_fd) {
+  Event event;
+  event.fd = event_fd;
+  event.was_fired = false;
+  events_.push_back(event);
+}
+
+bool Socket::DidReceiveEventOnFd(int fd) const {
+  for (size_t i = 0; i < events_.size(); ++i)
+    if (events_[i].fd == fd)
+      return events_[i].was_fired;
+  return false;
+}
+
+bool Socket::DidReceiveEvent() const {
+  for (size_t i = 0; i < events_.size(); ++i)
+    if (events_[i].was_fired)
+      return true;
+  return false;
+}
+
+int Socket::WriteNumBytes(const void* buffer, size_t num_bytes) {
+  int bytes_written = 0;
+  int ret = 1;
+  while (bytes_written < num_bytes && ret > 0) {
+    ret = Write(static_cast<const char*>(buffer) + bytes_written,
+                num_bytes - bytes_written);
+    if (ret >= 0)
+      bytes_written += ret;
+  }
+  return bytes_written;
+}
+
+bool Socket::WaitForEvent(EventType type, int timeout_secs) {
+  if (socket_ == -1)
+    return true;
+  DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
+  fd_set read_fds;
+  fd_set write_fds;
+  FD_ZERO(&read_fds);
+  FD_ZERO(&write_fds);
+  if (type == READ)
+    FD_SET(socket_, &read_fds);
+  else
+    FD_SET(socket_, &write_fds);
+  for (size_t i = 0; i < events_.size(); ++i)
+    FD_SET(events_[i].fd, &read_fds);
+  timeval tv = {};
+  timeval* tv_ptr = NULL;
+  if (timeout_secs > 0) {
+    tv.tv_sec = timeout_secs;
+    tv.tv_usec = 0;
+    tv_ptr = &tv;
+  }
+  int max_fd = socket_;
+  for (size_t i = 0; i < events_.size(); ++i)
+    if (events_[i].fd > max_fd)
+      max_fd = events_[i].fd;
+  if (HANDLE_EINTR(
+          select(max_fd + 1, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) {
+    PLOG(ERROR) << "select";
+    return false;
+  }
+  bool event_was_fired = false;
+  for (size_t i = 0; i < events_.size(); ++i) {
+    if (FD_ISSET(events_[i].fd, &read_fds)) {
+      events_[i].was_fired = true;
+      event_was_fired = true;
+    }
+  }
+  return !event_was_fired;
+}
+
+// static
+pid_t Socket::GetUnixDomainSocketProcessOwner(const std::string& path) {
+  Socket socket;
+  if (!socket.ConnectUnix(path))
+    return -1;
+  ucred ucred;
+  socklen_t len = sizeof(ucred);
+  if (getsockopt(socket.socket_, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
+    CHECK_NE(ENOPROTOOPT, errno);
+    return -1;
+  }
+  return ucred.pid;
+}
+
+}  // namespace forwarder2
diff --git a/tools/android/forwarder2/socket.h b/tools/android/forwarder2/socket.h
new file mode 100644
index 0000000..6047a1c
--- /dev/null
+++ b/tools/android/forwarder2/socket.h
@@ -0,0 +1,152 @@
+// Copyright (c) 2012 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_SOCKET_H_
+#define TOOLS_ANDROID_FORWARDER2_SOCKET_H_
+
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+
+namespace forwarder2 {
+
+// Wrapper class around unix socket api.  Can be used to create, bind or
+// connect to both Unix domain sockets and TCP sockets.
+// TODO(pliard): Split this class into TCPSocket and UnixDomainSocket.
+class Socket {
+ public:
+  Socket();
+  ~Socket();
+
+  bool BindUnix(const std::string& path);
+  bool BindTcp(const std::string& host, int port);
+  bool ConnectUnix(const std::string& path);
+  bool ConnectTcp(const std::string& host, int port);
+
+  // Just a wrapper around unix socket shutdown(), see man 2 shutdown.
+  void Shutdown();
+
+  // Just a wrapper around unix socket close(), see man 2 close.
+  void Close();
+  bool IsClosed() const { return socket_ < 0; }
+
+  int fd() const { return socket_; }
+
+  bool Accept(Socket* new_socket);
+
+  // Returns the port allocated to this socket or zero on error.
+  int GetPort();
+
+  // Just a wrapper around unix read() function.
+  // Reads up to buffer_size, but may read less then buffer_size.
+  // Returns the number of bytes read.
+  int Read(void* buffer, size_t buffer_size);
+
+  // Non-blocking version of Read() above. This must be called after a
+  // successful call to select(). The socket must also be in non-blocking mode
+  // before calling this method.
+  int NonBlockingRead(void* buffer, size_t buffer_size);
+
+  // Wrapper around send().
+  int Write(const void* buffer, size_t count);
+
+  // Same as NonBlockingRead() but for writing.
+  int NonBlockingWrite(const void* buffer, size_t count);
+
+  // Calls Read() multiple times until num_bytes is written to the provided
+  // buffer. No bounds checking is performed.
+  // Returns number of bytes read, which can be different from num_bytes in case
+  // of errror.
+  int ReadNumBytes(void* buffer, size_t num_bytes);
+
+  // Calls Write() multiple times until num_bytes is written. No bounds checking
+  // is performed. Returns number of bytes written, which can be different from
+  // num_bytes in case of errror.
+  int WriteNumBytes(const void* buffer, size_t num_bytes);
+
+  // Calls WriteNumBytes for the given std::string. Note that the null
+  // terminator is not written to the socket.
+  int WriteString(const std::string& buffer);
+
+  bool has_error() const { return socket_error_; }
+
+  // |event_fd| must be a valid pipe file descriptor created from the
+  // PipeNotifier and must live (not be closed) at least as long as this socket
+  // is alive.
+  void AddEventFd(int event_fd);
+
+  // Returns whether Accept() or Connect() was interrupted because the socket
+  // received an external event fired through the provided fd.
+  bool DidReceiveEventOnFd(int fd) const;
+
+  bool DidReceiveEvent() const;
+
+  static pid_t GetUnixDomainSocketProcessOwner(const std::string& path);
+
+ private:
+  enum EventType {
+    READ,
+    WRITE
+  };
+
+  union SockAddr {
+    // IPv4 sockaddr
+    sockaddr_in addr4;
+    // IPv6 sockaddr
+    sockaddr_in6 addr6;
+    // Unix Domain sockaddr
+    sockaddr_un addr_un;
+  };
+
+  struct Event {
+    int fd;
+    bool was_fired;
+  };
+
+  bool SetNonBlocking();
+
+  // If |host| is empty, use localhost.
+  bool InitTcpSocket(const std::string& host, int port);
+  bool InitUnixSocket(const std::string& path);
+  bool BindAndListen();
+  bool Connect();
+
+  bool Resolve(const std::string& host);
+  bool InitSocketInternal();
+  void SetSocketError();
+
+  // Waits until either the Socket or the |exit_notifier_fd_| has received an
+  // event.
+  bool WaitForEvent(EventType type, int timeout_secs);
+
+  int socket_;
+  int port_;
+  bool socket_error_;
+
+  // Family of the socket (PF_INET, PF_INET6 or PF_UNIX).
+  int family_;
+
+  SockAddr addr_;
+
+  // Points to one of the members of the above union depending on the family.
+  sockaddr* addr_ptr_;
+  // Length of one of the members of the above union depending on the family.
+  socklen_t addr_len_;
+
+  // Used to listen for external events (e.g. process received a SIGTERM) while
+  // blocking on I/O operations.
+  std::vector<Event> events_;
+
+  DISALLOW_COPY_AND_ASSIGN(Socket);
+};
+
+}  // namespace forwarder
+
+#endif  // TOOLS_ANDROID_FORWARDER2_SOCKET_H_
diff --git a/tools/android/forwarder2/util.h b/tools/android/forwarder2/util.h
new file mode 100644
index 0000000..9947628
--- /dev/null
+++ b/tools/android/forwarder2/util.h
@@ -0,0 +1,36 @@
+// Copyright 2013 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.
+
+#ifndef TOOLS_ANDROID_FORWARDER2_UTIL_H_
+#define TOOLS_ANDROID_FORWARDER2_UTIL_H_
+
+#include "base/logging.h"
+
+namespace forwarder2 {
+
+// Safely deletes a ref-counted value in a provided map by unlinking the object
+// from the map before deleting it in case its destructor would access the map.
+// Deletion will only happen by definition if the object's refcount is set to 1
+// before this function gets called. Returns whether the element could be found
+// in the map.
+template <typename Map, typename K>
+bool DeleteRefCountedValueInMap(const K& key, Map* map) {
+  const typename Map::iterator it = map->find(key);
+  if (it == map->end())
+    return false;
+  DeleteRefCountedValueInMapFromIterator(it, map);
+  return true;
+}
+
+// See DeleteRefCountedValuetInMap() above.
+template <typename Map, typename Iterator>
+void DeleteRefCountedValueInMapFromIterator(Iterator it, Map* map) {
+  DCHECK(it != map->end());
+  const typename Map::value_type::second_type shared_ptr_copy = it->second;
+  map->erase(it);
+}
+
+}  // namespace forwarder2
+
+#endif  // TOOLS_ANDROID_FORWARDER2_UTIL_H_