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

Side by Side Diff: chrome/browser/devtools/tethering_adb_filter.cc

Issue 22685003: Visualize status of port forwarding sockets in chrome:inspect Devices tab (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 4 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
OLDNEW
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 12 matching lines...) Expand all
23 #include "net/base/net_util.h" 23 #include "net/base/net_util.h"
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 kBufferSize = 16 * 1024; 31 const int kBufferSize = 16 * 1024;
32 32
33 enum {
34 kStatusError = -3,
35 kStatusDisconnecting = -2,
36 kStatusConnecting = -1,
37 kStatusOK = 0,
38 // Positive values are used to count open connections.
39 };
40
33 static const char kPortAttribute[] = "port"; 41 static const char kPortAttribute[] = "port";
34 static const char kConnectionIdAttribute[] = "connectionId"; 42 static const char kConnectionIdAttribute[] = "connectionId";
35 static const char kTetheringAccepted[] = "Tethering.accepted"; 43 static const char kTetheringAccepted[] = "Tethering.accepted";
36 static const char kTetheringBind[] = "Tethering.bind"; 44 static const char kTetheringBind[] = "Tethering.bind";
37 static const char kTetheringUnbind[] = "Tethering.unbind"; 45 static const char kTetheringUnbind[] = "Tethering.unbind";
38 46
39 static const char kDevToolsRemoteSocketName[] = "chrome_devtools_remote"; 47 static const char kDevToolsRemoteSocketName[] = "chrome_devtools_remote";
40 static const char kDevToolsRemoteBrowserTarget[] = "/devtools/browser"; 48 static const char kDevToolsRemoteBrowserTarget[] = "/devtools/browser";
41 49
42 class SocketTunnel { 50 class SocketTunnel {
43 public: 51 public:
44 explicit SocketTunnel(const std::string& location) 52 typedef base::Callback<void(int)> CounterCallback;
53
54 SocketTunnel(const std::string& location, const CounterCallback& callback)
45 : location_(location), 55 : location_(location),
46 pending_writes_(0), 56 pending_writes_(0),
47 pending_destruction_(false) { 57 pending_destruction_(false),
58 callback_(callback) {
59 callback_.Run(1);
48 } 60 }
49 61
50 void Start(int result, net::StreamSocket* socket) { 62 void Start(int result, net::StreamSocket* socket) {
51 if (result < 0) { 63 if (result < 0) {
52 SelfDestruct(); 64 SelfDestruct();
53 return; 65 return;
54 } 66 }
55 remote_socket_.reset(socket); 67 remote_socket_.reset(socket);
56 68
57 std::vector<std::string> tokens; 69 std::vector<std::string> tokens;
(...skipping 28 matching lines...) Expand all
86 base::Unretained(this))); 98 base::Unretained(this)));
87 if (result != net::ERR_IO_PENDING) 99 if (result != net::ERR_IO_PENDING)
88 OnConnected(result); 100 OnConnected(result);
89 } 101 }
90 102
91 ~SocketTunnel() { 103 ~SocketTunnel() {
92 if (host_socket_) 104 if (host_socket_)
93 host_socket_->Disconnect(); 105 host_socket_->Disconnect();
94 if (remote_socket_) 106 if (remote_socket_)
95 remote_socket_->Disconnect(); 107 remote_socket_->Disconnect();
108 callback_.Run(-1);
96 } 109 }
97 110
98 void OnConnected(int result) { 111 void OnConnected(int result) {
99 if (result < 0) { 112 if (result < 0) {
100 SelfDestruct(); 113 SelfDestruct();
101 return; 114 return;
102 } 115 }
103 116
104 Pump(host_socket_.get(), remote_socket_.get()); 117 Pump(host_socket_.get(), remote_socket_.get());
105 Pump(remote_socket_.get(), host_socket_.get()); 118 Pump(remote_socket_.get(), host_socket_.get());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 delete this; 194 delete this;
182 } 195 }
183 196
184 std::string location_; 197 std::string location_;
185 scoped_ptr<net::StreamSocket> remote_socket_; 198 scoped_ptr<net::StreamSocket> remote_socket_;
186 scoped_ptr<net::StreamSocket> host_socket_; 199 scoped_ptr<net::StreamSocket> host_socket_;
187 scoped_ptr<net::HostResolver> host_resolver_; 200 scoped_ptr<net::HostResolver> host_resolver_;
188 net::AddressList address_list_; 201 net::AddressList address_list_;
189 int pending_writes_; 202 int pending_writes_;
190 bool pending_destruction_; 203 bool pending_destruction_;
204 CounterCallback callback_;
191 }; 205 };
192 206
193 } // namespace 207 } // namespace
194 208
195 TetheringAdbFilter::TetheringAdbFilter( 209 TetheringAdbFilter::TetheringAdbFilter(
196 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, 210 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device,
197 base::MessageLoop* adb_message_loop, 211 base::MessageLoop* adb_message_loop,
198 PrefService* pref_service, 212 PrefService* pref_service,
199 scoped_refptr<AdbWebSocket> web_socket) 213 scoped_refptr<AdbWebSocket> web_socket)
200 : device_(device), 214 : device_(device),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 continue; // The port points to the same location in both configs, skip. 279 continue; // The port points to the same location in both configs, skip.
266 280
267 SendCommand(method, port); 281 SendCommand(method, port);
268 } 282 }
269 } 283 }
270 284
271 void TetheringAdbFilter::SendCommand(const std::string& method, int port) { 285 void TetheringAdbFilter::SendCommand(const std::string& method, int port) {
272 base::DictionaryValue params; 286 base::DictionaryValue params;
273 params.SetInteger(kPortAttribute, port); 287 params.SetInteger(kPortAttribute, port);
274 DevToolsProtocol::Command command(++command_id_, method, &params); 288 DevToolsProtocol::Command command(++command_id_, method, &params);
289
290 if (method == kTetheringBind) {
291 pending_responses_[command.id()] =
292 base::Bind(&TetheringAdbFilter::ProcessBindResponse,
293 weak_factory_.GetWeakPtr(), port);
294 #if defined(DEBUG_DEVTOOLS)
295 port_status_[port] = kStatusConnecting;
296 UpdatePortStatusMap();
297 #endif // defined(DEBUG_DEVTOOLS)
298 } else {
299 DCHECK_EQ(kTetheringUnbind, method);
300
301 PortStatusMap::iterator it = port_status_.find(port);
302 if (it != port_status_.end() && it->second == kStatusError) {
303 // The bind command failed on this port, do not attempt unbind.
304 port_status_.erase(it);
305 UpdatePortStatusMap();
306 return;
307 }
308
309 pending_responses_[command.id()] =
310 base::Bind(&TetheringAdbFilter::ProcessUnbindResponse,
311 weak_factory_.GetWeakPtr(), port);
312 #if defined(DEBUG_DEVTOOLS)
313 port_status_[port] = kStatusDisconnecting;
314 UpdatePortStatusMap();
315 #endif // defined(DEBUG_DEVTOOLS)
316 }
317
275 web_socket_->SendFrameOnHandlerThread(command.Serialize()); 318 web_socket_->SendFrameOnHandlerThread(command.Serialize());
276 } 319 }
277 320
321 bool TetheringAdbFilter::ProcessResponse(const std::string& message) {
322 scoped_ptr<DevToolsProtocol::Response> response(
323 DevToolsProtocol::ParseResponse(message));
324 if (!response)
325 return false;
326
327 CommandCallbackMap::iterator it = pending_responses_.find(response->id());
328 if (it == pending_responses_.end())
329 return false;
330
331 it->second.Run(response->error_code() ? kStatusError : kStatusOK);
332 pending_responses_.erase(it);
333 return true;
334 }
335
336 void TetheringAdbFilter::ProcessBindResponse(int port, PortStatus status) {
337 port_status_[port] = status;
338 UpdatePortStatusMap();
339 }
340
341 void TetheringAdbFilter::ProcessUnbindResponse(int port, PortStatus status) {
342 PortStatusMap::iterator it = port_status_.find(port);
343 if (it == port_status_.end())
344 return;
345 if (status == kStatusError)
346 it->second = status;
347 else
348 port_status_.erase(it);
349 UpdatePortStatusMap();
350 }
351
352 void TetheringAdbFilter::UpdateSocketCount(int port, int increment) {
353 #if defined(DEBUG_DEVTOOLS)
354 PortStatusMap::iterator it = port_status_.find(port);
355 if (it == port_status_.end())
356 return;
357 if (it->second < 0 || (it->second == 0 && increment < 0))
358 return;
359 it->second += increment;
360 UpdatePortStatusMap();
361 #endif // defined(DEBUG_DEVTOOLS)
362 }
363
364 void TetheringAdbFilter::UpdatePortStatusMap() {
365 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
366 base::Bind(&TetheringAdbFilter::UpdatePortStatusMapOnUIThread,
367 weak_factory_.GetWeakPtr(), port_status_));
368 }
369
370 void TetheringAdbFilter::UpdatePortStatusMapOnUIThread(
371 const PortStatusMap& status_map) {
372 port_status_on_ui_thread_ = status_map;
373 }
374
375 const TetheringAdbFilter::PortStatusMap&
376 TetheringAdbFilter::GetPortStatusMap() {
377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
378 return port_status_on_ui_thread_;
379 }
380
278 bool TetheringAdbFilter::ProcessIncomingMessage(const std::string& message) { 381 bool TetheringAdbFilter::ProcessIncomingMessage(const std::string& message) {
279 DCHECK_EQ(base::MessageLoop::current(), adb_message_loop_); 382 DCHECK_EQ(base::MessageLoop::current(), adb_message_loop_);
280 383
281 // Only parse messages that might be Tethering.accepted event. 384 if (ProcessResponse(message))
282 if (message.length() > 200 || 385 return true;
283 message.find(kTetheringAccepted) == std::string::npos)
284 return false;
285 386
286 scoped_ptr<DevToolsProtocol::Notification> notification( 387 scoped_ptr<DevToolsProtocol::Notification> notification(
287 DevToolsProtocol::ParseNotification(message)); 388 DevToolsProtocol::ParseNotification(message));
288 if (!notification) 389 if (!notification)
289 return false; 390 return false;
290 391
291 if (notification->method() != kTetheringAccepted) 392 if (notification->method() != kTetheringAccepted)
292 return false; 393 return false;
293 394
294 DictionaryValue* params = notification->params(); 395 DictionaryValue* params = notification->params();
295 if (!params) 396 if (!params)
296 return false; 397 return false;
297 398
298 int port; 399 int port;
299 std::string connection_id; 400 std::string connection_id;
300 if (!params->GetInteger(kPortAttribute, &port) || 401 if (!params->GetInteger(kPortAttribute, &port) ||
301 !params->GetString(kConnectionIdAttribute, &connection_id)) 402 !params->GetString(kConnectionIdAttribute, &connection_id))
302 return false; 403 return false;
303 404
304 std::map<int, std::string>::iterator it = forwarding_map_.find(port); 405 std::map<int, std::string>::iterator it = forwarding_map_.find(port);
305 if (it == forwarding_map_.end()) 406 if (it == forwarding_map_.end())
306 return false; 407 return false;
307 408
308 std::string location = it->second; 409 std::string location = it->second;
309 410
310 SocketTunnel* tunnel = new SocketTunnel(location); 411 SocketTunnel* tunnel = new SocketTunnel(location,
412 base::Bind(&TetheringAdbFilter::UpdateSocketCount,
413 weak_factory_.GetWeakPtr(),
414 port));
415
311 device_->OpenSocket(connection_id.c_str(), 416 device_->OpenSocket(connection_id.c_str(),
312 base::Bind(&SocketTunnel::Start, base::Unretained(tunnel))); 417 base::Bind(&SocketTunnel::Start, base::Unretained(tunnel)));
313 return true; 418 return true;
314 } 419 }
315 420
316 class PortForwardingController::Connection : public AdbWebSocket::Delegate { 421 class PortForwardingController::Connection : public AdbWebSocket::Delegate {
317 public: 422 public:
318 Connection( 423 Connection(
319 Registry* registry, 424 Registry* registry,
320 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, 425 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device,
321 base::MessageLoop* adb_message_loop, 426 base::MessageLoop* adb_message_loop,
322 PrefService* pref_service); 427 PrefService* pref_service);
323 428
324 void Shutdown(); 429 void Shutdown();
325 430
431 TetheringAdbFilter::PortStatusMap port_status();
432
326 private: 433 private:
327 virtual ~Connection(); 434 virtual ~Connection();
328 435
329 virtual void OnSocketOpened() OVERRIDE; 436 virtual void OnSocketOpened() OVERRIDE;
330 virtual void OnFrameRead(const std::string& message) OVERRIDE; 437 virtual void OnFrameRead(const std::string& message) OVERRIDE;
331 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE; 438 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
332 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE; 439 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE;
333 440
334 Registry* registry_; 441 Registry* registry_;
335 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device_; 442 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device_;
(...skipping 18 matching lines...) Expand all
354 device, kDevToolsRemoteSocketName, kDevToolsRemoteBrowserTarget, 461 device, kDevToolsRemoteSocketName, kDevToolsRemoteBrowserTarget,
355 adb_message_loop_, this); 462 adb_message_loop_, this);
356 } 463 }
357 464
358 void PortForwardingController::Connection::Shutdown() { 465 void PortForwardingController::Connection::Shutdown() {
359 registry_ = NULL; 466 registry_ = NULL;
360 // This will have no effect if the socket is not connected yet. 467 // This will have no effect if the socket is not connected yet.
361 web_socket_->Disconnect(); 468 web_socket_->Disconnect();
362 } 469 }
363 470
471 TetheringAdbFilter::PortStatusMap
472 PortForwardingController::Connection::port_status() {
473 if (tethering_adb_filter_)
474 return tethering_adb_filter_->GetPortStatusMap();
475 else
476 return TetheringAdbFilter::PortStatusMap();
477 }
478
364 PortForwardingController::Connection::~Connection() { 479 PortForwardingController::Connection::~Connection() {
365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
366 if (registry_) { 481 if (registry_) {
367 DCHECK(registry_->find(device_->serial()) != registry_->end()); 482 DCHECK(registry_->find(device_->serial()) != registry_->end());
368 registry_->erase(device_->serial()); 483 registry_->erase(device_->serial());
369 } 484 }
370 } 485 }
371 486
372 void PortForwardingController::Connection::OnSocketOpened() { 487 void PortForwardingController::Connection::OnSocketOpened() {
373 if (!registry_) { 488 if (!registry_) {
(...skipping 30 matching lines...) Expand all
404 519
405 PortForwardingController::~PortForwardingController() { 520 PortForwardingController::~PortForwardingController() {
406 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it) 521 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it)
407 it->second->Shutdown(); 522 it->second->Shutdown();
408 } 523 }
409 524
410 void PortForwardingController::UpdateDeviceList( 525 void PortForwardingController::UpdateDeviceList(
411 const DevToolsAdbBridge::RemoteDevices& devices) { 526 const DevToolsAdbBridge::RemoteDevices& devices) {
412 for (DevToolsAdbBridge::RemoteDevices::const_iterator it = devices.begin(); 527 for (DevToolsAdbBridge::RemoteDevices::const_iterator it = devices.begin();
413 it != devices.end(); ++it) { 528 it != devices.end(); ++it) {
414 if (registry_.find((*it)->serial()) == registry_.end()) { 529 Registry::iterator rit = registry_.find((*it)->serial());
530 if (rit == registry_.end()) {
415 // Will delete itself when disconnected. 531 // Will delete itself when disconnected.
416 new Connection( 532 new Connection(
417 &registry_, (*it)->device(), adb_message_loop_, pref_service_); 533 &registry_, (*it)->device(), adb_message_loop_, pref_service_);
534 } else {
535 (*it)->set_port_status((*rit).second->port_status());
418 } 536 }
419 } 537 }
420 } 538 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/tethering_adb_filter.h ('k') | chrome/browser/resources/inspect/inspect.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698