summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-03 10:21:26 +0000
committerpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-03 10:21:26 +0000
commitd47d11d525fe4de37b7812528875347c38ca4f83 (patch)
tree7cdfe0b010257da97257974c35473279b39fe8ac /tools
parenta2463666b3e88f018d42b321efee3cac2f419bd1 (diff)
downloadchromium_src-d47d11d525fe4de37b7812528875347c38ca4f83.zip
chromium_src-d47d11d525fe4de37b7812528875347c38ca4f83.tar.gz
chromium_src-d47d11d525fe4de37b7812528875347c38ca4f83.tar.bz2
Add --serial-id option to host_forwarder.
This moves the forwarder's control channel set up logic (which can be considered as an internal implementation detail) from the Python script to the host_forwarder binary. This also changes the command line interface for the host_forwarder and device_forwarder binaries. BUG=242846 R=bulach@chromium.org, digit@chromium.org Review URL: https://codereview.chromium.org/18354005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209945 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
-rw-r--r--tools/android/forwarder2/device_forwarder_main.cc68
-rw-r--r--tools/android/forwarder2/host_forwarder_main.cc191
2 files changed, 127 insertions, 132 deletions
diff --git a/tools/android/forwarder2/device_forwarder_main.cc b/tools/android/forwarder2/device_forwarder_main.cc
index f822d28..26904b4 100644
--- a/tools/android/forwarder2/device_forwarder_main.cc
+++ b/tools/android/forwarder2/device_forwarder_main.cc
@@ -3,9 +3,9 @@
// found in the LICENSE file.
#include <signal.h>
-#include <stdio.h>
#include <stdlib.h>
+#include <iostream>
#include <string>
#include "base/at_exit.h"
@@ -29,11 +29,9 @@ forwarder2::PipeNotifier* g_notifier = NULL;
const int kBufSize = 256;
+const char kUnixDomainSocketPath[] = "chrome_device_forwarder";
const char kDaemonIdentifier[] = "chrome_device_forwarder_daemon";
-const char kKillServerCommand[] = "kill-server";
-const char kStartCommand[] = "start";
-
void KillHandler(int /* unused */) {
CHECK(g_notifier);
if (!g_notifier->Notify())
@@ -48,6 +46,8 @@ int GetExitNotifierFD() {
class ServerDelegate : public Daemon::ServerDelegate {
public:
+ ServerDelegate() : initialized_(false) {}
+
// Daemon::ServerDelegate:
virtual void Init() OVERRIDE {
DCHECK(!g_notifier);
@@ -59,45 +59,28 @@ class ServerDelegate : public Daemon::ServerDelegate {
}
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()");
- return;
- }
- const std::string adb_socket_path(buf, bytes_read);
- if (adb_socket_path == adb_socket_path_) {
+ if (initialized_) {
client_socket->WriteString("OK");
return;
}
- if (!adb_socket_path_.empty()) {
- client_socket->WriteString(
- base::StringPrintf(
- "ERROR: Device controller already running (adb_socket_path=%s)",
- adb_socket_path_.c_str()));
- return;
- }
- adb_socket_path_ = adb_socket_path;
controller_thread_->message_loop()->PostTask(
FROM_HERE,
- base::Bind(&ServerDelegate::StartController, adb_socket_path,
- GetExitNotifierFD(), base::Passed(&client_socket)));
+ base::Bind(&ServerDelegate::StartController, GetExitNotifierFD(),
+ base::Passed(&client_socket)));
+ initialized_ = true;
}
virtual void OnServerExited() OVERRIDE {}
private:
- static void StartController(const std::string& adb_socket_path,
- int exit_notifier_fd,
+ static void StartController(int exit_notifier_fd,
scoped_ptr<Socket> client_socket) {
forwarder2::DeviceController controller(exit_notifier_fd);
- if (!controller.Init(adb_socket_path)) {
+ if (!controller.Init(kUnixDomainSocketPath)) {
client_socket->WriteString(
base::StringPrintf("ERROR: Could not initialize device controller "
"with ADB socket path: %s",
- adb_socket_path.c_str()));
+ kUnixDomainSocketPath));
return;
}
client_socket->WriteString("OK");
@@ -110,23 +93,17 @@ class ServerDelegate : public Daemon::ServerDelegate {
base::AtExitManager at_exit_manager_; // Used by base::Thread.
scoped_ptr<base::Thread> controller_thread_;
- std::string adb_socket_path_;
+ bool initialized_;
};
class ClientDelegate : public Daemon::ClientDelegate {
public:
- ClientDelegate(const std::string& adb_socket)
- : adb_socket_(adb_socket),
- has_failed_(false) {
- }
+ ClientDelegate() : has_failed_(false) {}
bool has_failed() const { return has_failed_; }
// Daemon::ClientDelegate:
virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
- // Send the adb socket path to the daemon.
- CHECK(daemon_socket->Write(adb_socket_.c_str(),
- adb_socket_.length()));
char buf[kBufSize];
const int bytes_read = daemon_socket->Read(
buf, sizeof(buf) - 1 /* leave space for null terminator */);
@@ -142,31 +119,26 @@ class ClientDelegate : public Daemon::ClientDelegate {
}
private:
- const std::string adb_socket_;
bool has_failed_;
};
int RunDeviceForwarder(int argc, char** argv) {
- if (argc != 2) {
- fprintf(stderr,
- "Usage: %s kill-server|<adb_socket>\n"
- " <adb_socket> is the abstract Unix Domain Socket path "
- "where Adb is configured to forward from.\n", argv[0]);
+ 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;
}
- CommandLine::Init(argc, argv); // Needed by logging.
- const char* const command =
- !strcmp(argv[1], kKillServerCommand) ? kKillServerCommand : kStartCommand;
- ClientDelegate client_delegate(argv[1]);
+ ClientDelegate client_delegate;
ServerDelegate daemon_delegate;
const char kLogFilePath[] = ""; // Log to logcat.
Daemon daemon(kLogFilePath, kDaemonIdentifier, &client_delegate,
&daemon_delegate, &GetExitNotifierFD);
- if (command == kKillServerCommand)
+ if (kill_server)
return !daemon.Kill();
- DCHECK(command == kStartCommand);
if (!daemon.SpawnIfNeeded())
return 1;
return client_delegate.has_failed();
diff --git a/tools/android/forwarder2/host_forwarder_main.cc b/tools/android/forwarder2/host_forwarder_main.cc
index 0f0ca68..82bb7a8 100644
--- a/tools/android/forwarder2/host_forwarder_main.cc
+++ b/tools/android/forwarder2/host_forwarder_main.cc
@@ -4,10 +4,13 @@
#include <errno.h>
#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <cstdio>
-#include <cstring>
+#include <iostream>
+#include <limits>
#include <string>
#include <utility>
#include <vector>
@@ -20,6 +23,7 @@
#include "base/logging.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_vector.h"
+#include "base/pickle.h"
#include "base/posix/eintr_wrapper.h"
#include "base/safe_strerror_posix.h"
#include "base/strings/string_number_conversions.h"
@@ -72,40 +76,6 @@ void KillHandler(int signal_number) {
exit(1);
}
-// Format of |command|:
-// <ADB port>:<Device port>[:<Forward to port>:<Forward to address>].
-bool ParseForwardCommand(const std::string& command,
- int* adb_port,
- int* device_port,
- std::string* forward_to_host,
- int* forward_to_port) {
- std::vector<std::string> command_pieces;
- base::SplitString(command, ':', &command_pieces);
-
- if (command_pieces.size() < 2 ||
- !base::StringToInt(command_pieces[0], adb_port) ||
- !base::StringToInt(command_pieces[1], device_port))
- return false;
-
- if (command_pieces.size() > 2) {
- if (!base::StringToInt(command_pieces[2], forward_to_port))
- return false;
- if (command_pieces.size() > 3)
- *forward_to_host = command_pieces[3];
- } else {
- *forward_to_port = *device_port;
- }
- return true;
-}
-
-bool IsForwardCommandValid(const std::string& command) {
- int adb_port, device_port, forward_to_port;
- std::string forward_to_host;
- std::vector<std::string> command_pieces;
- return ParseForwardCommand(
- command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
-}
-
class ServerDelegate : public Daemon::ServerDelegate {
public:
ServerDelegate() : has_failed_(false) {}
@@ -131,18 +101,21 @@ class ServerDelegate : public Daemon::ServerDelegate {
has_failed_ = true;
return;
}
- const std::string command(buf, bytes_read);
- int adb_port = 0;
- int device_port = 0;
- std::string forward_to_host;
- int forward_to_port = 0;
- const bool succeeded = ParseForwardCommand(
- command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
- if (!succeeded) {
- has_failed_ = true;
- const std::string msg = base::StringPrintf(
- "ERROR: Could not parse forward command '%s'", command.c_str());
- SendMessage(msg, client_socket.get());
+ 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)) {
+ SendMessage("ERROR: missing device port", client_socket.get());
+ return;
+ }
+ 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) {
@@ -156,10 +129,15 @@ class ServerDelegate : public Daemon::ServerDelegate {
client_socket.get());
return;
}
+ int host_port;
+ if (!pickle_it.ReadInt(&host_port)) {
+ SendMessage("ERROR: missing host port", 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()));
+ new HostController(device_port, "127.0.0.1", host_port, adb_port,
+ GetExitNotifierFD()));
if (!host_controller->Connect()) {
has_failed_ = true;
SendMessage("ERROR: Connection to device failed.", client_socket.get());
@@ -167,10 +145,9 @@ class ServerDelegate : public Daemon::ServerDelegate {
}
// 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;
- const std::string msg = base::StringPrintf(
- "%d:%d", device_port, forward_to_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();
@@ -201,6 +178,29 @@ class ServerDelegate : public Daemon::ServerDelegate {
return base::StringPrintf("%d:%d", adb_port, device_port);
}
+ 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",
+ device_serial.empty() ? "" : 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);
@@ -209,6 +209,7 @@ class ServerDelegate : public Daemon::ServerDelegate {
return result;
}
+ base::hash_map<std::string, int> device_serial_to_adb_port_map_;
HostControllerMap controllers_;
bool has_failed_;
@@ -217,8 +218,8 @@ class ServerDelegate : public Daemon::ServerDelegate {
class ClientDelegate : public Daemon::ClientDelegate {
public:
- ClientDelegate(const std::string& forward_command)
- : forward_command_(forward_command),
+ ClientDelegate(const Pickle& command_pickle)
+ : command_pickle_(command_pickle),
has_failed_(false) {
}
@@ -227,7 +228,9 @@ class ClientDelegate : public Daemon::ClientDelegate {
// Daemon::ClientDelegate:
virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
// Send the forward command to the daemon.
- CHECK(daemon_socket->WriteString(forward_command_));
+ 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 */);
@@ -244,49 +247,69 @@ class ClientDelegate : public Daemon::ClientDelegate {
}
private:
- const std::string forward_command_;
+ const Pickle command_pickle_;
bool has_failed_;
};
-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.\n"
- "Note that <from_port> can be unmapped by making it negative.";
+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 RunHostForwarder(int argc, char** argv) {
- if (!CommandLine::Init(argc, argv)) {
- LOG(ERROR) << "Could not initialize command line";
- return 1;
- }
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- const char* command = NULL;
- int adb_port = 0;
- if (argc != 2) {
- PrintUsage(argv[0]);
- return 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();
}
- if (!strcmp(argv[1], kKillServerCommand)) {
- command = kKillServerCommand;
+ 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 {
- command = kForwardCommand;
- if (!IsForwardCommandValid(argv[1])) {
- PrintUsage(argv[0]);
- return 1;
- }
+ ExitWithUsage();
}
- ClientDelegate client_delegate(argv[1]);
+ if (kill_server && args.size() > 0)
+ ExitWithUsage();
+
+ ClientDelegate client_delegate(pickle);
ServerDelegate daemon_delegate;
Daemon daemon(
kLogFilePath, kDaemonIdentifier, &client_delegate, &daemon_delegate,
&GetExitNotifierFD);
- if (command == kKillServerCommand)
+ if (kill_server)
return !daemon.Kill();
-
- DCHECK(command == kForwardCommand);
if (!daemon.SpawnIfNeeded())
return 1;