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

Side by Side Diff: chrome/browser/devtools/device/port_forwarding_controller.cc

Issue 449883002: DevTools: Removed refcounting from AndroidWebSocket (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/device/port_forwarding_controller.h" 5 #include "chrome/browser/devtools/device/port_forwarding_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 const int kMinVersionPortForwarding = 28; 52 const int kMinVersionPortForwarding = 28;
53 53
54 class SocketTunnel : public base::NonThreadSafe { 54 class SocketTunnel : public base::NonThreadSafe {
55 public: 55 public:
56 typedef base::Callback<void(int)> CounterCallback; 56 typedef base::Callback<void(int)> CounterCallback;
57 57
58 static void StartTunnel(const std::string& host, 58 static void StartTunnel(const std::string& host,
59 int port, 59 int port,
60 const CounterCallback& callback, 60 const CounterCallback& callback,
61 int result, 61 int result,
62 net::StreamSocket* socket) { 62 scoped_ptr<net::StreamSocket> socket) {
63 if (result < 0) 63 if (result < 0)
64 return; 64 return;
65 SocketTunnel* tunnel = new SocketTunnel(callback); 65 SocketTunnel* tunnel = new SocketTunnel(callback);
66 tunnel->Start(socket, host, port); 66 tunnel->Start(socket.Pass(), host, port);
67 } 67 }
68 68
69 private: 69 private:
70 explicit SocketTunnel(const CounterCallback& callback) 70 explicit SocketTunnel(const CounterCallback& callback)
71 : pending_writes_(0), 71 : pending_writes_(0),
72 pending_destruction_(false), 72 pending_destruction_(false),
73 callback_(callback), 73 callback_(callback),
74 about_to_destroy_(false) { 74 about_to_destroy_(false) {
75 callback_.Run(1); 75 callback_.Run(1);
76 } 76 }
77 77
78 void Start(net::StreamSocket* socket, const std::string& host, int port) { 78 void Start(scoped_ptr<net::StreamSocket> socket,
79 remote_socket_.reset(socket); 79 const std::string& host, int port) {
80 remote_socket_.swap(socket);
80 81
81 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL); 82 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
82 net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); 83 net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port));
83 int result = host_resolver_->Resolve( 84 int result = host_resolver_->Resolve(
84 request_info, 85 request_info,
85 net::DEFAULT_PRIORITY, 86 net::DEFAULT_PRIORITY,
86 &address_list_, 87 &address_list_,
87 base::Bind(&SocketTunnel::OnResolved, base::Unretained(this)), 88 base::Bind(&SocketTunnel::OnResolved, base::Unretained(this)),
88 NULL, 89 NULL,
89 net::BoundNetLog()); 90 net::BoundNetLog());
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 best_browser = browser; 248 best_browser = browser;
248 newest_version = current_version; 249 newest_version = current_version;
249 } 250 }
250 } 251 }
251 return best_browser; 252 return best_browser;
252 } 253 }
253 254
254 } // namespace 255 } // namespace
255 256
256 class PortForwardingController::Connection 257 class PortForwardingController::Connection
257 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate, 258 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate {
258 public base::RefCountedThreadSafe<
259 Connection,
260 content::BrowserThread::DeleteOnUIThread> {
261 public: 259 public:
262 Connection(Registry* registry, 260 Connection(Registry* registry,
263 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device, 261 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device,
264 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 262 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
265 const ForwardingMap& forwarding_map); 263 const ForwardingMap& forwarding_map);
264 virtual ~Connection();
266 265
267 const PortStatusMap& GetPortStatusMap(); 266 const PortStatusMap& GetPortStatusMap();
268 267
269 void UpdateForwardingMap(const ForwardingMap& new_forwarding_map); 268 void UpdateForwardingMap(const ForwardingMap& new_forwarding_map);
270 269
271 void Shutdown(); 270 void Shutdown();
272 271
273 private: 272 private:
274 friend struct content::BrowserThread::DeleteOnThread< 273 friend struct content::BrowserThread::DeleteOnThread<
275 content::BrowserThread::UI>; 274 content::BrowserThread::UI>;
276 friend class base::DeleteHelper<Connection>; 275 friend class base::DeleteHelper<Connection>;
277 276
278 virtual ~Connection();
279 277
280 typedef std::map<int, std::string> ForwardingMap; 278 typedef std::map<int, std::string> ForwardingMap;
281 279
282 typedef base::Callback<void(PortStatus)> CommandCallback; 280 typedef base::Callback<void(PortStatus)> CommandCallback;
283 typedef std::map<int, CommandCallback> CommandCallbackMap; 281 typedef std::map<int, CommandCallback> CommandCallbackMap;
284 282
285 void SerializeChanges(const std::string& method, 283 void SerializeChanges(const std::string& method,
286 const ForwardingMap& old_map, 284 const ForwardingMap& old_map,
287 const ForwardingMap& new_map); 285 const ForwardingMap& new_map);
288 286
289 void SendCommand(const std::string& method, int port); 287 void SendCommand(const std::string& method, int port);
290 bool ProcessResponse(const std::string& json); 288 bool ProcessResponse(const std::string& json);
291 289
292 void ProcessBindResponse(int port, PortStatus status); 290 void ProcessBindResponse(int port, PortStatus status);
293 void ProcessUnbindResponse(int port, PortStatus status); 291 void ProcessUnbindResponse(int port, PortStatus status);
294 292
295 void UpdateSocketCountOnHandlerThread(int port, int increment); 293 static void UpdateSocketCountOnHandlerThread(
294 base::WeakPtr<Connection> weak_connection, int port, int increment);
296 void UpdateSocketCount(int port, int increment); 295 void UpdateSocketCount(int port, int increment);
297 296
298 // DevToolsAndroidBridge::AndroidWebSocket::Delegate implementation: 297 // DevToolsAndroidBridge::AndroidWebSocket::Delegate implementation:
299 virtual void OnSocketOpened() OVERRIDE; 298 virtual void OnSocketOpened() OVERRIDE;
300 virtual void OnFrameRead(const std::string& message) OVERRIDE; 299 virtual void OnFrameRead(const std::string& message) OVERRIDE;
301 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE; 300 virtual void OnSocketClosed() OVERRIDE;
302 301
303 PortForwardingController::Registry* registry_; 302 PortForwardingController::Registry* registry_;
304 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device_; 303 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device_;
305 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_; 304 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_;
306 scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_; 305 scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
307 int command_id_; 306 int command_id_;
308 bool connected_; 307 bool connected_;
309 ForwardingMap forwarding_map_; 308 ForwardingMap forwarding_map_;
310 CommandCallbackMap pending_responses_; 309 CommandCallbackMap pending_responses_;
311 PortStatusMap port_status_; 310 PortStatusMap port_status_;
311 base::WeakPtrFactory<Connection> weak_factory_;
312 312
313 DISALLOW_COPY_AND_ASSIGN(Connection); 313 DISALLOW_COPY_AND_ASSIGN(Connection);
314 }; 314 };
315 315
316 PortForwardingController::Connection::Connection( 316 PortForwardingController::Connection::Connection(
317 Registry* registry, 317 Registry* registry,
318 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device, 318 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device,
319 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 319 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
320 const ForwardingMap& forwarding_map) 320 const ForwardingMap& forwarding_map)
321 : registry_(registry), 321 : registry_(registry),
322 device_(device), 322 device_(device),
323 browser_(browser), 323 browser_(browser),
324 command_id_(0), 324 command_id_(0),
325 connected_(false), 325 connected_(false),
326 forwarding_map_(forwarding_map) { 326 forwarding_map_(forwarding_map),
327 weak_factory_(this) {
327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
328 (*registry_)[device_->serial()] = this; 329 (*registry_)[device_->serial()] = this;
329 web_socket_ = browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this); 330 web_socket_.reset(
330 web_socket_->Connect(); 331 browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this));
331 AddRef(); // Balanced in OnSocketClosed();
332 }
333
334 void PortForwardingController::Connection::Shutdown() {
335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
336 registry_ = NULL;
337 // This will have no effect if the socket is not connected yet.
338 web_socket_->Disconnect();
339 } 332 }
340 333
341 PortForwardingController::Connection::~Connection() { 334 PortForwardingController::Connection::~Connection() {
342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
343 if (registry_) { 336 DCHECK(registry_->find(device_->serial()) != registry_->end());
344 DCHECK(registry_->find(device_->serial()) != registry_->end()); 337 registry_->erase(device_->serial());
345 registry_->erase(device_->serial());
346 }
347 } 338 }
348 339
349 void PortForwardingController::Connection::UpdateForwardingMap( 340 void PortForwardingController::Connection::UpdateForwardingMap(
350 const ForwardingMap& new_forwarding_map) { 341 const ForwardingMap& new_forwarding_map) {
351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
352 if (connected_) { 343 if (connected_) {
353 SerializeChanges(kTetheringUnbind, new_forwarding_map, forwarding_map_); 344 SerializeChanges(kTetheringUnbind, new_forwarding_map, forwarding_map_);
354 SerializeChanges(kTetheringBind, forwarding_map_, new_forwarding_map); 345 SerializeChanges(kTetheringBind, forwarding_map_, new_forwarding_map);
355 } 346 }
356 forwarding_map_ = new_forwarding_map; 347 forwarding_map_ = new_forwarding_map;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 int port, PortStatus status) { 424 int port, PortStatus status) {
434 PortStatusMap::iterator it = port_status_.find(port); 425 PortStatusMap::iterator it = port_status_.find(port);
435 if (it == port_status_.end()) 426 if (it == port_status_.end())
436 return; 427 return;
437 if (status == kStatusError) 428 if (status == kStatusError)
438 it->second = status; 429 it->second = status;
439 else 430 else
440 port_status_.erase(it); 431 port_status_.erase(it);
441 } 432 }
442 433
434 // static
443 void PortForwardingController::Connection::UpdateSocketCountOnHandlerThread( 435 void PortForwardingController::Connection::UpdateSocketCountOnHandlerThread(
444 int port, int increment) { 436 base::WeakPtr<Connection> weak_connection, int port, int increment) {
445 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 437 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
446 base::Bind(&Connection::UpdateSocketCount, this, port, increment)); 438 base::Bind(&Connection::UpdateSocketCount,
439 weak_connection, port, increment));
447 } 440 }
448 441
449 void PortForwardingController::Connection::UpdateSocketCount( 442 void PortForwardingController::Connection::UpdateSocketCount(
450 int port, int increment) { 443 int port, int increment) {
451 #if defined(DEBUG_DEVTOOLS) 444 #if defined(DEBUG_DEVTOOLS)
452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
453 PortStatusMap::iterator it = port_status_.find(port); 446 PortStatusMap::iterator it = port_status_.find(port);
454 if (it == port_status_.end()) 447 if (it == port_status_.end())
455 return; 448 return;
456 if (it->second < 0 || (it->second == 0 && increment < 0)) 449 if (it->second < 0 || (it->second == 0 && increment < 0))
457 return; 450 return;
458 it->second += increment; 451 it->second += increment;
459 #endif // defined(DEBUG_DEVTOOLS) 452 #endif // defined(DEBUG_DEVTOOLS)
460 } 453 }
461 454
462 const PortForwardingController::PortStatusMap& 455 const PortForwardingController::PortStatusMap&
463 PortForwardingController::Connection::GetPortStatusMap() { 456 PortForwardingController::Connection::GetPortStatusMap() {
464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 457 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
465 return port_status_; 458 return port_status_;
466 } 459 }
467 460
468 void PortForwardingController::Connection::OnSocketOpened() { 461 void PortForwardingController::Connection::OnSocketOpened() {
469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
470 if (!registry_) {
471 // Socket was created after Shutdown was called. Disconnect immediately.
472 web_socket_->Disconnect();
473 return;
474 }
475 connected_ = true; 463 connected_ = true;
476 SerializeChanges(kTetheringBind, ForwardingMap(), forwarding_map_); 464 SerializeChanges(kTetheringBind, ForwardingMap(), forwarding_map_);
477 } 465 }
478 466
479 void PortForwardingController::Connection::OnSocketClosed( 467 void PortForwardingController::Connection::OnSocketClosed() {
480 bool closed_by_device) { 468 delete this;
481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
482 Release(); // Balanced in the constructor.
483 } 469 }
484 470
485 void PortForwardingController::Connection::OnFrameRead( 471 void PortForwardingController::Connection::OnFrameRead(
486 const std::string& message) { 472 const std::string& message) {
487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
488 if (ProcessResponse(message)) 474 if (ProcessResponse(message))
489 return; 475 return;
490 476
491 scoped_ptr<DevToolsProtocol::Notification> notification( 477 scoped_ptr<DevToolsProtocol::Notification> notification(
492 DevToolsProtocol::ParseNotification(message)); 478 DevToolsProtocol::ParseNotification(message));
(...skipping 19 matching lines...) Expand all
512 498
513 std::string location = it->second; 499 std::string location = it->second;
514 std::vector<std::string> tokens; 500 std::vector<std::string> tokens;
515 Tokenize(location, ":", &tokens); 501 Tokenize(location, ":", &tokens);
516 int destination_port = 0; 502 int destination_port = 0;
517 if (tokens.size() != 2 || !base::StringToInt(tokens[1], &destination_port)) 503 if (tokens.size() != 2 || !base::StringToInt(tokens[1], &destination_port))
518 return; 504 return;
519 std::string destination_host = tokens[0]; 505 std::string destination_host = tokens[0];
520 506
521 SocketTunnel::CounterCallback callback = 507 SocketTunnel::CounterCallback callback =
522 base::Bind(&Connection::UpdateSocketCountOnHandlerThread, this, port); 508 base::Bind(&Connection::UpdateSocketCountOnHandlerThread,
509 weak_factory_.GetWeakPtr(), port);
523 510
524 device_->OpenSocket( 511 device_->OpenSocket(
525 connection_id.c_str(), 512 connection_id.c_str(),
526 base::Bind(&SocketTunnel::StartTunnel, 513 base::Bind(&SocketTunnel::StartTunnel,
527 destination_host, 514 destination_host,
528 destination_port, 515 destination_port,
529 callback)); 516 callback));
530 } 517 }
531 518
532 PortForwardingController::PortForwardingController(Profile* profile) 519 PortForwardingController::PortForwardingController(Profile* profile)
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 dict->GetString(it.key(), &location)) 586 dict->GetString(it.key(), &location))
600 forwarding_map_[port_num] = location; 587 forwarding_map_[port_num] = location;
601 } 588 }
602 } 589 }
603 590
604 if (!forwarding_map_.empty()) { 591 if (!forwarding_map_.empty()) {
605 StartListening(); 592 StartListening();
606 UpdateConnections(); 593 UpdateConnections();
607 } else { 594 } else {
608 StopListening(); 595 StopListening();
609 ShutdownConnections(); 596 STLDeleteValues(&registry_);
vkuzkokov 2014/09/23 13:50:22 FYI, this is the place where crash happened: delet
610 NotifyListeners(DevicesStatus()); 597 NotifyListeners(DevicesStatus());
611 } 598 }
612 } 599 }
613 600
614 void PortForwardingController::StartListening() { 601 void PortForwardingController::StartListening() {
615 if (listening_) 602 if (listening_)
616 return; 603 return;
617 listening_ = true; 604 listening_ = true;
618 DevToolsAndroidBridge* android_bridge = 605 DevToolsAndroidBridge* android_bridge =
619 DevToolsAndroidBridge::Factory::GetForProfile(profile_); 606 DevToolsAndroidBridge::Factory::GetForProfile(profile_);
(...skipping 10 matching lines...) Expand all
630 DevToolsAndroidBridge::Factory::GetForProfile(profile_); 617 DevToolsAndroidBridge::Factory::GetForProfile(profile_);
631 if (android_bridge) 618 if (android_bridge)
632 android_bridge->RemoveDeviceListListener(this); 619 android_bridge->RemoveDeviceListListener(this);
633 } 620 }
634 621
635 void PortForwardingController::UpdateConnections() { 622 void PortForwardingController::UpdateConnections() {
636 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it) 623 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it)
637 it->second->UpdateForwardingMap(forwarding_map_); 624 it->second->UpdateForwardingMap(forwarding_map_);
638 } 625 }
639 626
640 void PortForwardingController::ShutdownConnections() {
641 for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it)
642 it->second->Shutdown();
643 registry_.clear();
644 }
645
646 void PortForwardingController::NotifyListeners( 627 void PortForwardingController::NotifyListeners(
647 const DevicesStatus& status) const { 628 const DevicesStatus& status) const {
648 Listeners copy(listeners_); // Iterate over copy. 629 Listeners copy(listeners_); // Iterate over copy.
649 for (Listeners::const_iterator it = copy.begin(); it != copy.end(); ++it) 630 for (Listeners::const_iterator it = copy.begin(); it != copy.end(); ++it)
650 (*it)->PortStatusChanged(status); 631 (*it)->PortStatusChanged(status);
651 } 632 }
652 633
653 // static 634 // static
654 PortForwardingController::Factory* 635 PortForwardingController::Factory*
655 PortForwardingController::Factory::GetInstance() { 636 PortForwardingController::Factory::GetInstance() {
(...skipping 12 matching lines...) Expand all
668 "PortForwardingController", 649 "PortForwardingController",
669 BrowserContextDependencyManager::GetInstance()) {} 650 BrowserContextDependencyManager::GetInstance()) {}
670 651
671 PortForwardingController::Factory::~Factory() {} 652 PortForwardingController::Factory::~Factory() {}
672 653
673 KeyedService* PortForwardingController::Factory::BuildServiceInstanceFor( 654 KeyedService* PortForwardingController::Factory::BuildServiceInstanceFor(
674 content::BrowserContext* context) const { 655 content::BrowserContext* context) const {
675 Profile* profile = Profile::FromBrowserContext(context); 656 Profile* profile = Profile::FromBrowserContext(context);
676 return new PortForwardingController(profile); 657 return new PortForwardingController(profile);
677 } 658 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698