| // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/debugger/devtools_protocol_handler.h" |
| |
| #include "base/logging.h" |
| #include "chrome/browser/debugger/inspectable_tab_proxy.h" |
| #include "chrome/browser/debugger/debugger_remote_service.h" |
| #include "chrome/browser/debugger/devtools_remote_message.h" |
| #include "chrome/browser/debugger/devtools_remote_listen_socket.h" |
| #include "chrome/browser/debugger/devtools_remote_service.h" |
| #include "chrome/browser/debugger/extension_ports_remote_service.h" |
| #include "content/browser/browser_thread.h" |
| |
| // static |
| scoped_refptr<DevToolsProtocolHandler> DevToolsProtocolHandler::Start( |
| int port) { |
| scoped_refptr<DevToolsProtocolHandler> proto_handler = |
| new DevToolsProtocolHandler(port); |
| proto_handler->RegisterDestination( |
| new DevToolsRemoteService(proto_handler), |
| DevToolsRemoteService::kToolName); |
| proto_handler->RegisterDestination( |
| new DebuggerRemoteService(proto_handler), |
| DebuggerRemoteService::kToolName); |
| proto_handler->RegisterDestination( |
| new ExtensionPortsRemoteService(proto_handler), |
| ExtensionPortsRemoteService::kToolName); |
| proto_handler->Start(); |
| return proto_handler; |
| } |
| |
| DevToolsProtocolHandler::DevToolsProtocolHandler(int port) |
| : port_(port), |
| connection_(NULL), |
| server_(NULL) { |
| inspectable_tab_proxy_.reset(new InspectableTabProxy); |
| } |
| |
| DevToolsProtocolHandler::~DevToolsProtocolHandler() { |
| // Stop() must be called prior to this being called |
| DCHECK(server_.get() == NULL); |
| DCHECK(connection_.get() == NULL); |
| } |
| |
| void DevToolsProtocolHandler::Start() { |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| NewRunnableMethod(this, &DevToolsProtocolHandler::Init)); |
| } |
| |
| void DevToolsProtocolHandler::Init() { |
| server_ = DevToolsRemoteListenSocket::Listen( |
| "127.0.0.1", port_, this); |
| } |
| |
| void DevToolsProtocolHandler::Stop() { |
| BrowserThread::PostTask( |
| BrowserThread::IO, FROM_HERE, |
| NewRunnableMethod(this, &DevToolsProtocolHandler::Teardown)); |
| tool_to_listener_map_.clear(); // Releases all scoped_refptr's to listeners |
| } |
| |
| // Run in I/O thread |
| void DevToolsProtocolHandler::Teardown() { |
| connection_ = NULL; |
| server_ = NULL; |
| } |
| |
| void DevToolsProtocolHandler::RegisterDestination( |
| DevToolsRemoteListener* listener, |
| const std::string& tool_name) { |
| DCHECK(tool_to_listener_map_.find(tool_name) == tool_to_listener_map_.end()); |
| tool_to_listener_map_.insert(std::make_pair(tool_name, listener)); |
| } |
| |
| void DevToolsProtocolHandler::UnregisterDestination( |
| DevToolsRemoteListener* listener, |
| const std::string& tool_name) { |
| DCHECK(tool_to_listener_map_.find(tool_name) != tool_to_listener_map_.end()); |
| DCHECK(tool_to_listener_map_.find(tool_name)->second == listener); |
| tool_to_listener_map_.erase(tool_name); |
| } |
| |
| void DevToolsProtocolHandler::HandleMessage( |
| const DevToolsRemoteMessage& message) { |
| std::string tool = message.GetHeaderWithEmptyDefault( |
| DevToolsRemoteMessageHeaders::kTool); |
| ToolToListenerMap::const_iterator it = tool_to_listener_map_.find(tool); |
| if (it == tool_to_listener_map_.end()) { |
| NOTREACHED(); // an unsupported tool, bail out |
| return; |
| } |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| NewRunnableMethod( |
| it->second.get(), &DevToolsRemoteListener::HandleMessage, message)); |
| } |
| |
| void DevToolsProtocolHandler::Send(const DevToolsRemoteMessage& message) { |
| if (connection_ != NULL) { |
| connection_->Send(message.ToString()); |
| } |
| } |
| |
| void DevToolsProtocolHandler::OnAcceptConnection(ListenSocket *connection) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| connection_ = connection; |
| } |
| |
| void DevToolsProtocolHandler::OnConnectionLost() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| connection_ = NULL; |
| for (ToolToListenerMap::const_iterator it = tool_to_listener_map_.begin(), |
| end = tool_to_listener_map_.end(); |
| it != end; |
| ++it) { |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| NewRunnableMethod( |
| it->second.get(), &DevToolsRemoteListener::OnConnectionLost)); |
| } |
| } |