1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// 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/chrome_thread.h"
#include "chrome/browser/debugger/inspectable_tab_proxy.h"
#include "chrome/browser/debugger/devtools_remote_message.h"
#include "chrome/browser/debugger/devtools_remote_listen_socket.h"
#include "chrome/browser/tab_contents/tab_contents.h"
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() {
ChromeThread::PostTask(
ChromeThread::IO, FROM_HERE,
NewRunnableMethod(this, &DevToolsProtocolHandler::Init));
}
void DevToolsProtocolHandler::Init() {
server_ = DevToolsRemoteListenSocket::Listen(
"127.0.0.1", port_, this, this);
}
void DevToolsProtocolHandler::Stop() {
ChromeThread::PostTask(
ChromeThread::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(ChromeThread::CurrentlyOn(ChromeThread::IO));
ChromeThread::PostTask(
ChromeThread::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::DidAccept(ListenSocket *server,
ListenSocket *connection) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
if (connection_ == NULL) {
connection_ = connection;
connection_->AddRef();
}
// else the connection will get deleted itself with scoped_refptr
}
void DevToolsProtocolHandler::DidRead(ListenSocket *connection,
const std::string& data) {
// Not used.
}
void DevToolsProtocolHandler::DidClose(ListenSocket *sock) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
DCHECK(connection_ == sock);
connection_ = NULL;
sock->Release();
for (ToolToListenerMap::const_iterator it = tool_to_listener_map_.begin(),
end = tool_to_listener_map_.end();
it != end;
++it) {
ChromeThread::PostTask(
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(
it->second.get(), &DevToolsRemoteListener::OnConnectionLost));
}
}
|