Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: tools/android/forwarder2/device_controller.cc

Issue 10918057: Add forwarder2 (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/android/forwarder2/device_controller.h ('k') | tools/android/forwarder2/device_forwarder_main.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/android/forwarder2/device_controller.cc
diff --git a/tools/android/forwarder2/device_controller.cc b/tools/android/forwarder2/device_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ca54e2e7f0f7f9b0b1811a786a15cfe19e483b74
--- /dev/null
+++ b/tools/android/forwarder2/device_controller.cc
@@ -0,0 +1,124 @@
+// 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 forwarder {
+
+DeviceController::DeviceController(int notifier_fd)
+ : exit_notifier_fd_(notifier_fd) {
+ kickstart_adb_socket_.set_notifier_fd(notifier_fd);
+}
+
+DeviceController::~DeviceController() {
+ KillAllListeners();
+ CleanUpDeadListeners();
+ CHECK_EQ(0, listeners_.size());
+}
+
+void DeviceController::CleanUpDeadListeners() {
+ // Clean up dead listeners.
+ for (ListenersMap::iterator it = listeners_.begin();
+ it != listeners_.end();) {
+ if (!it->second->is_alive()) {
+ ListenersMap::iterator to_erase(it);
+ to_erase->second.reset();
+ ++it;
+ listeners_.erase(to_erase);
+ } else {
+ ++it;
+ }
+ }
+}
+
+void DeviceController::KillAllListeners() {
+ ListenersMap::iterator it;
+ for (it = listeners_.begin(); it != listeners_.end(); ++it) {
+ it->second->ForceExit();
+ }
+ for (it = listeners_.begin(); it != listeners_.end(); ++it) {
+ it->second->Join();
+ CHECK(!it->second->is_alive());
+ }
+}
+
+bool DeviceController::Start(const string& adb_unix_socket) {
+ if (!kickstart_adb_socket_.BindUnix(adb_unix_socket,
+ /* abstract = */ true)) {
+ 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_notifier_fd(exit_notifier_fd_);
+ int port;
+ command::Type command;
+ if (!ReadCommand(socket.get(), &port, &command)) {
+ LOG(ERROR) << "Invalid command received.";
+ socket->Close();
+ continue;
+ }
+ ListenersMap::iterator listener_it(listeners_.find(port));
+ switch (command) {
+ case command::LISTEN:
+ if (listener_it != listeners_.end()) {
+ LOG(WARNING) << "Already forwarding port " << port
+ << ". Attempting to restart the listener.\n";
+ listener_it->second->ForceExit();
+ listener_it->second->Join();
+ CHECK(!listener_it->second->is_alive());
+ } else {
+ // Listener object will be deleted by the CleanUpDeadListeners method.
+ DeviceListener* listener = new DeviceListener(socket.Pass(), port);
+ listeners_[port].reset(listener);
+ listener->Start();
+ }
+ break;
+ case command::DATA_CONNECTION:
+ if (listener_it == listeners_.end()) {
+ 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_it->second->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.";
+ socket->Close();
+ continue;
+ }
+ }
+ KillAllListeners();
+ CleanUpDeadListeners();
+ kickstart_adb_socket_.Close();
+}
+
+} // namespace forwarder
« no previous file with comments | « tools/android/forwarder2/device_controller.h ('k') | tools/android/forwarder2/device_forwarder_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698