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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "tools/android/forwarder2/device_controller.h"
6
7 #include <errno.h>
8 #include <stdlib.h>
9
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/safe_strerror_posix.h"
13 #include "tools/android/forwarder2/command.h"
14 #include "tools/android/forwarder2/device_listener.h"
15 #include "tools/android/forwarder2/socket.h"
16
17 namespace forwarder {
18
19 DeviceController::DeviceController(int notifier_fd)
20 : exit_notifier_fd_(notifier_fd) {
21 kickstart_adb_socket_.set_notifier_fd(notifier_fd);
22 }
23
24 DeviceController::~DeviceController() {
25 KillAllListeners();
26 CleanUpDeadListeners();
27 CHECK_EQ(0, listeners_.size());
28 }
29
30 void DeviceController::CleanUpDeadListeners() {
31 // Clean up dead listeners.
32 for (ListenersMap::iterator it = listeners_.begin();
33 it != listeners_.end();) {
34 if (!it->second->is_alive()) {
35 ListenersMap::iterator to_erase(it);
36 to_erase->second.reset();
37 ++it;
38 listeners_.erase(to_erase);
39 } else {
40 ++it;
41 }
42 }
43 }
44
45 void DeviceController::KillAllListeners() {
46 ListenersMap::iterator it;
47 for (it = listeners_.begin(); it != listeners_.end(); ++it) {
48 it->second->ForceExit();
49 }
50 for (it = listeners_.begin(); it != listeners_.end(); ++it) {
51 it->second->Join();
52 CHECK(!it->second->is_alive());
53 }
54 }
55
56 bool DeviceController::Start(const string& adb_unix_socket) {
57 if (!kickstart_adb_socket_.BindUnix(adb_unix_socket,
58 /* abstract = */ true)) {
59 LOG(ERROR) << "Could not BindAndListen DeviceController socket on port: "
60 << adb_unix_socket;
61 return false;
62 }
63 while (true) {
64 CleanUpDeadListeners();
65 scoped_ptr<Socket> socket(new Socket);
66 if (!kickstart_adb_socket_.Accept(socket.get())) {
67 LOG(ERROR) << "Could not Accept DeviceController socket: "
68 << safe_strerror(errno);
69 break;
70 }
71 // So that |socket| doesn't block on read if it has notifications.
72 socket->set_notifier_fd(exit_notifier_fd_);
73 int port;
74 command::Type command;
75 if (!ReadCommand(socket.get(), &port, &command)) {
76 LOG(ERROR) << "Invalid command received.";
77 socket->Close();
78 continue;
79 }
80 ListenersMap::iterator listener_it(listeners_.find(port));
81 switch (command) {
82 case command::LISTEN:
83 if (listener_it != listeners_.end()) {
84 LOG(WARNING) << "Already forwarding port " << port
85 << ". Attempting to restart the listener.\n";
86 listener_it->second->ForceExit();
87 listener_it->second->Join();
88 CHECK(!listener_it->second->is_alive());
89 } else {
90 // Listener object will be deleted by the CleanUpDeadListeners method.
91 DeviceListener* listener = new DeviceListener(socket.Pass(), port);
92 listeners_[port].reset(listener);
93 listener->Start();
94 }
95 break;
96 case command::DATA_CONNECTION:
97 if (listener_it == listeners_.end()) {
98 LOG(ERROR) << "Data Connection command received, but "
99 << "listener has not been set up yet for port " << port;
100 // After this point it is assumed that, once we close our Adb Data
101 // socket, the Adb forwarder command will propagate the closing of
102 // sockets all the way to the host side.
103 socket->Close();
104 continue;
105 } else if (!listener_it->second->SetAdbDataSocket(socket.Pass())) {
106 LOG(ERROR) << "Could not set Adb Data Socket for port: " << port;
107 // Same assumption as above, but in this case the socket is closed
108 // inside SetAdbDataSocket.
109 continue;
110 }
111 break;
112 default:
113 // TODO(felipeg): add a KillAllListeners command.
114 LOG(ERROR) << "Invalid command received.";
115 socket->Close();
116 continue;
117 }
118 }
119 KillAllListeners();
120 CleanUpDeadListeners();
121 kickstart_adb_socket_.Close();
122 }
123
124 } // namespace forwarder
OLDNEW
« 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