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) { |