1 // Copyright (c) 2012 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.
5 #include "content/renderer/devtools_agent.h"
9 #include "base/lazy_instance.h"
10 #include "base/message_loop.h"
11 #include "base/process.h"
12 #include "base/string_number_conversions.h"
13 #include "content/common/devtools_messages.h"
14 #include "content/common/view_messages.h"
15 #include "content/renderer/devtools_agent_filter.h"
16 #include "content/renderer/devtools_client.h"
17 #include "content/renderer/render_view_impl.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPoint.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
26 #if defined(USE_TCMALLOC)
27 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
30 using WebKit::WebConsoleMessage
;
31 using WebKit::WebDevToolsAgent
;
32 using WebKit::WebDevToolsAgentClient
;
33 using WebKit::WebFrame
;
34 using WebKit::WebPoint
;
35 using WebKit::WebString
;
36 using WebKit::WebCString
;
37 using WebKit::WebVector
;
38 using WebKit::WebView
;
44 class WebKitClientMessageLoopImpl
45 : public WebDevToolsAgentClient::WebKitClientMessageLoop
{
47 WebKitClientMessageLoopImpl() : message_loop_(MessageLoop::current()) { }
48 virtual ~WebKitClientMessageLoopImpl() {
52 MessageLoop::ScopedNestableTaskAllower
allow(message_loop_
);
55 virtual void quitNow() {
56 message_loop_
->QuitNow();
59 MessageLoop
* message_loop_
;
62 typedef std::map
<int, DevToolsAgent
*> IdToAgentMap
;
63 base::LazyInstance
<IdToAgentMap
>::Leaky
64 g_agent_for_routing_id
= LAZY_INSTANCE_INITIALIZER
;
68 DevToolsAgent::DevToolsAgent(RenderViewImpl
* render_view
)
69 : RenderViewObserver(render_view
), is_attached_(false) {
70 g_agent_for_routing_id
.Get()[routing_id()] = this;
72 render_view
->webview()->setDevToolsAgentClient(this);
73 render_view
->webview()->devToolsAgent()->setProcessId(
74 base::Process::Current().pid());
77 DevToolsAgent::~DevToolsAgent() {
78 g_agent_for_routing_id
.Get().erase(routing_id());
81 // Called on the Renderer thread.
82 bool DevToolsAgent::OnMessageReceived(const IPC::Message
& message
) {
84 IPC_BEGIN_MESSAGE_MAP(DevToolsAgent
, message
)
85 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Attach
, OnAttach
)
86 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Reattach
, OnReattach
)
87 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Detach
, OnDetach
)
88 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DispatchOnInspectorBackend
,
89 OnDispatchOnInspectorBackend
)
90 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_InspectElement
, OnInspectElement
)
91 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_AddMessageToConsole
,
92 OnAddMessageToConsole
)
93 IPC_MESSAGE_HANDLER(DevToolsMsg_SetupDevToolsClient
, OnSetupDevToolsClient
)
94 IPC_MESSAGE_UNHANDLED(handled
= false)
97 if (message
.type() == ViewMsg_Navigate::ID
||
98 message
.type() == ViewMsg_Close::ID
)
99 ContinueProgram(); // Don't want to swallow the message.
104 void DevToolsAgent::sendMessageToInspectorFrontend(
105 const WebKit::WebString
& message
) {
106 Send(new DevToolsClientMsg_DispatchOnInspectorFrontend(routing_id(),
110 int DevToolsAgent::hostIdentifier() {
114 void DevToolsAgent::saveAgentRuntimeState(
115 const WebKit::WebString
& state
) {
116 Send(new DevToolsHostMsg_SaveAgentRuntimeState(routing_id(), state
.utf8()));
119 WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop
*
120 DevToolsAgent::createClientMessageLoop() {
121 return new WebKitClientMessageLoopImpl();
124 void DevToolsAgent::clearBrowserCache() {
125 Send(new DevToolsHostMsg_ClearBrowserCache(routing_id()));
128 void DevToolsAgent::clearBrowserCookies() {
129 Send(new DevToolsHostMsg_ClearBrowserCookies(routing_id()));
132 #if defined(USE_TCMALLOC) && !defined(OS_WIN)
133 static void AllocationVisitor(void* data
, const void* ptr
) {
134 typedef WebKit::WebDevToolsAgentClient::AllocatedObjectVisitor Visitor
;
135 Visitor
* visitor
= reinterpret_cast<Visitor
*>(data
);
136 visitor
->visitObject(ptr
);
140 void DevToolsAgent::visitAllocatedObjects(AllocatedObjectVisitor
* visitor
) {
141 #if defined(USE_TCMALLOC) && !defined(OS_WIN)
142 IterateAllocatedObjects(&AllocationVisitor
, visitor
);
147 DevToolsAgent
* DevToolsAgent::FromHostId(int host_id
) {
148 IdToAgentMap::iterator it
= g_agent_for_routing_id
.Get().find(host_id
);
149 if (it
!= g_agent_for_routing_id
.Get().end()) {
155 void DevToolsAgent::OnAttach() {
156 WebDevToolsAgent
* web_agent
= GetWebAgent();
163 void DevToolsAgent::OnReattach(const std::string
& agent_state
) {
164 WebDevToolsAgent
* web_agent
= GetWebAgent();
166 web_agent
->reattach(WebString::fromUTF8(agent_state
));
171 void DevToolsAgent::OnDetach() {
172 WebDevToolsAgent
* web_agent
= GetWebAgent();
175 is_attached_
= false;
179 void DevToolsAgent::OnDispatchOnInspectorBackend(const std::string
& message
) {
180 WebDevToolsAgent
* web_agent
= GetWebAgent();
182 web_agent
->dispatchOnInspectorBackend(WebString::fromUTF8(message
));
185 void DevToolsAgent::OnInspectElement(int x
, int y
) {
186 WebDevToolsAgent
* web_agent
= GetWebAgent();
189 web_agent
->inspectElementAt(WebPoint(x
, y
));
193 void DevToolsAgent::OnAddMessageToConsole(ConsoleMessageLevel level
,
194 const std::string
& message
) {
195 WebView
* web_view
= render_view()->GetWebView();
199 WebFrame
* main_frame
= web_view
-> mainFrame();
203 WebConsoleMessage::Level target_level
= WebConsoleMessage::LevelLog
;
205 case CONSOLE_MESSAGE_LEVEL_TIP
:
206 target_level
= WebConsoleMessage::LevelTip
;
208 case CONSOLE_MESSAGE_LEVEL_LOG
:
209 target_level
= WebConsoleMessage::LevelLog
;
211 case CONSOLE_MESSAGE_LEVEL_WARNING
:
212 target_level
= WebConsoleMessage::LevelWarning
;
214 case CONSOLE_MESSAGE_LEVEL_ERROR
:
215 target_level
= WebConsoleMessage::LevelError
;
218 main_frame
->addMessageToConsole(
219 WebConsoleMessage(target_level
, WebString::fromUTF8(message
)));
222 void DevToolsAgent::ContinueProgram() {
223 WebDevToolsAgent
* web_agent
= GetWebAgent();
224 // TODO(pfeldman): rename didNavigate to continueProgram upstream.
225 // That is in fact the purpose of the signal.
227 web_agent
->didNavigate();
230 void DevToolsAgent::OnSetupDevToolsClient() {
231 new DevToolsClient(static_cast<RenderViewImpl
*>(render_view()));
234 WebDevToolsAgent
* DevToolsAgent::GetWebAgent() {
235 WebView
* web_view
= render_view()->GetWebView();
238 return web_view
->devToolsAgent();
241 bool DevToolsAgent::IsAttached() {
245 } // namespace content