summaryrefslogtreecommitdiffstats
path: root/tools/android
diff options
context:
space:
mode:
authorfelipeg@chromium.org <felipeg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-12 16:37:38 +0000
committerfelipeg@chromium.org <felipeg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-12 16:37:38 +0000
commit51f78ce519b229882e5515cae6febe47dbab8c5d (patch)
tree5b4ca899d9675b148f3267232bfc01b9c5dc931d /tools/android
parentaccdb8daf92d3375a2e6a49b688d4f7e4e45429b (diff)
downloadchromium_src-51f78ce519b229882e5515cae6febe47dbab8c5d.zip
chromium_src-51f78ce519b229882e5515cae6febe47dbab8c5d.tar.gz
chromium_src-51f78ce519b229882e5515cae6febe47dbab8c5d.tar.bz2
Add DeviceController and device_forwarder_main to Forwarder2.
The big picture CL can be seem here: https://chromiumcodereview.appspot.com/10918057/ BUG=146502 Review URL: https://chromiumcodereview.appspot.com/10919213 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156311 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/android')
-rw-r--r--tools/android/forwarder2/device_controller.cc120
-rw-r--r--tools/android/forwarder2/device_controller.h45
-rw-r--r--tools/android/forwarder2/device_forwarder_main.cc60
-rw-r--r--tools/android/forwarder2/forwarder.gyp1
4 files changed, 224 insertions, 2 deletions
diff --git a/tools/android/forwarder2/device_controller.cc b/tools/android/forwarder2/device_controller.cc
new file mode 100644
index 0000000..e0effb8
--- /dev/null
+++ b/tools/android/forwarder2/device_controller.cc
@@ -0,0 +1,120 @@
+// 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 <errno.h>
+#include <stdlib.h>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/safe_strerror_posix.h"
+#include "tools/android/forwarder2/command.h"
+#include "tools/android/forwarder2/device_listener.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+DeviceController::DeviceController(int exit_notifier_fd)
+ : exit_notifier_fd_(exit_notifier_fd) {
+ kickstart_adb_socket_.set_exit_notifier_fd(exit_notifier_fd);
+}
+
+DeviceController::~DeviceController() {
+ KillAllListeners();
+ CleanUpDeadListeners();
+ CHECK_EQ(0, listeners_.size());
+}
+
+void DeviceController::CleanUpDeadListeners() {
+ // Clean up dead listeners.
+ for (ListenersMap::iterator it(&listeners_); !it.IsAtEnd(); it.Advance()) {
+ if (!it.GetCurrentValue()->is_alive())
+ // Remove deletes the listener.
+ listeners_.Remove(it.GetCurrentKey());
+ }
+}
+
+void DeviceController::KillAllListeners() {
+ for (ListenersMap::iterator it(&listeners_); !it.IsAtEnd(); it.Advance())
+ it.GetCurrentValue()->ForceExit();
+ for (ListenersMap::iterator it(&listeners_); !it.IsAtEnd(); it.Advance()) {
+ it.GetCurrentValue()->Join();
+ CHECK(!it.GetCurrentValue()->is_alive());
+ }
+}
+
+bool DeviceController::Start(const std::string& adb_unix_socket) {
+ if (!kickstart_adb_socket_.BindUnix(adb_unix_socket,
+ true /* abstract */)) {
+ LOG(ERROR) << "Could not BindAndListen DeviceController socket on port: "
+ << adb_unix_socket;
+ return false;
+ }
+ while (true) {
+ CleanUpDeadListeners();
+ scoped_ptr<Socket> socket(new Socket);
+ if (!kickstart_adb_socket_.Accept(socket.get())) {
+ LOG(ERROR) << "Could not Accept DeviceController socket: "
+ << safe_strerror(errno);
+ break;
+ }
+ // So that |socket| doesn't block on read if it has notifications.
+ socket->set_exit_notifier_fd(exit_notifier_fd_);
+ int port;
+ command::Type command;
+ if (!ReadCommand(socket.get(), &port, &command)) {
+ LOG(ERROR) << "Invalid command received.";
+ socket->Close();
+ continue;
+ }
+ DeviceListener* listener = listeners_.Lookup(port);
+ switch (command) {
+ case command::LISTEN: {
+ if (listener != NULL) {
+ LOG(WARNING) << "Already forwarding port " << port
+ << ". Attempting to restart the listener.\n";
+ listener->ForceExit();
+ listener->Join();
+ CHECK(!listener->is_alive());
+ // Remove deletes the listener object.
+ listeners_.Remove(port);
+ }
+ // Listener object will be deleted by the CleanUpDeadListeners method.
+ DeviceListener* new_listener = new DeviceListener(socket.Pass(), port);
+ listeners_.AddWithID(new_listener, port);
+ new_listener->Start();
+ 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.
+ socket->Close();
+ continue;
+ } else if (!listener->SetAdbDataSocket(socket.Pass())) {
+ LOG(ERROR) << "Could not set Adb Data Socket for port: " << port;
+ // Same assumption as above, but in this case the socket is closed
+ // inside SetAdbDataSocket.
+ continue;
+ }
+ break;
+ default:
+ // TODO(felipeg): add a KillAllListeners command.
+ LOG(ERROR) << "Invalid command received. Port: " << port
+ << " Command: " << command;
+ socket->Close();
+ continue;
+ break;
+ }
+ }
+ KillAllListeners();
+ CleanUpDeadListeners();
+ kickstart_adb_socket_.Close();
+}
+
+} // namespace forwarder
diff --git a/tools/android/forwarder2/device_controller.h b/tools/android/forwarder2/device_controller.h
new file mode 100644
index 0000000..213cb8a8
--- /dev/null
+++ b/tools/android/forwarder2/device_controller.h
@@ -0,0 +1,45 @@
+// 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 <hash_map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/id_map.h"
+#include "base/memory/linked_ptr.h"
+#include "tools/android/forwarder2/socket.h"
+
+namespace forwarder2 {
+
+class DeviceListener;
+
+class DeviceController {
+ public:
+ explicit DeviceController(int exit_notifier_fd);
+ ~DeviceController();
+
+ bool Start(const std::string& adb_unix_socket);
+
+ private:
+ void KillAllListeners();
+ void CleanUpDeadListeners();
+
+ // Map from Port to DeviceListener objects (owns the pointer).
+ typedef IDMap<DeviceListener, IDMapOwnPointer> ListenersMap;
+
+ ListenersMap listeners_;
+ Socket kickstart_adb_socket_;
+
+ // Used to notify the controller to exit.
+ const int exit_notifier_fd_;
+
+ 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
index f52450c..69faa29 100644
--- a/tools/android/forwarder2/device_forwarder_main.cc
+++ b/tools/android/forwarder2/device_forwarder_main.cc
@@ -2,9 +2,65 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/stringprintf.h"
+#include "tools/android/common/daemon.h"
+#include "tools/android/forwarder2/device_controller.h"
+#include "tools/android/forwarder2/pipe_notifier.h"
+
+namespace {
+
+// Leaky global instance, accessed from the signal handler.
+forwarder2::PipeNotifier* g_notifier = NULL;
+
+// Unix domain socket name for Device Controller.
+const char kDefaultAdbSocket[] = "chrome_device_forwarder";
+
+void KillHandler(int /* unused */) {
+ CHECK(g_notifier);
+ if (!g_notifier->Notify())
+ exit(-1);
+}
+
+} // namespace
+
int main(int argc, char** argv) {
- // TODO(felipeg): To be implemented.
- // BUG=146502
+ printf("Device forwarder to forward connections to the Host machine.\n");
+ printf("Like 'adb forward' but in the reverse direction\n");
+
+ CommandLine command_line(argc, argv);
+ std::string adb_socket_path = command_line.GetSwitchValueASCII("adb_sock");
+ if (adb_socket_path.empty()) {
+ adb_socket_path = kDefaultAdbSocket;
+ }
+ if (tools::HasHelpSwitch(command_line)) {
+ tools::ShowHelp(
+ argv[0],
+ "[--adb_sock=<adb sock>]",
+ base::StringPrintf(
+ " <adb sock> is the Abstract Unix Domain Socket path "
+ " where Adb is configured to forward from."
+ " Default is %s\n", kDefaultAdbSocket).c_str());
+ return 0;
+ }
+ if (!tools::HasNoSpawnDaemonSwitch(command_line)) {
+ tools::SpawnDaemon(0);
+ }
+
+ g_notifier = new forwarder2::PipeNotifier();
+
+ signal(SIGTERM, KillHandler);
+ signal(SIGINT, KillHandler);
+ CHECK(g_notifier);
+ forwarder2::DeviceController controller(g_notifier->receiver_fd());
+ printf("Starting Device Forwarder.\n");
+ controller.Start(adb_socket_path);
return 0;
}
diff --git a/tools/android/forwarder2/forwarder.gyp b/tools/android/forwarder2/forwarder.gyp
index b2ab893..b18b4bd 100644
--- a/tools/android/forwarder2/forwarder.gyp
+++ b/tools/android/forwarder2/forwarder.gyp
@@ -38,6 +38,7 @@
],
'sources': [
'command.cc',
+ 'device_controller.cc',
'device_forwarder_main.cc',
'device_listener.cc',
'forwarder.cc',