OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chrome/browser/devtools/tethering_adb_filter.h" | 5 #include "chrome/browser/devtools/tethering_adb_filter.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "net/dns/host_resolver.h" | 24 #include "net/dns/host_resolver.h" |
25 #include "net/socket/tcp_client_socket.h" | 25 #include "net/socket/tcp_client_socket.h" |
26 | 26 |
27 using content::BrowserThread; | 27 using content::BrowserThread; |
28 | 28 |
29 namespace { | 29 namespace { |
30 | 30 |
31 const int kAdbPort = 5037; | 31 const int kAdbPort = 5037; |
32 const int kBufferSize = 16 * 1024; | 32 const int kBufferSize = 16 * 1024; |
33 | 33 |
34 const int kStatusError = -2; | |
35 const int kStatusConnecting = -1; | |
36 const int kStatusOK = 0; | |
pfeldman
2013/08/08 16:43:22
kStatusOk. Is that enum?
Vladislav Kaznacheev
2013/08/09 08:24:58
Done
On 2013/08/08 16:43:22, pfeldman wrote:
| |
37 | |
34 static const char kPortAttribute[] = "port"; | 38 static const char kPortAttribute[] = "port"; |
35 static const char kConnectionIdAttribute[] = "connectionId"; | 39 static const char kConnectionIdAttribute[] = "connectionId"; |
36 static const char kTetheringAccepted[] = "Tethering.accepted"; | 40 static const char kTetheringAccepted[] = "Tethering.accepted"; |
37 static const char kTetheringBind[] = "Tethering.bind"; | 41 static const char kTetheringBind[] = "Tethering.bind"; |
38 static const char kTetheringUnbind[] = "Tethering.unbind"; | 42 static const char kTetheringUnbind[] = "Tethering.unbind"; |
39 static const char kLocalAbstractCommand[] = "localabstract:%s"; | 43 static const char kLocalAbstractCommand[] = "localabstract:%s"; |
40 | 44 |
41 static const char kDevToolsRemoteSocketName[] = "chrome_devtools_remote"; | 45 static const char kDevToolsRemoteSocketName[] = "chrome_devtools_remote"; |
42 static const char kDevToolsRemoteBrowserTarget[] = "/devtools/browser"; | 46 static const char kDevToolsRemoteBrowserTarget[] = "/devtools/browser"; |
43 | 47 |
44 class SocketTunnel { | 48 class SocketTunnel { |
45 public: | 49 public: |
46 explicit SocketTunnel(const std::string& location) | 50 typedef base::Callback<void(int)> CounterCallback; |
51 | |
52 SocketTunnel(const std::string& location, const CounterCallback& callback) | |
47 : location_(location), | 53 : location_(location), |
48 pending_writes_(0), | 54 pending_writes_(0), |
49 pending_destruction_(false) { | 55 pending_destruction_(false), |
56 callback_(callback) { | |
57 callback_.Run(1); | |
50 } | 58 } |
51 | 59 |
52 void Start(int result, net::StreamSocket* socket) { | 60 void Start(int result, net::StreamSocket* socket) { |
53 if (result < 0) { | 61 if (result < 0) { |
54 SelfDestruct(); | 62 SelfDestruct(); |
55 return; | 63 return; |
56 } | 64 } |
57 remote_socket_.reset(socket); | 65 remote_socket_.reset(socket); |
58 | 66 |
59 std::vector<std::string> tokens; | 67 std::vector<std::string> tokens; |
(...skipping 28 matching lines...) Expand all Loading... | |
88 base::Unretained(this))); | 96 base::Unretained(this))); |
89 if (result != net::ERR_IO_PENDING) | 97 if (result != net::ERR_IO_PENDING) |
90 OnConnected(result); | 98 OnConnected(result); |
91 } | 99 } |
92 | 100 |
93 ~SocketTunnel() { | 101 ~SocketTunnel() { |
94 if (host_socket_) | 102 if (host_socket_) |
95 host_socket_->Disconnect(); | 103 host_socket_->Disconnect(); |
96 if (remote_socket_) | 104 if (remote_socket_) |
97 remote_socket_->Disconnect(); | 105 remote_socket_->Disconnect(); |
106 callback_.Run(-1); | |
98 } | 107 } |
99 | 108 |
100 void OnConnected(int result) { | 109 void OnConnected(int result) { |
101 if (result < 0) { | 110 if (result < 0) { |
102 SelfDestruct(); | 111 SelfDestruct(); |
103 return; | 112 return; |
104 } | 113 } |
105 | 114 |
106 Pump(host_socket_.get(), remote_socket_.get()); | 115 Pump(host_socket_.get(), remote_socket_.get()); |
107 Pump(remote_socket_.get(), host_socket_.get()); | 116 Pump(remote_socket_.get(), host_socket_.get()); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 delete this; | 192 delete this; |
184 } | 193 } |
185 | 194 |
186 std::string location_; | 195 std::string location_; |
187 scoped_ptr<net::StreamSocket> remote_socket_; | 196 scoped_ptr<net::StreamSocket> remote_socket_; |
188 scoped_ptr<net::StreamSocket> host_socket_; | 197 scoped_ptr<net::StreamSocket> host_socket_; |
189 scoped_ptr<net::HostResolver> host_resolver_; | 198 scoped_ptr<net::HostResolver> host_resolver_; |
190 net::AddressList address_list_; | 199 net::AddressList address_list_; |
191 int pending_writes_; | 200 int pending_writes_; |
192 bool pending_destruction_; | 201 bool pending_destruction_; |
202 CounterCallback callback_; | |
193 }; | 203 }; |
194 | 204 |
195 } // namespace | 205 } // namespace |
196 | 206 |
197 TetheringAdbFilter::TetheringAdbFilter(int adb_port, | 207 TetheringAdbFilter::TetheringAdbFilter(int adb_port, |
198 const std::string& serial, | 208 const std::string& serial, |
199 base::MessageLoop* adb_message_loop, | 209 base::MessageLoop* adb_message_loop, |
200 PrefService* pref_service, | 210 PrefService* pref_service, |
201 scoped_refptr<AdbWebSocket> web_socket) | 211 scoped_refptr<AdbWebSocket> web_socket) |
202 : adb_port_(adb_port), | 212 : adb_port_(adb_port), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 | 279 |
270 SendCommand(method, port); | 280 SendCommand(method, port); |
271 } | 281 } |
272 } | 282 } |
273 | 283 |
274 void TetheringAdbFilter::SendCommand(const std::string& method, int port) { | 284 void TetheringAdbFilter::SendCommand(const std::string& method, int port) { |
275 base::DictionaryValue params; | 285 base::DictionaryValue params; |
276 params.SetInteger(kPortAttribute, port); | 286 params.SetInteger(kPortAttribute, port); |
277 DevToolsProtocol::Command command(++command_id_, method, ¶ms); | 287 DevToolsProtocol::Command command(++command_id_, method, ¶ms); |
278 web_socket_->SendFrameOnHandlerThread(command.Serialize()); | 288 web_socket_->SendFrameOnHandlerThread(command.Serialize()); |
289 | |
290 if (method == kTetheringBind) { | |
291 pending_responses_[command.id()] = | |
292 base::Bind(&TetheringAdbFilter::ProcessBindResponseOnUIThread, | |
293 weak_factory_.GetWeakPtr(), port); | |
294 #if defined(DEBUG_DEVTOOLS) | |
295 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
296 base::Bind(&TetheringAdbFilter::ProcessBindResponseOnUIThread, | |
297 weak_factory_.GetWeakPtr(), port, kStatusConnecting)); | |
298 #endif // defined(DEBUG_DEVTOOLS) | |
299 } else { | |
300 DCHECK_EQ(kTetheringUnbind, method); | |
301 pending_responses_[command.id()] = | |
302 base::Bind(&TetheringAdbFilter::ProcessUnbindResponseOnUIThread, | |
303 weak_factory_.GetWeakPtr(), port); | |
304 } | |
305 } | |
306 | |
307 bool TetheringAdbFilter::ProcessResponse(const std::string& message) { | |
pfeldman
2013/08/08 16:43:22
Sounds like a part of devtools_protocol.
Vladislav Kaznacheev
2013/08/09 08:24:58
You mean move the pending_responses_ part into Dev
| |
308 scoped_ptr<DevToolsProtocol::Response> response( | |
309 DevToolsProtocol::ParseResponse(message)); | |
310 if (!response) | |
311 return false; | |
312 | |
313 CommandCallbackMap::iterator it = pending_responses_.find(response->id()); | |
314 if (it == pending_responses_.end()) | |
315 return false; | |
316 | |
317 CommandCallback callback = it->second; | |
318 BrowserThread::PostTask( | |
319 BrowserThread::UI, | |
320 FROM_HERE, | |
321 base::Bind(callback, response->error_code() ? kStatusError : kStatusOK)); | |
322 pending_responses_.erase(it); | |
323 return true; | |
324 } | |
325 | |
326 void TetheringAdbFilter::ProcessBindResponseOnUIThread( | |
327 int port, PortStatus status) { | |
328 port_status_[port] = status; | |
329 } | |
330 | |
331 void TetheringAdbFilter::ProcessUnbindResponseOnUIThread( | |
332 int port, PortStatus status) { | |
333 PortStatusMap::iterator it = port_status_.find(port); | |
334 if (it == port_status_.end()) | |
335 return; | |
336 if (status == kStatusError) | |
337 it->second = status; | |
338 else | |
339 port_status_.erase(it); | |
340 } | |
341 | |
342 void TetheringAdbFilter::UpdateSocketCount(int port, int increment) { | |
343 #if defined(DEBUG_DEVTOOLS) | |
344 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
345 base::Bind(&TetheringAdbFilter::UpdateSocketCountOnUIThread, | |
346 weak_factory_.GetWeakPtr(), port, increment)); | |
347 #endif // defined(DEBUG_DEVTOOLS) | |
348 } | |
349 | |
350 void TetheringAdbFilter::UpdateSocketCountOnUIThread(int port, int increment) { | |
351 PortStatusMap::iterator it = port_status_.find(port); | |
352 if (it == port_status_.end()) | |
353 return; | |
354 if (it->second < 0 || (it->second == 0 && increment < 0)) | |
355 return; | |
356 it->second += increment; | |
279 } | 357 } |
280 | 358 |
281 bool TetheringAdbFilter::ProcessIncomingMessage(const std::string& message) { | 359 bool TetheringAdbFilter::ProcessIncomingMessage(const std::string& message) { |
282 DCHECK_EQ(base::MessageLoop::current(), adb_message_loop_); | 360 DCHECK_EQ(base::MessageLoop::current(), adb_message_loop_); |
283 | 361 |
284 // Only parse messages that might be Tethering.accepted event. | 362 if (message.length() > 200) |
pfeldman
2013/08/08 16:43:22
This check is no longer needed - you are the only
Vladislav Kaznacheev
2013/08/09 08:24:58
Removed this check and the one looking for kTether
| |
285 if (message.length() > 200 || | 363 return false; |
286 message.find(kTetheringAccepted) == std::string::npos) | 364 |
365 if (ProcessResponse(message)) | |
366 return true; | |
367 | |
368 if (message.find(kTetheringAccepted) == std::string::npos) | |
287 return false; | 369 return false; |
288 | 370 |
289 scoped_ptr<DevToolsProtocol::Notification> notification( | 371 scoped_ptr<DevToolsProtocol::Notification> notification( |
290 DevToolsProtocol::ParseNotification(message)); | 372 DevToolsProtocol::ParseNotification(message)); |
291 if (!notification) | 373 if (!notification) |
292 return false; | 374 return false; |
293 | 375 |
294 if (notification->method() != kTetheringAccepted) | 376 if (notification->method() != kTetheringAccepted) |
295 return false; | 377 return false; |
296 | 378 |
297 DictionaryValue* params = notification->params(); | 379 DictionaryValue* params = notification->params(); |
298 if (!params) | 380 if (!params) |
299 return false; | 381 return false; |
300 | 382 |
301 int port; | 383 int port; |
302 std::string connection_id; | 384 std::string connection_id; |
303 if (!params->GetInteger(kPortAttribute, &port) || | 385 if (!params->GetInteger(kPortAttribute, &port) || |
304 !params->GetString(kConnectionIdAttribute, &connection_id)) | 386 !params->GetString(kConnectionIdAttribute, &connection_id)) |
305 return false; | 387 return false; |
306 | 388 |
307 std::map<int, std::string>::iterator it = forwarding_map_.find(port); | 389 std::map<int, std::string>::iterator it = forwarding_map_.find(port); |
308 if (it == forwarding_map_.end()) | 390 if (it == forwarding_map_.end()) |
309 return false; | 391 return false; |
310 | 392 |
311 std::string location = it->second; | 393 std::string location = it->second; |
312 | 394 |
313 SocketTunnel* tunnel = new SocketTunnel(location); | 395 SocketTunnel* tunnel = new SocketTunnel(location, |
396 base::Bind(&TetheringAdbFilter::UpdateSocketCount, | |
397 weak_factory_.GetWeakPtr(), | |
398 port)); | |
399 | |
314 std::string command = base::StringPrintf(kLocalAbstractCommand, | 400 std::string command = base::StringPrintf(kLocalAbstractCommand, |
315 connection_id.c_str()); | 401 connection_id.c_str()); |
316 AdbClientSocket::TransportQuery( | 402 AdbClientSocket::TransportQuery( |
317 adb_port_, serial_, command, | 403 adb_port_, serial_, command, |
318 base::Bind(&SocketTunnel::Start, base::Unretained(tunnel))); | 404 base::Bind(&SocketTunnel::Start, base::Unretained(tunnel))); |
319 return true; | 405 return true; |
320 } | 406 } |
321 | 407 |
322 class PortForwardingController::Connection : public AdbWebSocket::Delegate { | 408 class PortForwardingController::Connection : public AdbWebSocket::Delegate { |
323 public: | 409 public: |
324 Connection( | 410 Connection( |
325 Registry* registry, | 411 Registry* registry, |
326 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, | 412 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, |
327 base::MessageLoop* adb_message_loop, | 413 base::MessageLoop* adb_message_loop, |
328 PrefService* pref_service); | 414 PrefService* pref_service); |
329 | 415 |
330 void Shutdown(); | 416 void Shutdown(); |
331 | 417 |
418 TetheringAdbFilter::PortStatusMap port_status(); | |
419 | |
332 private: | 420 private: |
333 virtual ~Connection(); | 421 virtual ~Connection(); |
334 | 422 |
335 virtual void OnSocketOpened() OVERRIDE; | 423 virtual void OnSocketOpened() OVERRIDE; |
336 virtual void OnFrameRead(const std::string& message) OVERRIDE; | 424 virtual void OnFrameRead(const std::string& message) OVERRIDE; |
337 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE; | 425 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE; |
338 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE; | 426 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE; |
339 | 427 |
340 Registry* registry_; | 428 Registry* registry_; |
341 const std::string serial_; | 429 const std::string serial_; |
(...skipping 18 matching lines...) Expand all Loading... | |
360 device, kDevToolsRemoteSocketName, kDevToolsRemoteBrowserTarget, | 448 device, kDevToolsRemoteSocketName, kDevToolsRemoteBrowserTarget, |
361 adb_message_loop_, this); | 449 adb_message_loop_, this); |
362 } | 450 } |
363 | 451 |
364 void PortForwardingController::Connection::Shutdown() { | 452 void PortForwardingController::Connection::Shutdown() { |
365 registry_ = NULL; | 453 registry_ = NULL; |
366 // This will have no effect if the socket is not connected yet. | 454 // This will have no effect if the socket is not connected yet. |
367 web_socket_->Disconnect(); | 455 web_socket_->Disconnect(); |
368 } | 456 } |
369 | 457 |
458 TetheringAdbFilter::PortStatusMap | |
459 PortForwardingController::Connection::port_status() { | |
460 if (tethering_adb_filter_) | |
461 return tethering_adb_filter_->port_status(); | |
462 else | |
463 return TetheringAdbFilter::PortStatusMap(); | |
464 } | |
465 | |
370 PortForwardingController::Connection::~Connection() { | 466 PortForwardingController::Connection::~Connection() { |
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
372 if (registry_) { | 468 if (registry_) { |
373 DCHECK(registry_->find(serial_) != registry_->end()); | 469 DCHECK(registry_->find(serial_) != registry_->end()); |
374 registry_->erase(serial_); | 470 registry_->erase(serial_); |
375 } | 471 } |
376 } | 472 } |
377 | 473 |
378 void PortForwardingController::Connection::OnSocketOpened() { | 474 void PortForwardingController::Connection::OnSocketOpened() { |
379 if (!registry_) { | 475 if (!registry_) { |
(...skipping 27 matching lines...) Expand all Loading... | |
407 : adb_message_loop_(adb_message_loop), | 503 : adb_message_loop_(adb_message_loop), |
408 pref_service_(pref_service) { | 504 pref_service_(pref_service) { |
409 } | 505 } |
410 | 506 |
411 PortForwardingController::~PortForwardingController() { | 507 PortForwardingController::~PortForwardingController() { |
412 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it) | 508 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it) |
413 it->second->Shutdown(); | 509 it->second->Shutdown(); |
414 } | 510 } |
415 | 511 |
416 void PortForwardingController::UpdateDeviceList( | 512 void PortForwardingController::UpdateDeviceList( |
417 const DevToolsAdbBridge::RemoteDevices& devices) { | 513 DevToolsAdbBridge::RemoteDevices& devices) { |
418 for (DevToolsAdbBridge::RemoteDevices::const_iterator it = devices.begin(); | 514 for (DevToolsAdbBridge::RemoteDevices::iterator it = devices.begin(); |
419 it != devices.end(); ++it) { | 515 it != devices.end(); ++it) { |
420 if (registry_.find((*it)->serial()) == registry_.end()) { | 516 Registry::iterator rit = registry_.find((*it)->serial()); |
517 if (rit == registry_.end()) { | |
421 // Will delete itself when disconnected. | 518 // Will delete itself when disconnected. |
422 new Connection( | 519 new Connection( |
423 ®istry_, (*it)->device(), adb_message_loop_, pref_service_); | 520 ®istry_, (*it)->device(), adb_message_loop_, pref_service_); |
521 } else { | |
522 (*it)->SetPortStatus((*rit).second->port_status()); | |
424 } | 523 } |
425 } | 524 } |
426 } | 525 } |
OLD | NEW |