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

Side by Side Diff: tools/android/forwarder2/host_forwarder_main.cc

Issue 18640002: Revert "Add --serial-id option to host_forwarder." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « tools/android/forwarder2/device_forwarder_main.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <signal.h> 6 #include <signal.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9 #include <unistd.h> 7 #include <unistd.h>
10 8
11 #include <cstdio> 9 #include <cstdio>
12 #include <iostream> 10 #include <cstring>
13 #include <limits>
14 #include <string> 11 #include <string>
15 #include <utility> 12 #include <utility>
16 #include <vector> 13 #include <vector>
17 14
18 #include "base/command_line.h" 15 #include "base/command_line.h"
19 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
20 #include "base/containers/hash_tables.h" 17 #include "base/containers/hash_tables.h"
21 #include "base/file_util.h" 18 #include "base/file_util.h"
22 #include "base/files/file_path.h" 19 #include "base/files/file_path.h"
23 #include "base/logging.h" 20 #include "base/logging.h"
24 #include "base/memory/linked_ptr.h" 21 #include "base/memory/linked_ptr.h"
25 #include "base/memory/scoped_vector.h" 22 #include "base/memory/scoped_vector.h"
26 #include "base/pickle.h"
27 #include "base/posix/eintr_wrapper.h" 23 #include "base/posix/eintr_wrapper.h"
28 #include "base/safe_strerror_posix.h" 24 #include "base/safe_strerror_posix.h"
29 #include "base/strings/string_number_conversions.h" 25 #include "base/strings/string_number_conversions.h"
30 #include "base/strings/string_piece.h" 26 #include "base/strings/string_piece.h"
31 #include "base/strings/string_split.h" 27 #include "base/strings/string_split.h"
32 #include "base/strings/string_util.h" 28 #include "base/strings/string_util.h"
33 #include "base/strings/stringprintf.h" 29 #include "base/strings/stringprintf.h"
34 #include "tools/android/forwarder2/common.h" 30 #include "tools/android/forwarder2/common.h"
35 #include "tools/android/forwarder2/daemon.h" 31 #include "tools/android/forwarder2/daemon.h"
36 #include "tools/android/forwarder2/host_controller.h" 32 #include "tools/android/forwarder2/host_controller.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 static int s_kill_handler_count = 0; 65 static int s_kill_handler_count = 0;
70 CHECK(g_notifier); 66 CHECK(g_notifier);
71 // If for some reason the forwarder get stuck in any socket waiting forever, 67 // If for some reason the forwarder get stuck in any socket waiting forever,
72 // we can send a SIGKILL or SIGINT three times to force it die 68 // we can send a SIGKILL or SIGINT three times to force it die
73 // (non-nicely). This is useful when debugging. 69 // (non-nicely). This is useful when debugging.
74 ++s_kill_handler_count; 70 ++s_kill_handler_count;
75 if (!g_notifier->Notify() || s_kill_handler_count > 2) 71 if (!g_notifier->Notify() || s_kill_handler_count > 2)
76 exit(1); 72 exit(1);
77 } 73 }
78 74
75 // Format of |command|:
76 // <ADB port>:<Device port>[:<Forward to port>:<Forward to address>].
77 bool ParseForwardCommand(const std::string& command,
78 int* adb_port,
79 int* device_port,
80 std::string* forward_to_host,
81 int* forward_to_port) {
82 std::vector<std::string> command_pieces;
83 base::SplitString(command, ':', &command_pieces);
84
85 if (command_pieces.size() < 2 ||
86 !base::StringToInt(command_pieces[0], adb_port) ||
87 !base::StringToInt(command_pieces[1], device_port))
88 return false;
89
90 if (command_pieces.size() > 2) {
91 if (!base::StringToInt(command_pieces[2], forward_to_port))
92 return false;
93 if (command_pieces.size() > 3)
94 *forward_to_host = command_pieces[3];
95 } else {
96 *forward_to_port = *device_port;
97 }
98 return true;
99 }
100
101 bool IsForwardCommandValid(const std::string& command) {
102 int adb_port, device_port, forward_to_port;
103 std::string forward_to_host;
104 std::vector<std::string> command_pieces;
105 return ParseForwardCommand(
106 command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
107 }
108
79 class ServerDelegate : public Daemon::ServerDelegate { 109 class ServerDelegate : public Daemon::ServerDelegate {
80 public: 110 public:
81 ServerDelegate() : has_failed_(false) {} 111 ServerDelegate() : has_failed_(false) {}
82 112
83 bool has_failed() const { return has_failed_; } 113 bool has_failed() const { return has_failed_; }
84 114
85 // Daemon::ServerDelegate: 115 // Daemon::ServerDelegate:
86 virtual void Init() OVERRIDE { 116 virtual void Init() OVERRIDE {
87 LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")"; 117 LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")";
88 DCHECK(!g_notifier); 118 DCHECK(!g_notifier);
89 g_notifier = new PipeNotifier(); 119 g_notifier = new PipeNotifier();
90 signal(SIGTERM, KillHandler); 120 signal(SIGTERM, KillHandler);
91 signal(SIGINT, KillHandler); 121 signal(SIGINT, KillHandler);
92 } 122 }
93 123
94 virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE { 124 virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
95 char buf[kBufSize]; 125 char buf[kBufSize];
96 const int bytes_read = client_socket->Read(buf, sizeof(buf)); 126 const int bytes_read = client_socket->Read(buf, sizeof(buf));
97 if (bytes_read <= 0) { 127 if (bytes_read <= 0) {
98 if (client_socket->DidReceiveEvent()) 128 if (client_socket->DidReceiveEvent())
99 return; 129 return;
100 PError("Read()"); 130 PError("Read()");
101 has_failed_ = true; 131 has_failed_ = true;
102 return; 132 return;
103 } 133 }
104 const Pickle command_pickle(buf, bytes_read); 134 const std::string command(buf, bytes_read);
105 PickleIterator pickle_it(command_pickle); 135 int adb_port = 0;
106 std::string device_serial; 136 int device_port = 0;
107 CHECK(pickle_it.ReadString(&device_serial)); 137 std::string forward_to_host;
108 int device_port; 138 int forward_to_port = 0;
109 if (!pickle_it.ReadInt(&device_port)) { 139 const bool succeeded = ParseForwardCommand(
110 SendMessage("ERROR: missing device port", client_socket.get()); 140 command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
111 return; 141 if (!succeeded) {
112 } 142 has_failed_ = true;
113 const int adb_port = GetAdbPortForDevice(device_serial); 143 const std::string msg = base::StringPrintf(
114 if (adb_port < 0) { 144 "ERROR: Could not parse forward command '%s'", command.c_str());
115 SendMessage( 145 SendMessage(msg, client_socket.get());
116 "ERROR: could not get adb port for device. You might need to add "
117 "'adb' to your PATH or provide the device serial id.",
118 client_socket.get());
119 return; 146 return;
120 } 147 }
121 if (device_port < 0) { 148 if (device_port < 0) {
122 // Remove the previously created host controller. 149 // Remove the previously created host controller.
123 const std::string controller_key = MakeHostControllerMapKey( 150 const std::string controller_key = MakeHostControllerMapKey(
124 adb_port, -device_port); 151 adb_port, -device_port);
125 const HostControllerMap::size_type removed_elements = controllers_.erase( 152 const HostControllerMap::size_type removed_elements = controllers_.erase(
126 controller_key); 153 controller_key);
127 SendMessage( 154 SendMessage(
128 !removed_elements ? "ERROR: could not unmap port" : "OK", 155 !removed_elements ? "ERROR: could not unmap port" : "OK",
129 client_socket.get()); 156 client_socket.get());
130 return; 157 return;
131 } 158 }
132 int host_port;
133 if (!pickle_it.ReadInt(&host_port)) {
134 SendMessage("ERROR: missing host port", client_socket.get());
135 return;
136 }
137 // Create a new host controller. 159 // Create a new host controller.
138 scoped_ptr<HostController> host_controller( 160 scoped_ptr<HostController> host_controller(
139 new HostController(device_port, "127.0.0.1", host_port, adb_port, 161 new HostController(device_port, forward_to_host, forward_to_port,
140 GetExitNotifierFD())); 162 adb_port, GetExitNotifierFD()));
141 if (!host_controller->Connect()) { 163 if (!host_controller->Connect()) {
142 has_failed_ = true; 164 has_failed_ = true;
143 SendMessage("ERROR: Connection to device failed.", client_socket.get()); 165 SendMessage("ERROR: Connection to device failed.", client_socket.get());
144 return; 166 return;
145 } 167 }
146 // Get the current allocated port. 168 // Get the current allocated port.
147 device_port = host_controller->device_port(); 169 device_port = host_controller->device_port();
148 LOG(INFO) << "Forwarding device port " << device_port << " to host port " 170 LOG(INFO) << "Forwarding device port " << device_port << " to host "
149 << host_port; 171 << forward_to_host << ":" << forward_to_port;
150 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); 172 const std::string msg = base::StringPrintf(
173 "%d:%d", device_port, forward_to_port);
151 if (!SendMessage(msg, client_socket.get())) 174 if (!SendMessage(msg, client_socket.get()))
152 return; 175 return;
153 host_controller->Start(); 176 host_controller->Start();
154 const std::string controller_key = MakeHostControllerMapKey( 177 const std::string controller_key = MakeHostControllerMapKey(
155 adb_port, device_port); 178 adb_port, device_port);
156 controllers_.insert( 179 controllers_.insert(
157 std::make_pair(controller_key, 180 std::make_pair(controller_key,
158 linked_ptr<HostController>(host_controller.release()))); 181 linked_ptr<HostController>(host_controller.release())));
159 } 182 }
160 183
(...skipping 10 matching lines...) Expand all
171 } 194 }
172 195
173 private: 196 private:
174 typedef base::hash_map< 197 typedef base::hash_map<
175 std::string, linked_ptr<HostController> > HostControllerMap; 198 std::string, linked_ptr<HostController> > HostControllerMap;
176 199
177 static std::string MakeHostControllerMapKey(int adb_port, int device_port) { 200 static std::string MakeHostControllerMapKey(int adb_port, int device_port) {
178 return base::StringPrintf("%d:%d", adb_port, device_port); 201 return base::StringPrintf("%d:%d", adb_port, device_port);
179 } 202 }
180 203
181 int GetAdbPortForDevice(const std::string& device_serial) {
182 base::hash_map<std::string, int>::const_iterator it =
183 device_serial_to_adb_port_map_.find(device_serial);
184 if (it != device_serial_to_adb_port_map_.end())
185 return it->second;
186 Socket bind_socket;
187 CHECK(bind_socket.BindTcp("127.0.0.1", 0));
188 const int port = bind_socket.GetPort();
189 bind_socket.Close();
190 const std::string serial_part = device_serial.empty() ?
191 std::string() : std::string("-s ") + device_serial;
192 const std::string command = base::StringPrintf(
193 "adb %s forward tcp:%d localabstract:chrome_device_forwarder",
194 device_serial.empty() ? "" : serial_part.c_str(),
195 port);
196 LOG(INFO) << command;
197 const int ret = system(command.c_str());
198 if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
199 return -1;
200 device_serial_to_adb_port_map_[device_serial] = port;
201 return port;
202 }
203
204 bool SendMessage(const std::string& msg, Socket* client_socket) { 204 bool SendMessage(const std::string& msg, Socket* client_socket) {
205 bool result = client_socket->WriteString(msg); 205 bool result = client_socket->WriteString(msg);
206 DCHECK(result); 206 DCHECK(result);
207 if (!result) 207 if (!result)
208 has_failed_ = true; 208 has_failed_ = true;
209 return result; 209 return result;
210 } 210 }
211 211
212 base::hash_map<std::string, int> device_serial_to_adb_port_map_;
213 HostControllerMap controllers_; 212 HostControllerMap controllers_;
214 bool has_failed_; 213 bool has_failed_;
215 214
216 DISALLOW_COPY_AND_ASSIGN(ServerDelegate); 215 DISALLOW_COPY_AND_ASSIGN(ServerDelegate);
217 }; 216 };
218 217
219 class ClientDelegate : public Daemon::ClientDelegate { 218 class ClientDelegate : public Daemon::ClientDelegate {
220 public: 219 public:
221 ClientDelegate(const Pickle& command_pickle) 220 ClientDelegate(const std::string& forward_command)
222 : command_pickle_(command_pickle), 221 : forward_command_(forward_command),
223 has_failed_(false) { 222 has_failed_(false) {
224 } 223 }
225 224
226 bool has_failed() const { return has_failed_; } 225 bool has_failed() const { return has_failed_; }
227 226
228 // Daemon::ClientDelegate: 227 // Daemon::ClientDelegate:
229 virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE { 228 virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
230 // Send the forward command to the daemon. 229 // Send the forward command to the daemon.
231 CHECK_EQ(command_pickle_.size(), 230 CHECK(daemon_socket->WriteString(forward_command_));
232 daemon_socket->WriteNumBytes(command_pickle_.data(),
233 command_pickle_.size()));
234 char buf[kBufSize]; 231 char buf[kBufSize];
235 const int bytes_read = daemon_socket->Read( 232 const int bytes_read = daemon_socket->Read(
236 buf, sizeof(buf) - 1 /* leave space for null terminator */); 233 buf, sizeof(buf) - 1 /* leave space for null terminator */);
237 CHECK_GT(bytes_read, 0); 234 CHECK_GT(bytes_read, 0);
238 DCHECK(bytes_read < sizeof(buf)); 235 DCHECK(bytes_read < sizeof(buf));
239 buf[bytes_read] = 0; 236 buf[bytes_read] = 0;
240 base::StringPiece msg(buf, bytes_read); 237 base::StringPiece msg(buf, bytes_read);
241 if (msg.starts_with("ERROR")) { 238 if (msg.starts_with("ERROR")) {
242 LOG(ERROR) << msg; 239 LOG(ERROR) << msg;
243 has_failed_ = true; 240 has_failed_ = true;
244 return; 241 return;
245 } 242 }
246 printf("%s\n", buf); 243 printf("%s\n", buf);
247 } 244 }
248 245
249 private: 246 private:
250 const Pickle command_pickle_; 247 const std::string forward_command_;
251 bool has_failed_; 248 bool has_failed_;
252 }; 249 };
253 250
254 void ExitWithUsage() { 251 void PrintUsage(const char* program_name) {
255 std::cerr << "Usage: host_forwarder [options]\n\n" 252 LOG(ERROR) << program_name
256 "Options:\n" 253 << " adb_port:from_port:to_port:to_host\n"
257 " --serial-id=[0-9A-Z]{16}]\n" 254 "<adb port> is the TCP port Adb is configured to forward to.\n"
258 " --map DEVICE_PORT HOST_PORT\n" 255 "Note that <from_port> can be unmapped by making it negative.";
259 " --unmap DEVICE_PORT\n"
260 " --kill-server\n";
261 exit(1);
262 }
263
264 int PortToInt(const std::string& s) {
265 int value;
266 // Note that 0 is a valid port (used for dynamic port allocation).
267 if (!base::StringToInt(s, &value) || value < 0 ||
268 value > std::numeric_limits<uint16>::max()) {
269 LOG(ERROR) << "Could not convert string " << s << " to port";
270 ExitWithUsage();
271 }
272 return value;
273 } 256 }
274 257
275 int RunHostForwarder(int argc, char** argv) { 258 int RunHostForwarder(int argc, char** argv) {
276 CommandLine::Init(argc, argv); 259 if (!CommandLine::Init(argc, argv)) {
277 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); 260 LOG(ERROR) << "Could not initialize command line";
278 bool kill_server = false; 261 return 1;
279 262 }
280 Pickle pickle; 263 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
281 pickle.WriteString( 264 const char* command = NULL;
282 cmd_line.HasSwitch("serial-id") ? 265 int adb_port = 0;
283 cmd_line.GetSwitchValueASCII("serial-id") : std::string()); 266 if (argc != 2) {
284 267 PrintUsage(argv[0]);
285 const std::vector<std::string> args = cmd_line.GetArgs(); 268 return 1;
286 if (cmd_line.HasSwitch("kill-server")) { 269 }
287 kill_server = true; 270 if (!strcmp(argv[1], kKillServerCommand)) {
288 } else if (cmd_line.HasSwitch("unmap")) { 271 command = kKillServerCommand;
289 if (args.size() != 1)
290 ExitWithUsage();
291 // Note the minus sign below.
292 pickle.WriteInt(-PortToInt(args[0]));
293 } else if (cmd_line.HasSwitch("map")) {
294 if (args.size() != 2)
295 ExitWithUsage();
296 pickle.WriteInt(PortToInt(args[0]));
297 pickle.WriteInt(PortToInt(args[1]));
298 } else { 272 } else {
299 ExitWithUsage(); 273 command = kForwardCommand;
274 if (!IsForwardCommandValid(argv[1])) {
275 PrintUsage(argv[0]);
276 return 1;
277 }
300 } 278 }
301 279
302 if (kill_server && args.size() > 0) 280 ClientDelegate client_delegate(argv[1]);
303 ExitWithUsage();
304
305 ClientDelegate client_delegate(pickle);
306 ServerDelegate daemon_delegate; 281 ServerDelegate daemon_delegate;
307 Daemon daemon( 282 Daemon daemon(
308 kLogFilePath, kDaemonIdentifier, &client_delegate, &daemon_delegate, 283 kLogFilePath, kDaemonIdentifier, &client_delegate, &daemon_delegate,
309 &GetExitNotifierFD); 284 &GetExitNotifierFD);
310 285
311 if (kill_server) 286 if (command == kKillServerCommand)
312 return !daemon.Kill(); 287 return !daemon.Kill();
288
289 DCHECK(command == kForwardCommand);
313 if (!daemon.SpawnIfNeeded()) 290 if (!daemon.SpawnIfNeeded())
314 return 1; 291 return 1;
315 292
316 return client_delegate.has_failed() || daemon_delegate.has_failed(); 293 return client_delegate.has_failed() || daemon_delegate.has_failed();
317 } 294 }
318 295
319 } // namespace 296 } // namespace
320 } // namespace forwarder2 297 } // namespace forwarder2
321 298
322 int main(int argc, char** argv) { 299 int main(int argc, char** argv) {
323 return forwarder2::RunHostForwarder(argc, argv); 300 return forwarder2::RunHostForwarder(argc, argv);
324 } 301 }
OLDNEW
« no previous file with comments | « tools/android/forwarder2/device_forwarder_main.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698