| Index: tools/android/forwarder2/host_forwarder_main.cc
|
| diff --git a/tools/android/forwarder2/host_forwarder_main.cc b/tools/android/forwarder2/host_forwarder_main.cc
|
| index f14583275011646139c89cfaedb090a7dd5a3643..31b76299358dd9e40ffcdfcf14285981688abe58 100644
|
| --- a/tools/android/forwarder2/host_forwarder_main.cc
|
| +++ b/tools/android/forwarder2/host_forwarder_main.cc
|
| @@ -9,13 +9,16 @@
|
| #include <cstdio>
|
| #include <cstring>
|
| #include <string>
|
| +#include <utility>
|
| #include <vector>
|
|
|
| #include "base/command_line.h"
|
| #include "base/compiler_specific.h"
|
| #include "base/file_util.h"
|
| #include "base/files/file_path.h"
|
| +#include "base/hash_tables.h"
|
| #include "base/logging.h"
|
| +#include "base/memory/linked_ptr.h"
|
| #include "base/memory/scoped_vector.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| #include "base/safe_strerror_posix.h"
|
| @@ -122,7 +125,7 @@ class ServerDelegate : public Daemon::ServerDelegate {
|
| char buf[kBufSize];
|
| const int bytes_read = client_socket->Read(buf, sizeof(buf));
|
| if (bytes_read <= 0) {
|
| - if (client_socket->exited())
|
| + if (client_socket->DidReceiveEvent())
|
| return;
|
| PError("Read()");
|
| has_failed_ = true;
|
| @@ -137,35 +140,53 @@ class ServerDelegate : public Daemon::ServerDelegate {
|
| command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
|
| if (!succeeded) {
|
| has_failed_ = true;
|
| - client_socket->WriteString(
|
| - base::StringPrintf("ERROR: Could not parse forward command '%s'",
|
| - command.c_str()));
|
| + const std::string msg = base::StringPrintf(
|
| + "ERROR: Could not parse forward command '%s'", command.c_str());
|
| + SendMessage(msg, 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 HostControllerMap::size_type removed_elements = controllers_.erase(
|
| + controller_key);
|
| + SendMessage(
|
| + !removed_elements ? "ERROR: could not unmap port" : "OK",
|
| + client_socket.get());
|
| + return;
|
| + }
|
| + // Create a new host controller.
|
| scoped_ptr<HostController> host_controller(
|
| new HostController(device_port, forward_to_host, forward_to_port,
|
| adb_port, GetExitNotifierFD()));
|
| if (!host_controller->Connect()) {
|
| has_failed_ = true;
|
| - client_socket->WriteString("ERROR: Connection to device failed.");
|
| + 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 "
|
| << forward_to_host << ":" << forward_to_port;
|
| - if (!client_socket->WriteString(
|
| - base::StringPrintf("%d:%d", device_port, forward_to_port))) {
|
| - has_failed_ = true;
|
| + const std::string msg = base::StringPrintf(
|
| + "%d:%d", device_port, forward_to_port);
|
| + if (!SendMessage(msg, client_socket.get()))
|
| return;
|
| - }
|
| host_controller->Start();
|
| - controllers_.push_back(host_controller.release());
|
| + const std::string controller_key = MakeHostControllerMapKey(
|
| + adb_port, device_port);
|
| + controllers_.insert(
|
| + std::make_pair(controller_key,
|
| + linked_ptr<HostController>(host_controller.release())));
|
| }
|
|
|
| virtual void OnServerExited() OVERRIDE {
|
| - for (int i = 0; i < controllers_.size(); ++i)
|
| - controllers_[i]->Join();
|
| + for (HostControllerMap::iterator it = controllers_.begin();
|
| + it != controllers_.end(); ++it) {
|
| + linked_ptr<HostController> host_controller = it->second;
|
| + host_controller->Join();
|
| + }
|
| if (controllers_.size() == 0) {
|
| LOG(ERROR) << "No forwarder servers could be started. Exiting.";
|
| has_failed_ = true;
|
| @@ -173,7 +194,22 @@ class ServerDelegate : public Daemon::ServerDelegate {
|
| }
|
|
|
| private:
|
| - ScopedVector<HostController> controllers_;
|
| + 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);
|
| + }
|
| +
|
| + bool SendMessage(const std::string& msg, Socket* client_socket) {
|
| + bool result = client_socket->WriteString(msg);
|
| + DCHECK(result);
|
| + if (!result)
|
| + has_failed_ = true;
|
| + return result;
|
| + }
|
| +
|
| + HostControllerMap controllers_;
|
| bool has_failed_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ServerDelegate);
|
| @@ -213,8 +249,10 @@ class ClientDelegate : public Daemon::ClientDelegate {
|
| };
|
|
|
| void PrintUsage(const char* program_name) {
|
| - LOG(ERROR) << program_name << " adb_port:from_port:to_port:to_host\n"
|
| - "<adb port> is the TCP port Adb is configured to forward to.";
|
| + LOG(ERROR) << program_name
|
| + << " adb_port:from_port:to_port:to_host\n"
|
| + "<adb port> is the TCP port Adb is configured to forward to.\n"
|
| + "Note that <from_port> can be unmapped by making it negative.";
|
| }
|
|
|
| int RunHostForwarder(int argc, char** argv) {
|
|
|