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

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

Issue 895853003: Update from https://crrev.com/314320 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « third_party/khronos/noninclude/GL/wglext.h ('k') | tools/linux/PRESUBMIT.py » ('j') | 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> 7 #include <sys/types.h>
8 #include <sys/wait.h> 8 #include <sys/wait.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 10
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 } 91 }
92 92
93 ~HostControllersManager() { 93 ~HostControllersManager() {
94 if (!thread_.get()) 94 if (!thread_.get())
95 return; 95 return;
96 // Delete the controllers on the thread they were created on. 96 // Delete the controllers on the thread they were created on.
97 thread_->message_loop_proxy()->DeleteSoon( 97 thread_->message_loop_proxy()->DeleteSoon(
98 FROM_HERE, controllers_.release()); 98 FROM_HERE, controllers_.release());
99 } 99 }
100 100
101 void HandleRequest(const std::string& device_serial, 101 void HandleRequest(const std::string& adb_path,
102 const std::string& device_serial,
102 int device_port, 103 int device_port,
103 int host_port, 104 int host_port,
104 scoped_ptr<Socket> client_socket) { 105 scoped_ptr<Socket> client_socket) {
105 // Lazy initialize so that the CLI process doesn't get this thread created. 106 // Lazy initialize so that the CLI process doesn't get this thread created.
106 InitOnce(); 107 InitOnce();
107 thread_->message_loop_proxy()->PostTask( 108 thread_->message_loop_proxy()->PostTask(
108 FROM_HERE, 109 FROM_HERE,
109 base::Bind( 110 base::Bind(&HostControllersManager::HandleRequestOnInternalThread,
110 &HostControllersManager::HandleRequestOnInternalThread, 111 base::Unretained(this), adb_path, device_serial, device_port,
111 base::Unretained(this), device_serial, device_port, host_port, 112 host_port, base::Passed(&client_socket)));
112 base::Passed(&client_socket)));
113 } 113 }
114 114
115 bool has_failed() const { return has_failed_; } 115 bool has_failed() const { return has_failed_; }
116 116
117 private: 117 private:
118 typedef base::hash_map< 118 typedef base::hash_map<
119 std::string, linked_ptr<HostController> > HostControllerMap; 119 std::string, linked_ptr<HostController> > HostControllerMap;
120 120
121 static std::string MakeHostControllerMapKey(int adb_port, int device_port) { 121 static std::string MakeHostControllerMapKey(int adb_port, int device_port) {
122 return base::StringPrintf("%d:%d", adb_port, device_port); 122 return base::StringPrintf("%d:%d", adb_port, device_port);
(...skipping 22 matching lines...) Expand all
145 return; 145 return;
146 } 146 }
147 DCHECK(manager->thread_->message_loop_proxy()->RunsTasksOnCurrentThread()); 147 DCHECK(manager->thread_->message_loop_proxy()->RunsTasksOnCurrentThread());
148 // Note that this will delete |controller| which is owned by the map. 148 // Note that this will delete |controller| which is owned by the map.
149 DeleteRefCountedValueInMap( 149 DeleteRefCountedValueInMap(
150 MakeHostControllerMapKey( 150 MakeHostControllerMapKey(
151 controller->adb_port(), controller->device_port()), 151 controller->adb_port(), controller->device_port()),
152 manager->controllers_.get()); 152 manager->controllers_.get());
153 } 153 }
154 154
155 void HandleRequestOnInternalThread(const std::string& device_serial, 155 void HandleRequestOnInternalThread(const std::string& adb_path,
156 const std::string& device_serial,
156 int device_port, 157 int device_port,
157 int host_port, 158 int host_port,
158 scoped_ptr<Socket> client_socket) { 159 scoped_ptr<Socket> client_socket) {
159 const int adb_port = GetAdbPortForDevice(device_serial); 160 const int adb_port = GetAdbPortForDevice(adb_path, device_serial);
160 if (adb_port < 0) { 161 if (adb_port < 0) {
161 SendMessage( 162 SendMessage(
162 "ERROR: could not get adb port for device. You might need to add " 163 "ERROR: could not get adb port for device. You might need to add "
163 "'adb' to your PATH or provide the device serial id.", 164 "'adb' to your PATH or provide the device serial id.",
164 client_socket.get()); 165 client_socket.get());
165 return; 166 return;
166 } 167 }
167 if (device_port < 0) { 168 if (device_port < 0) {
168 // Remove the previously created host controller. 169 // Remove the previously created host controller.
169 const std::string controller_key = MakeHostControllerMapKey( 170 const std::string controller_key = MakeHostControllerMapKey(
170 adb_port, -device_port); 171 adb_port, -device_port);
171 const bool controller_did_exist = DeleteRefCountedValueInMap( 172 const bool controller_did_exist = DeleteRefCountedValueInMap(
172 controller_key, controllers_.get()); 173 controller_key, controllers_.get());
173 SendMessage( 174 SendMessage(
174 !controller_did_exist ? "ERROR: could not unmap port" : "OK", 175 !controller_did_exist ? "ERROR: could not unmap port" : "OK",
175 client_socket.get()); 176 client_socket.get());
176 177
177 RemoveAdbPortForDeviceIfNeeded(device_serial); 178 RemoveAdbPortForDeviceIfNeeded(adb_path, device_serial);
178 return; 179 return;
179 } 180 }
180 if (host_port < 0) { 181 if (host_port < 0) {
181 SendMessage("ERROR: missing host port", client_socket.get()); 182 SendMessage("ERROR: missing host port", client_socket.get());
182 return; 183 return;
183 } 184 }
184 const bool use_dynamic_port_allocation = device_port == 0; 185 const bool use_dynamic_port_allocation = device_port == 0;
185 if (!use_dynamic_port_allocation) { 186 if (!use_dynamic_port_allocation) {
186 const std::string controller_key = MakeHostControllerMapKey( 187 const std::string controller_key = MakeHostControllerMapKey(
187 adb_port, device_port); 188 adb_port, device_port);
(...skipping 22 matching lines...) Expand all
210 << host_port; 211 << host_port;
211 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); 212 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port);
212 if (!SendMessage(msg, client_socket.get())) 213 if (!SendMessage(msg, client_socket.get()))
213 return; 214 return;
214 host_controller->Start(); 215 host_controller->Start();
215 controllers_->insert( 216 controllers_->insert(
216 std::make_pair(MakeHostControllerMapKey(adb_port, device_port), 217 std::make_pair(MakeHostControllerMapKey(adb_port, device_port),
217 linked_ptr<HostController>(host_controller.release()))); 218 linked_ptr<HostController>(host_controller.release())));
218 } 219 }
219 220
220 void RemoveAdbPortForDeviceIfNeeded(const std::string& device_serial) { 221 void RemoveAdbPortForDeviceIfNeeded(const std::string& adb_path,
222 const std::string& device_serial) {
221 base::hash_map<std::string, int>::const_iterator it = 223 base::hash_map<std::string, int>::const_iterator it =
222 device_serial_to_adb_port_map_.find(device_serial); 224 device_serial_to_adb_port_map_.find(device_serial);
223 if (it == device_serial_to_adb_port_map_.end()) 225 if (it == device_serial_to_adb_port_map_.end())
224 return; 226 return;
225 227
226 int port = it->second; 228 int port = it->second;
227 const std::string prefix = base::StringPrintf("%d:", port); 229 const std::string prefix = base::StringPrintf("%d:", port);
228 for (HostControllerMap::const_iterator others = controllers_->begin(); 230 for (HostControllerMap::const_iterator others = controllers_->begin();
229 others != controllers_->end(); ++others) { 231 others != controllers_->end(); ++others) {
230 if (others->first.find(prefix) == 0U) 232 if (others->first.find(prefix) == 0U)
231 return; 233 return;
232 } 234 }
233 // No other port is being forwarded to this device: 235 // No other port is being forwarded to this device:
234 // - Remove it from our internal serial -> adb port map. 236 // - Remove it from our internal serial -> adb port map.
235 // - Remove from "adb forward" command. 237 // - Remove from "adb forward" command.
236 LOG(INFO) << "Device " << device_serial << " has no more ports."; 238 LOG(INFO) << "Device " << device_serial << " has no more ports.";
237 device_serial_to_adb_port_map_.erase(device_serial); 239 device_serial_to_adb_port_map_.erase(device_serial);
238 const std::string serial_part = device_serial.empty() ? 240 const std::string serial_part = device_serial.empty() ?
239 std::string() : std::string("-s ") + device_serial; 241 std::string() : std::string("-s ") + device_serial;
240 const std::string command = base::StringPrintf( 242 const std::string command = base::StringPrintf(
241 "adb %s forward --remove tcp:%d", 243 "%s %s forward --remove tcp:%d",
244 adb_path.c_str(),
242 serial_part.c_str(), 245 serial_part.c_str(),
243 port); 246 port);
244 const int ret = system(command.c_str()); 247 const int ret = system(command.c_str());
245 LOG(INFO) << command << " ret: " << ret; 248 LOG(INFO) << command << " ret: " << ret;
246 // Wait for the socket to be fully unmapped. 249 // Wait for the socket to be fully unmapped.
247 const std::string port_mapped_cmd = base::StringPrintf( 250 const std::string port_mapped_cmd = base::StringPrintf(
248 "lsof -nPi:%d", 251 "lsof -nPi:%d",
249 port); 252 port);
250 const int poll_interval_us = 500 * 1000; 253 const int poll_interval_us = 500 * 1000;
251 int retries = 3; 254 int retries = 3;
252 while (retries) { 255 while (retries) {
253 const int port_unmapped = system(port_mapped_cmd.c_str()); 256 const int port_unmapped = system(port_mapped_cmd.c_str());
254 LOG(INFO) << "Device " << device_serial << " port " << port << " unmap " 257 LOG(INFO) << "Device " << device_serial << " port " << port << " unmap "
255 << port_unmapped; 258 << port_unmapped;
256 if (port_unmapped) 259 if (port_unmapped)
257 break; 260 break;
258 --retries; 261 --retries;
259 usleep(poll_interval_us); 262 usleep(poll_interval_us);
260 } 263 }
261 } 264 }
262 265
263 int GetAdbPortForDevice(const std::string& device_serial) { 266 int GetAdbPortForDevice(const std::string adb_path,
267 const std::string& device_serial) {
264 base::hash_map<std::string, int>::const_iterator it = 268 base::hash_map<std::string, int>::const_iterator it =
265 device_serial_to_adb_port_map_.find(device_serial); 269 device_serial_to_adb_port_map_.find(device_serial);
266 if (it != device_serial_to_adb_port_map_.end()) 270 if (it != device_serial_to_adb_port_map_.end())
267 return it->second; 271 return it->second;
268 Socket bind_socket; 272 Socket bind_socket;
269 CHECK(bind_socket.BindTcp("127.0.0.1", 0)); 273 CHECK(bind_socket.BindTcp("127.0.0.1", 0));
270 const int port = bind_socket.GetPort(); 274 const int port = bind_socket.GetPort();
271 bind_socket.Close(); 275 bind_socket.Close();
272 const std::string serial_part = device_serial.empty() ? 276 const std::string serial_part = device_serial.empty() ?
273 std::string() : std::string("-s ") + device_serial; 277 std::string() : std::string("-s ") + device_serial;
274 const std::string command = base::StringPrintf( 278 const std::string command = base::StringPrintf(
275 "adb %s forward tcp:%d localabstract:chrome_device_forwarder", 279 "%s %s forward tcp:%d localabstract:chrome_device_forwarder",
280 adb_path.c_str(),
276 serial_part.c_str(), 281 serial_part.c_str(),
277 port); 282 port);
278 LOG(INFO) << command; 283 LOG(INFO) << command;
279 const int ret = system(command.c_str()); 284 const int ret = system(command.c_str());
280 if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0) 285 if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
281 return -1; 286 return -1;
282 device_serial_to_adb_port_map_[device_serial] = port; 287 device_serial_to_adb_port_map_[device_serial] = port;
283 return port; 288 return port;
284 } 289 }
285 290
286 bool SendMessage(const std::string& msg, Socket* client_socket) { 291 bool SendMessage(const std::string& msg, Socket* client_socket) {
287 bool result = client_socket->WriteString(msg); 292 bool result = client_socket->WriteString(msg);
288 DCHECK(result); 293 DCHECK(result);
289 if (!result) 294 if (!result)
290 has_failed_ = true; 295 has_failed_ = true;
291 return result; 296 return result;
292 } 297 }
293 298
294 base::hash_map<std::string, int> device_serial_to_adb_port_map_; 299 base::hash_map<std::string, int> device_serial_to_adb_port_map_;
295 scoped_ptr<HostControllerMap> controllers_; 300 scoped_ptr<HostControllerMap> controllers_;
296 bool has_failed_; 301 bool has_failed_;
297 scoped_ptr<base::AtExitManager> at_exit_manager_; // Needed by base::Thread. 302 scoped_ptr<base::AtExitManager> at_exit_manager_; // Needed by base::Thread.
298 scoped_ptr<base::Thread> thread_; 303 scoped_ptr<base::Thread> thread_;
299 base::WeakPtrFactory<HostControllersManager> weak_ptr_factory_; 304 base::WeakPtrFactory<HostControllersManager> weak_ptr_factory_;
300 }; 305 };
301 306
302 class ServerDelegate : public Daemon::ServerDelegate { 307 class ServerDelegate : public Daemon::ServerDelegate {
303 public: 308 public:
304 ServerDelegate() : has_failed_(false) {} 309 ServerDelegate(const std::string& adb_path)
310 : adb_path_(adb_path), has_failed_(false) {}
305 311
306 bool has_failed() const { 312 bool has_failed() const {
307 return has_failed_ || controllers_manager_.has_failed(); 313 return has_failed_ || controllers_manager_.has_failed();
308 } 314 }
309 315
310 // Daemon::ServerDelegate: 316 // Daemon::ServerDelegate:
311 virtual void Init() override { 317 virtual void Init() override {
312 LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")"; 318 LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")";
313 DCHECK(!g_notifier); 319 DCHECK(!g_notifier);
314 g_notifier = new PipeNotifier(); 320 g_notifier = new PipeNotifier();
(...skipping 16 matching lines...) Expand all
331 std::string device_serial; 337 std::string device_serial;
332 CHECK(pickle_it.ReadString(&device_serial)); 338 CHECK(pickle_it.ReadString(&device_serial));
333 int device_port; 339 int device_port;
334 if (!pickle_it.ReadInt(&device_port)) { 340 if (!pickle_it.ReadInt(&device_port)) {
335 client_socket->WriteString("ERROR: missing device port"); 341 client_socket->WriteString("ERROR: missing device port");
336 return; 342 return;
337 } 343 }
338 int host_port; 344 int host_port;
339 if (!pickle_it.ReadInt(&host_port)) 345 if (!pickle_it.ReadInt(&host_port))
340 host_port = -1; 346 host_port = -1;
341 controllers_manager_.HandleRequest( 347 controllers_manager_.HandleRequest(adb_path_, device_serial, device_port,
342 device_serial, device_port, host_port, client_socket.Pass()); 348 host_port, client_socket.Pass());
343 } 349 }
344 350
345 private: 351 private:
352 std::string adb_path_;
346 bool has_failed_; 353 bool has_failed_;
347 HostControllersManager controllers_manager_; 354 HostControllersManager controllers_manager_;
348 355
349 DISALLOW_COPY_AND_ASSIGN(ServerDelegate); 356 DISALLOW_COPY_AND_ASSIGN(ServerDelegate);
350 }; 357 };
351 358
352 class ClientDelegate : public Daemon::ClientDelegate { 359 class ClientDelegate : public Daemon::ClientDelegate {
353 public: 360 public:
354 ClientDelegate(const Pickle& command_pickle) 361 ClientDelegate(const Pickle& command_pickle)
355 : command_pickle_(command_pickle), 362 : command_pickle_(command_pickle),
(...skipping 27 matching lines...) Expand all
383 const Pickle command_pickle_; 390 const Pickle command_pickle_;
384 bool has_failed_; 391 bool has_failed_;
385 }; 392 };
386 393
387 void ExitWithUsage() { 394 void ExitWithUsage() {
388 std::cerr << "Usage: host_forwarder [options]\n\n" 395 std::cerr << "Usage: host_forwarder [options]\n\n"
389 "Options:\n" 396 "Options:\n"
390 " --serial-id=[0-9A-Z]{16}]\n" 397 " --serial-id=[0-9A-Z]{16}]\n"
391 " --map DEVICE_PORT HOST_PORT\n" 398 " --map DEVICE_PORT HOST_PORT\n"
392 " --unmap DEVICE_PORT\n" 399 " --unmap DEVICE_PORT\n"
400 " --adb PATH_TO_ADB\n"
393 " --kill-server\n"; 401 " --kill-server\n";
394 exit(1); 402 exit(1);
395 } 403 }
396 404
397 int PortToInt(const std::string& s) { 405 int PortToInt(const std::string& s) {
398 int value; 406 int value;
399 // Note that 0 is a valid port (used for dynamic port allocation). 407 // Note that 0 is a valid port (used for dynamic port allocation).
400 if (!base::StringToInt(s, &value) || value < 0 || 408 if (!base::StringToInt(s, &value) || value < 0 ||
401 value > std::numeric_limits<uint16>::max()) { 409 value > std::numeric_limits<uint16>::max()) {
402 LOG(ERROR) << "Could not convert string " << s << " to port"; 410 LOG(ERROR) << "Could not convert string " << s << " to port";
403 ExitWithUsage(); 411 ExitWithUsage();
404 } 412 }
405 return value; 413 return value;
406 } 414 }
407 415
408 int RunHostForwarder(int argc, char** argv) { 416 int RunHostForwarder(int argc, char** argv) {
409 base::CommandLine::Init(argc, argv); 417 base::CommandLine::Init(argc, argv);
410 const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess(); 418 const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
419 std::string adb_path = "adb";
411 bool kill_server = false; 420 bool kill_server = false;
412 421
413 Pickle pickle; 422 Pickle pickle;
414 pickle.WriteString( 423 pickle.WriteString(
415 cmd_line.HasSwitch("serial-id") ? 424 cmd_line.HasSwitch("serial-id") ?
416 cmd_line.GetSwitchValueASCII("serial-id") : std::string()); 425 cmd_line.GetSwitchValueASCII("serial-id") : std::string());
417 426
418 const std::vector<std::string> args = cmd_line.GetArgs(); 427 const std::vector<std::string> args = cmd_line.GetArgs();
419 if (cmd_line.HasSwitch("kill-server")) { 428 if (cmd_line.HasSwitch("kill-server")) {
420 kill_server = true; 429 kill_server = true;
421 } else if (cmd_line.HasSwitch("unmap")) { 430 } else if (cmd_line.HasSwitch("unmap")) {
422 if (args.size() != 1) 431 if (args.size() != 1)
423 ExitWithUsage(); 432 ExitWithUsage();
424 // Note the minus sign below. 433 // Note the minus sign below.
425 pickle.WriteInt(-PortToInt(args[0])); 434 pickle.WriteInt(-PortToInt(args[0]));
426 } else if (cmd_line.HasSwitch("map")) { 435 } else if (cmd_line.HasSwitch("map")) {
427 if (args.size() != 2) 436 if (args.size() != 2)
428 ExitWithUsage(); 437 ExitWithUsage();
429 pickle.WriteInt(PortToInt(args[0])); 438 pickle.WriteInt(PortToInt(args[0]));
430 pickle.WriteInt(PortToInt(args[1])); 439 pickle.WriteInt(PortToInt(args[1]));
431 } else { 440 } else {
432 ExitWithUsage(); 441 ExitWithUsage();
433 } 442 }
434 443
444 if (cmd_line.HasSwitch("adb")) {
445 adb_path = cmd_line.GetSwitchValueASCII("adb");
446 }
447
435 if (kill_server && args.size() > 0) 448 if (kill_server && args.size() > 0)
436 ExitWithUsage(); 449 ExitWithUsage();
437 450
438 ClientDelegate client_delegate(pickle); 451 ClientDelegate client_delegate(pickle);
439 ServerDelegate daemon_delegate; 452 ServerDelegate daemon_delegate(adb_path);
440 Daemon daemon( 453 Daemon daemon(
441 kLogFilePath, kDaemonIdentifier, &client_delegate, &daemon_delegate, 454 kLogFilePath, kDaemonIdentifier, &client_delegate, &daemon_delegate,
442 &GetExitNotifierFD); 455 &GetExitNotifierFD);
443 456
444 if (kill_server) 457 if (kill_server)
445 return !daemon.Kill(); 458 return !daemon.Kill();
446 if (!daemon.SpawnIfNeeded()) 459 if (!daemon.SpawnIfNeeded())
447 return 1; 460 return 1;
448 461
449 return client_delegate.has_failed() || daemon_delegate.has_failed(); 462 return client_delegate.has_failed() || daemon_delegate.has_failed();
450 } 463 }
451 464
452 } // namespace 465 } // namespace
453 } // namespace forwarder2 466 } // namespace forwarder2
454 467
455 int main(int argc, char** argv) { 468 int main(int argc, char** argv) {
456 return forwarder2::RunHostForwarder(argc, argv); 469 return forwarder2::RunHostForwarder(argc, argv);
457 } 470 }
OLDNEW
« no previous file with comments | « third_party/khronos/noninclude/GL/wglext.h ('k') | tools/linux/PRESUBMIT.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698