• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/debugger/devtools_protocol_handler.h"
6 
7 #include "base/logging.h"
8 #include "chrome/browser/debugger/inspectable_tab_proxy.h"
9 #include "chrome/browser/debugger/debugger_remote_service.h"
10 #include "chrome/browser/debugger/devtools_remote_message.h"
11 #include "chrome/browser/debugger/devtools_remote_listen_socket.h"
12 #include "chrome/browser/debugger/devtools_remote_service.h"
13 #include "chrome/browser/debugger/extension_ports_remote_service.h"
14 #include "content/browser/browser_thread.h"
15 
16 // static
Start(int port)17 scoped_refptr<DevToolsProtocolHandler> DevToolsProtocolHandler::Start(
18     int port) {
19   scoped_refptr<DevToolsProtocolHandler> proto_handler =
20       new DevToolsProtocolHandler(port);
21   proto_handler->RegisterDestination(
22       new DevToolsRemoteService(proto_handler),
23       DevToolsRemoteService::kToolName);
24   proto_handler->RegisterDestination(
25       new DebuggerRemoteService(proto_handler),
26       DebuggerRemoteService::kToolName);
27   proto_handler->RegisterDestination(
28       new ExtensionPortsRemoteService(proto_handler),
29       ExtensionPortsRemoteService::kToolName);
30   proto_handler->Start();
31   return proto_handler;
32 }
33 
DevToolsProtocolHandler(int port)34 DevToolsProtocolHandler::DevToolsProtocolHandler(int port)
35     : port_(port),
36       connection_(NULL),
37       server_(NULL) {
38   inspectable_tab_proxy_.reset(new InspectableTabProxy);
39 }
40 
~DevToolsProtocolHandler()41 DevToolsProtocolHandler::~DevToolsProtocolHandler() {
42   // Stop() must be called prior to this being called
43   DCHECK(server_.get() == NULL);
44   DCHECK(connection_.get() == NULL);
45 }
46 
Start()47 void DevToolsProtocolHandler::Start() {
48   BrowserThread::PostTask(
49       BrowserThread::IO, FROM_HERE,
50       NewRunnableMethod(this, &DevToolsProtocolHandler::Init));
51 }
52 
Init()53 void DevToolsProtocolHandler::Init() {
54   server_ = DevToolsRemoteListenSocket::Listen(
55       "127.0.0.1", port_, this);
56 }
57 
Stop()58 void DevToolsProtocolHandler::Stop() {
59   BrowserThread::PostTask(
60       BrowserThread::IO, FROM_HERE,
61       NewRunnableMethod(this, &DevToolsProtocolHandler::Teardown));
62   tool_to_listener_map_.clear();  // Releases all scoped_refptr's to listeners
63 }
64 
65 // Run in I/O thread
Teardown()66 void DevToolsProtocolHandler::Teardown() {
67   connection_ = NULL;
68   server_ = NULL;
69 }
70 
RegisterDestination(DevToolsRemoteListener * listener,const std::string & tool_name)71 void DevToolsProtocolHandler::RegisterDestination(
72     DevToolsRemoteListener* listener,
73     const std::string& tool_name) {
74   DCHECK(tool_to_listener_map_.find(tool_name) == tool_to_listener_map_.end());
75   tool_to_listener_map_.insert(std::make_pair(tool_name, listener));
76 }
77 
UnregisterDestination(DevToolsRemoteListener * listener,const std::string & tool_name)78 void DevToolsProtocolHandler::UnregisterDestination(
79     DevToolsRemoteListener* listener,
80     const std::string& tool_name) {
81   DCHECK(tool_to_listener_map_.find(tool_name) != tool_to_listener_map_.end());
82   DCHECK(tool_to_listener_map_.find(tool_name)->second == listener);
83   tool_to_listener_map_.erase(tool_name);
84 }
85 
HandleMessage(const DevToolsRemoteMessage & message)86 void DevToolsProtocolHandler::HandleMessage(
87     const DevToolsRemoteMessage& message) {
88   std::string tool = message.GetHeaderWithEmptyDefault(
89       DevToolsRemoteMessageHeaders::kTool);
90   ToolToListenerMap::const_iterator it = tool_to_listener_map_.find(tool);
91   if (it == tool_to_listener_map_.end()) {
92     NOTREACHED();  // an unsupported tool, bail out
93     return;
94   }
95   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
96   BrowserThread::PostTask(
97       BrowserThread::UI, FROM_HERE,
98       NewRunnableMethod(
99           it->second.get(), &DevToolsRemoteListener::HandleMessage, message));
100 }
101 
Send(const DevToolsRemoteMessage & message)102 void DevToolsProtocolHandler::Send(const DevToolsRemoteMessage& message) {
103   if (connection_ != NULL) {
104     connection_->Send(message.ToString());
105   }
106 }
107 
OnAcceptConnection(ListenSocket * connection)108 void DevToolsProtocolHandler::OnAcceptConnection(ListenSocket *connection) {
109   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
110   connection_ = connection;
111 }
112 
OnConnectionLost()113 void DevToolsProtocolHandler::OnConnectionLost() {
114   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
115   connection_ = NULL;
116   for (ToolToListenerMap::const_iterator it = tool_to_listener_map_.begin(),
117        end = tool_to_listener_map_.end();
118        it != end;
119        ++it) {
120     BrowserThread::PostTask(
121       BrowserThread::UI, FROM_HERE,
122       NewRunnableMethod(
123           it->second.get(), &DevToolsRemoteListener::OnConnectionLost));
124   }
125 }
126