Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <sys/types.h> | 9 #include <sys/types.h> |
| 10 #include <sys/wait.h> | 10 #include <sys/wait.h> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 #include "tools/android/forwarder2/util.h" | 44 #include "tools/android/forwarder2/util.h" |
| 45 | 45 |
| 46 namespace forwarder2 { | 46 namespace forwarder2 { |
| 47 namespace { | 47 namespace { |
| 48 | 48 |
| 49 const char kLogFilePath[] = "/tmp/host_forwarder_log"; | 49 const char kLogFilePath[] = "/tmp/host_forwarder_log"; |
| 50 const char kDaemonIdentifier[] = "chrome_host_forwarder_daemon"; | 50 const char kDaemonIdentifier[] = "chrome_host_forwarder_daemon"; |
| 51 | 51 |
| 52 const int kBufSize = 256; | 52 const int kBufSize = 256; |
| 53 | 53 |
| 54 enum : int { | |
| 55 MAP = 0, | |
| 56 UNMAP = 1, | |
| 57 UNMAP_ALL = 2, | |
| 58 }; | |
| 59 | |
| 54 // Needs to be global to be able to be accessed from the signal handler. | 60 // Needs to be global to be able to be accessed from the signal handler. |
| 55 PipeNotifier* g_notifier = NULL; | 61 PipeNotifier* g_notifier = NULL; |
| 56 | 62 |
| 57 // Lets the daemon fetch the exit notifier file descriptor. | 63 // Lets the daemon fetch the exit notifier file descriptor. |
| 58 int GetExitNotifierFD() { | 64 int GetExitNotifierFD() { |
| 59 DCHECK(g_notifier); | 65 DCHECK(g_notifier); |
| 60 return g_notifier->receiver_fd(); | 66 return g_notifier->receiver_fd(); |
| 61 } | 67 } |
| 62 | 68 |
| 63 void KillHandler(int signal_number) { | 69 void KillHandler(int signal_number) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 93 ~HostControllersManager() { | 99 ~HostControllersManager() { |
| 94 if (!thread_.get()) | 100 if (!thread_.get()) |
| 95 return; | 101 return; |
| 96 // Delete the controllers on the thread they were created on. | 102 // Delete the controllers on the thread they were created on. |
| 97 thread_->task_runner()->DeleteSoon( | 103 thread_->task_runner()->DeleteSoon( |
| 98 FROM_HERE, controllers_.release()); | 104 FROM_HERE, controllers_.release()); |
| 99 } | 105 } |
| 100 | 106 |
| 101 void HandleRequest(const std::string& adb_path, | 107 void HandleRequest(const std::string& adb_path, |
| 102 const std::string& device_serial, | 108 const std::string& device_serial, |
| 109 int command, | |
| 103 int device_port, | 110 int device_port, |
| 104 int host_port, | 111 int host_port, |
| 105 std::unique_ptr<Socket> client_socket) { | 112 std::unique_ptr<Socket> client_socket) { |
| 106 // Lazy initialize so that the CLI process doesn't get this thread created. | 113 // Lazy initialize so that the CLI process doesn't get this thread created. |
| 107 InitOnce(); | 114 InitOnce(); |
| 108 thread_->task_runner()->PostTask( | 115 thread_->task_runner()->PostTask( |
| 109 FROM_HERE, | 116 FROM_HERE, |
| 110 base::Bind(&HostControllersManager::HandleRequestOnInternalThread, | 117 base::Bind(&HostControllersManager::HandleRequestOnInternalThread, |
| 111 base::Unretained(this), adb_path, device_serial, device_port, | 118 base::Unretained(this), adb_path, device_serial, command, |
| 112 host_port, base::Passed(&client_socket))); | 119 device_port, host_port, base::Passed(&client_socket))); |
| 113 } | 120 } |
| 114 | 121 |
| 115 bool has_failed() const { return has_failed_; } | 122 bool has_failed() const { return has_failed_; } |
| 116 | 123 |
| 117 private: | 124 private: |
| 118 typedef base::hash_map< | 125 typedef base::hash_map< |
| 119 std::string, linked_ptr<HostController> > HostControllerMap; | 126 std::string, linked_ptr<HostController> > HostControllerMap; |
| 120 | 127 |
| 121 static std::string MakeHostControllerMapKey(int adb_port, int device_port) { | 128 static std::string MakeHostControllerMapKey(int adb_port, int device_port) { |
| 122 return base::StringPrintf("%d:%d", adb_port, device_port); | 129 return base::StringPrintf("%d:%d", adb_port, device_port); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 145 return; | 152 return; |
| 146 } | 153 } |
| 147 DCHECK(manager->thread_->task_runner()->RunsTasksOnCurrentThread()); | 154 DCHECK(manager->thread_->task_runner()->RunsTasksOnCurrentThread()); |
| 148 // Note that this will delete |controller| which is owned by the map. | 155 // Note that this will delete |controller| which is owned by the map. |
| 149 DeleteRefCountedValueInMap( | 156 DeleteRefCountedValueInMap( |
| 150 MakeHostControllerMapKey( | 157 MakeHostControllerMapKey( |
| 151 controller->adb_port(), controller->device_port()), | 158 controller->adb_port(), controller->device_port()), |
| 152 manager->controllers_.get()); | 159 manager->controllers_.get()); |
| 153 } | 160 } |
| 154 | 161 |
| 155 void HandleRequestOnInternalThread(const std::string& adb_path, | 162 void Map(const std::string& adb_path, |
| 156 const std::string& device_serial, | 163 const std::string& device_serial, |
| 157 int device_port, | 164 int adb_port, |
| 158 int host_port, | 165 int device_port, |
| 159 std::unique_ptr<Socket> client_socket) { | 166 int host_port, |
| 160 const int adb_port = GetAdbPortForDevice(adb_path, device_serial); | 167 Socket* client_socket) { |
| 161 if (adb_port < 0) { | |
| 162 SendMessage( | |
| 163 "ERROR: could not get adb port for device. You might need to add " | |
| 164 "'adb' to your PATH or provide the device serial id.\n", | |
| 165 client_socket.get()); | |
| 166 return; | |
| 167 } | |
| 168 if (device_port < 0) { | |
| 169 // Remove the previously created host controller. | |
| 170 const std::string controller_key = MakeHostControllerMapKey( | |
| 171 adb_port, -device_port); | |
| 172 const bool controller_did_exist = DeleteRefCountedValueInMap( | |
| 173 controller_key, controllers_.get()); | |
| 174 if (!controller_did_exist) { | |
| 175 SendMessage("ERROR: could not unmap port.\n", client_socket.get()); | |
| 176 LogExistingControllers(client_socket); | |
| 177 } else { | |
| 178 SendMessage("OK", client_socket.get()); | |
| 179 } | |
| 180 | |
| 181 RemoveAdbPortForDeviceIfNeeded(adb_path, device_serial); | |
| 182 return; | |
| 183 } | |
| 184 if (host_port < 0) { | 168 if (host_port < 0) { |
| 185 SendMessage("ERROR: missing host port\n", client_socket.get()); | 169 SendMessage("ERROR: missing host port\n", client_socket); |
| 186 return; | 170 return; |
| 187 } | 171 } |
| 188 const bool use_dynamic_port_allocation = device_port == 0; | 172 const bool use_dynamic_port_allocation = device_port == 0; |
| 189 if (!use_dynamic_port_allocation) { | 173 if (!use_dynamic_port_allocation) { |
| 190 const std::string controller_key = MakeHostControllerMapKey( | 174 const std::string controller_key = MakeHostControllerMapKey( |
| 191 adb_port, device_port); | 175 adb_port, device_port); |
| 192 if (controllers_->find(controller_key) != controllers_->end()) { | 176 if (controllers_->find(controller_key) != controllers_->end()) { |
| 193 LOG(INFO) << "Already forwarding device port " << device_port | 177 LOG(INFO) << "Already forwarding device port " << device_port |
| 194 << " to host port " << host_port; | 178 << " to host port " << host_port; |
| 195 SendMessage(base::StringPrintf("%d:%d", device_port, host_port), | 179 SendMessage(base::StringPrintf("%d:%d", device_port, host_port), |
| 196 client_socket.get()); | 180 client_socket); |
| 197 return; | 181 return; |
| 198 } | 182 } |
| 199 } | 183 } |
| 200 // Create a new host controller. | 184 // Create a new host controller. |
| 201 std::unique_ptr<HostController> host_controller(HostController::Create( | 185 std::unique_ptr<HostController> host_controller(HostController::Create( |
| 202 device_serial, device_port, host_port, adb_port, GetExitNotifierFD(), | 186 device_serial, device_port, host_port, adb_port, GetExitNotifierFD(), |
| 203 base::Bind(&HostControllersManager::DeleteHostController, | 187 base::Bind(&HostControllersManager::DeleteHostController, |
| 204 weak_ptr_factory_.GetWeakPtr()))); | 188 weak_ptr_factory_.GetWeakPtr()))); |
| 205 if (!host_controller.get()) { | 189 if (!host_controller.get()) { |
| 206 has_failed_ = true; | 190 has_failed_ = true; |
| 207 SendMessage("ERROR: Connection to device failed.\n", client_socket.get()); | 191 SendMessage("ERROR: Connection to device failed.\n", client_socket); |
| 208 LogExistingControllers(client_socket); | 192 LogExistingControllers(client_socket); |
| 209 return; | 193 return; |
| 210 } | 194 } |
| 211 // Get the current allocated port. | 195 // Get the current allocated port. |
| 212 device_port = host_controller->device_port(); | 196 device_port = host_controller->device_port(); |
| 213 LOG(INFO) << "Forwarding device port " << device_port << " to host port " | 197 LOG(INFO) << "Forwarding device port " << device_port << " to host port " |
| 214 << host_port; | 198 << host_port; |
| 215 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); | 199 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); |
| 216 if (!SendMessage(msg, client_socket.get())) | 200 if (!SendMessage(msg, client_socket)) |
| 217 return; | 201 return; |
| 218 host_controller->Start(); | 202 host_controller->Start(); |
| 219 controllers_->insert( | 203 controllers_->insert( |
| 220 std::make_pair(MakeHostControllerMapKey(adb_port, device_port), | 204 std::make_pair(MakeHostControllerMapKey(adb_port, device_port), |
| 221 linked_ptr<HostController>(host_controller.release()))); | 205 linked_ptr<HostController>(host_controller.release()))); |
| 222 } | 206 } |
| 223 | 207 |
| 224 void LogExistingControllers(const std::unique_ptr<Socket>& client_socket) { | 208 void Unmap(const std::string& adb_path, |
| 225 SendMessage("ERROR: Existing controllers:\n", client_socket.get()); | 209 const std::string& device_serial, |
| 226 for (const auto& controller : *controllers_) { | 210 int adb_port, |
| 227 SendMessage(base::StringPrintf("ERROR: %s\n", controller.first.c_str()), | 211 int device_port, |
| 212 Socket* client_socket) { | |
| 213 // Remove the previously created host controller. | |
| 214 const std::string controller_key = | |
| 215 MakeHostControllerMapKey(adb_port, device_port); | |
| 216 const bool controller_did_exist = | |
| 217 DeleteRefCountedValueInMap(controller_key, controllers_.get()); | |
| 218 if (!controller_did_exist) { | |
| 219 SendMessage("ERROR: could not unmap port.\n", client_socket); | |
| 220 LogExistingControllers(client_socket); | |
| 221 } else { | |
| 222 SendMessage("OK", client_socket); | |
| 223 } | |
| 224 | |
| 225 RemoveAdbPortForDeviceIfNeeded(adb_path, device_serial); | |
| 226 } | |
| 227 | |
| 228 void UnmapAll(const std::string& adb_path, | |
| 229 const std::string& device_serial, | |
| 230 int adb_port, | |
| 231 Socket* client_socket) { | |
| 232 const std::string adb_port_str = base::StringPrintf("%d", adb_port); | |
| 233 for (HostControllerMap::const_iterator controller_key = | |
| 234 controllers_->cbegin(); | |
| 235 controller_key != controllers_->cend(); ++controller_key) { | |
| 236 LOG(INFO) << controller_key->first; | |
|
agrieve
2016/09/30 14:41:07
intentional? If so, maybe prefix with what this is
jbudorick
2016/09/30 14:46:03
No, leftover. Removed.
| |
| 237 std::vector<std::string> pieces = | |
| 238 base::SplitString(controller_key->first, ":", base::KEEP_WHITESPACE, | |
| 239 base::SPLIT_WANT_ALL); | |
| 240 if (pieces.size() == 2) { | |
| 241 if (pieces[0] == adb_port_str) { | |
| 242 DeleteRefCountedValueInMapFromIterator(controller_key, | |
| 243 controllers_.get()); | |
| 244 } | |
| 245 } else { | |
| 246 LOG(ERROR) << "Unexpected controller key: " << controller_key->first; | |
| 247 } | |
| 248 } | |
| 249 | |
| 250 RemoveAdbPortForDeviceIfNeeded(adb_path, device_serial); | |
| 251 SendMessage("OK", client_socket); | |
| 252 } | |
| 253 | |
| 254 void HandleRequestOnInternalThread(const std::string& adb_path, | |
| 255 const std::string& device_serial, | |
| 256 int command, | |
| 257 int device_port, | |
| 258 int host_port, | |
| 259 std::unique_ptr<Socket> client_socket) { | |
| 260 const int adb_port = GetAdbPortForDevice(adb_path, device_serial); | |
| 261 if (adb_port < 0) { | |
| 262 SendMessage( | |
| 263 "ERROR: could not get adb port for device. You might need to add " | |
| 264 "'adb' to your PATH or provide the device serial id.\n", | |
| 228 client_socket.get()); | 265 client_socket.get()); |
| 266 return; | |
| 267 } | |
| 268 switch (command) { | |
| 269 case MAP: | |
| 270 Map(adb_path, device_serial, adb_port, device_port, host_port, | |
| 271 client_socket.get()); | |
| 272 break; | |
| 273 case UNMAP: | |
| 274 Unmap(adb_path, device_serial, adb_port, device_port, | |
| 275 client_socket.get()); | |
| 276 break; | |
| 277 case UNMAP_ALL: | |
| 278 UnmapAll(adb_path, device_serial, adb_port, client_socket.get()); | |
| 279 break; | |
| 280 default: | |
| 281 SendMessage( | |
| 282 base::StringPrintf("ERROR: unrecognized command %d\n", command), | |
| 283 client_socket.get()); | |
| 284 break; | |
| 229 } | 285 } |
| 230 } | 286 } |
| 231 | 287 |
| 288 void LogExistingControllers(Socket* client_socket) { | |
| 289 SendMessage("ERROR: Existing controllers:\n", client_socket); | |
| 290 for (const auto& controller : *controllers_) { | |
| 291 SendMessage(base::StringPrintf("ERROR: %s\n", controller.first.c_str()), | |
| 292 client_socket); | |
| 293 } | |
| 294 } | |
| 295 | |
| 232 void RemoveAdbPortForDeviceIfNeeded(const std::string& adb_path, | 296 void RemoveAdbPortForDeviceIfNeeded(const std::string& adb_path, |
| 233 const std::string& device_serial) { | 297 const std::string& device_serial) { |
| 234 base::hash_map<std::string, int>::const_iterator it = | 298 base::hash_map<std::string, int>::const_iterator it = |
| 235 device_serial_to_adb_port_map_.find(device_serial); | 299 device_serial_to_adb_port_map_.find(device_serial); |
| 236 if (it == device_serial_to_adb_port_map_.end()) | 300 if (it == device_serial_to_adb_port_map_.end()) |
| 237 return; | 301 return; |
| 238 | 302 |
| 239 int port = it->second; | 303 int port = it->second; |
| 240 const std::string prefix = base::StringPrintf("%d:", port); | 304 const std::string prefix = base::StringPrintf("%d:", port); |
| 241 for (HostControllerMap::const_iterator others = controllers_->begin(); | 305 for (HostControllerMap::const_iterator others = controllers_->begin(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 const int bytes_read = client_socket->Read(buf, sizeof(buf)); | 403 const int bytes_read = client_socket->Read(buf, sizeof(buf)); |
| 340 if (bytes_read <= 0) { | 404 if (bytes_read <= 0) { |
| 341 if (client_socket->DidReceiveEvent()) | 405 if (client_socket->DidReceiveEvent()) |
| 342 return; | 406 return; |
| 343 PError("Read()"); | 407 PError("Read()"); |
| 344 has_failed_ = true; | 408 has_failed_ = true; |
| 345 return; | 409 return; |
| 346 } | 410 } |
| 347 const base::Pickle command_pickle(buf, bytes_read); | 411 const base::Pickle command_pickle(buf, bytes_read); |
| 348 base::PickleIterator pickle_it(command_pickle); | 412 base::PickleIterator pickle_it(command_pickle); |
| 413 | |
| 349 std::string device_serial; | 414 std::string device_serial; |
| 350 CHECK(pickle_it.ReadString(&device_serial)); | 415 CHECK(pickle_it.ReadString(&device_serial)); |
| 351 int device_port; | 416 |
| 352 if (!pickle_it.ReadInt(&device_port)) { | 417 int command; |
| 353 client_socket->WriteString("ERROR: missing device port\n"); | 418 if (!pickle_it.ReadInt(&command)) { |
| 419 client_socket->WriteString("Error: missing command\n"); | |
| 354 return; | 420 return; |
| 355 } | 421 } |
| 422 | |
| 423 int device_port; | |
| 424 if (!pickle_it.ReadInt(&device_port)) | |
| 425 device_port = -1; | |
| 426 | |
| 356 int host_port; | 427 int host_port; |
| 357 if (!pickle_it.ReadInt(&host_port)) | 428 if (!pickle_it.ReadInt(&host_port)) |
| 358 host_port = -1; | 429 host_port = -1; |
| 359 controllers_manager_.HandleRequest(adb_path_, device_serial, device_port, | 430 controllers_manager_.HandleRequest(adb_path_, device_serial, command, |
| 360 host_port, std::move(client_socket)); | 431 device_port, host_port, |
| 432 std::move(client_socket)); | |
| 361 } | 433 } |
| 362 | 434 |
| 363 private: | 435 private: |
| 364 std::string adb_path_; | 436 std::string adb_path_; |
| 365 bool has_failed_; | 437 bool has_failed_; |
| 366 HostControllersManager controllers_manager_; | 438 HostControllersManager controllers_manager_; |
| 367 | 439 |
| 368 DISALLOW_COPY_AND_ASSIGN(ServerDelegate); | 440 DISALLOW_COPY_AND_ASSIGN(ServerDelegate); |
| 369 }; | 441 }; |
| 370 | 442 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 400 const base::Pickle command_pickle_; | 472 const base::Pickle command_pickle_; |
| 401 bool has_failed_; | 473 bool has_failed_; |
| 402 }; | 474 }; |
| 403 | 475 |
| 404 void ExitWithUsage() { | 476 void ExitWithUsage() { |
| 405 std::cerr << "Usage: host_forwarder [options]\n\n" | 477 std::cerr << "Usage: host_forwarder [options]\n\n" |
| 406 "Options:\n" | 478 "Options:\n" |
| 407 " --serial-id=[0-9A-Z]{16}]\n" | 479 " --serial-id=[0-9A-Z]{16}]\n" |
| 408 " --map DEVICE_PORT HOST_PORT\n" | 480 " --map DEVICE_PORT HOST_PORT\n" |
| 409 " --unmap DEVICE_PORT\n" | 481 " --unmap DEVICE_PORT\n" |
| 482 " --unmap-all\n" | |
| 410 " --adb PATH_TO_ADB\n" | 483 " --adb PATH_TO_ADB\n" |
| 411 " --kill-server\n"; | 484 " --kill-server\n"; |
| 412 exit(1); | 485 exit(1); |
| 413 } | 486 } |
| 414 | 487 |
| 415 int PortToInt(const std::string& s) { | 488 int PortToInt(const std::string& s) { |
| 416 int value; | 489 int value; |
| 417 // Note that 0 is a valid port (used for dynamic port allocation). | 490 // Note that 0 is a valid port (used for dynamic port allocation). |
| 418 if (!base::StringToInt(s, &value) || value < 0 || | 491 if (!base::StringToInt(s, &value) || value < 0 || |
| 419 value > std::numeric_limits<uint16_t>::max()) { | 492 value > std::numeric_limits<uint16_t>::max()) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 433 pickle.WriteString( | 506 pickle.WriteString( |
| 434 cmd_line.HasSwitch("serial-id") ? | 507 cmd_line.HasSwitch("serial-id") ? |
| 435 cmd_line.GetSwitchValueASCII("serial-id") : std::string()); | 508 cmd_line.GetSwitchValueASCII("serial-id") : std::string()); |
| 436 | 509 |
| 437 const std::vector<std::string> args = cmd_line.GetArgs(); | 510 const std::vector<std::string> args = cmd_line.GetArgs(); |
| 438 if (cmd_line.HasSwitch("kill-server")) { | 511 if (cmd_line.HasSwitch("kill-server")) { |
| 439 kill_server = true; | 512 kill_server = true; |
| 440 } else if (cmd_line.HasSwitch("unmap")) { | 513 } else if (cmd_line.HasSwitch("unmap")) { |
| 441 if (args.size() != 1) | 514 if (args.size() != 1) |
| 442 ExitWithUsage(); | 515 ExitWithUsage(); |
| 443 // Note the minus sign below. | 516 pickle.WriteInt(UNMAP); |
| 444 pickle.WriteInt(-PortToInt(args[0])); | 517 pickle.WriteInt(PortToInt(args[0])); |
| 518 } else if (cmd_line.HasSwitch("unmap-all")) { | |
| 519 pickle.WriteInt(UNMAP_ALL); | |
| 445 } else if (cmd_line.HasSwitch("map")) { | 520 } else if (cmd_line.HasSwitch("map")) { |
| 446 if (args.size() != 2) | 521 if (args.size() != 2) |
| 447 ExitWithUsage(); | 522 ExitWithUsage(); |
| 523 pickle.WriteInt(MAP); | |
| 448 pickle.WriteInt(PortToInt(args[0])); | 524 pickle.WriteInt(PortToInt(args[0])); |
| 449 pickle.WriteInt(PortToInt(args[1])); | 525 pickle.WriteInt(PortToInt(args[1])); |
| 450 } else { | 526 } else { |
| 451 ExitWithUsage(); | 527 ExitWithUsage(); |
| 452 } | 528 } |
| 453 | 529 |
| 454 if (cmd_line.HasSwitch("adb")) { | 530 if (cmd_line.HasSwitch("adb")) { |
| 455 adb_path = cmd_line.GetSwitchValueASCII("adb"); | 531 adb_path = cmd_line.GetSwitchValueASCII("adb"); |
| 456 } | 532 } |
| 457 | 533 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 471 | 547 |
| 472 return client_delegate.has_failed() || daemon_delegate.has_failed(); | 548 return client_delegate.has_failed() || daemon_delegate.has_failed(); |
| 473 } | 549 } |
| 474 | 550 |
| 475 } // namespace | 551 } // namespace |
| 476 } // namespace forwarder2 | 552 } // namespace forwarder2 |
| 477 | 553 |
| 478 int main(int argc, char** argv) { | 554 int main(int argc, char** argv) { |
| 479 return forwarder2::RunHostForwarder(argc, argv); | 555 return forwarder2::RunHostForwarder(argc, argv); |
| 480 } | 556 } |
| OLD | NEW |