| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "content/renderer/devtools_agent.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 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" | |
| 25 | |
| 26 #if defined(USE_TCMALLOC) | |
| 27 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" | |
| 28 #endif | |
| 29 | |
| 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; | |
| 39 | |
| 40 namespace content { | |
| 41 | |
| 42 namespace { | |
| 43 | |
| 44 class WebKitClientMessageLoopImpl | |
| 45 : public WebDevToolsAgentClient::WebKitClientMessageLoop { | |
| 46 public: | |
| 47 WebKitClientMessageLoopImpl() : message_loop_(MessageLoop::current()) { } | |
| 48 virtual ~WebKitClientMessageLoopImpl() { | |
| 49 message_loop_ = NULL; | |
| 50 } | |
| 51 virtual void run() { | |
| 52 MessageLoop::ScopedNestableTaskAllower allow(message_loop_); | |
| 53 message_loop_->Run(); | |
| 54 } | |
| 55 virtual void quitNow() { | |
| 56 message_loop_->QuitNow(); | |
| 57 } | |
| 58 private: | |
| 59 MessageLoop* message_loop_; | |
| 60 }; | |
| 61 | |
| 62 typedef std::map<int, DevToolsAgent*> IdToAgentMap; | |
| 63 base::LazyInstance<IdToAgentMap>::Leaky | |
| 64 g_agent_for_routing_id = LAZY_INSTANCE_INITIALIZER; | |
| 65 | |
| 66 } // namespace | |
| 67 | |
| 68 DevToolsAgent::DevToolsAgent(RenderViewImpl* render_view) | |
| 69 : RenderViewObserver(render_view), is_attached_(false) { | |
| 70 g_agent_for_routing_id.Get()[routing_id()] = this; | |
| 71 | |
| 72 render_view->webview()->setDevToolsAgentClient(this); | |
| 73 render_view->webview()->devToolsAgent()->setProcessId( | |
| 74 base::Process::Current().pid()); | |
| 75 } | |
| 76 | |
| 77 DevToolsAgent::~DevToolsAgent() { | |
| 78 g_agent_for_routing_id.Get().erase(routing_id()); | |
| 79 } | |
| 80 | |
| 81 // Called on the Renderer thread. | |
| 82 bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) { | |
| 83 bool handled = true; | |
| 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) | |
| 95 IPC_END_MESSAGE_MAP() | |
| 96 | |
| 97 if (message.type() == ViewMsg_Navigate::ID || | |
| 98 message.type() == ViewMsg_Close::ID) | |
| 99 ContinueProgram(); // Don't want to swallow the message. | |
| 100 | |
| 101 return handled; | |
| 102 } | |
| 103 | |
| 104 void DevToolsAgent::sendMessageToInspectorFrontend( | |
| 105 const WebKit::WebString& message) { | |
| 106 Send(new DevToolsClientMsg_DispatchOnInspectorFrontend(routing_id(), | |
| 107 message.utf8())); | |
| 108 } | |
| 109 | |
| 110 int DevToolsAgent::hostIdentifier() { | |
| 111 return routing_id(); | |
| 112 } | |
| 113 | |
| 114 void DevToolsAgent::saveAgentRuntimeState( | |
| 115 const WebKit::WebString& state) { | |
| 116 Send(new DevToolsHostMsg_SaveAgentRuntimeState(routing_id(), state.utf8())); | |
| 117 } | |
| 118 | |
| 119 WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop* | |
| 120 DevToolsAgent::createClientMessageLoop() { | |
| 121 return new WebKitClientMessageLoopImpl(); | |
| 122 } | |
| 123 | |
| 124 void DevToolsAgent::clearBrowserCache() { | |
| 125 Send(new DevToolsHostMsg_ClearBrowserCache(routing_id())); | |
| 126 } | |
| 127 | |
| 128 void DevToolsAgent::clearBrowserCookies() { | |
| 129 Send(new DevToolsHostMsg_ClearBrowserCookies(routing_id())); | |
| 130 } | |
| 131 | |
| 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); | |
| 137 } | |
| 138 #endif | |
| 139 | |
| 140 void DevToolsAgent::visitAllocatedObjects(AllocatedObjectVisitor* visitor) { | |
| 141 #if defined(USE_TCMALLOC) && !defined(OS_WIN) | |
| 142 IterateAllocatedObjects(&AllocationVisitor, visitor); | |
| 143 #endif | |
| 144 } | |
| 145 | |
| 146 // static | |
| 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()) { | |
| 150 return it->second; | |
| 151 } | |
| 152 return NULL; | |
| 153 } | |
| 154 | |
| 155 void DevToolsAgent::OnAttach() { | |
| 156 WebDevToolsAgent* web_agent = GetWebAgent(); | |
| 157 if (web_agent) { | |
| 158 web_agent->attach(); | |
| 159 is_attached_ = true; | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 void DevToolsAgent::OnReattach(const std::string& agent_state) { | |
| 164 WebDevToolsAgent* web_agent = GetWebAgent(); | |
| 165 if (web_agent) { | |
| 166 web_agent->reattach(WebString::fromUTF8(agent_state)); | |
| 167 is_attached_ = true; | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 void DevToolsAgent::OnDetach() { | |
| 172 WebDevToolsAgent* web_agent = GetWebAgent(); | |
| 173 if (web_agent) { | |
| 174 web_agent->detach(); | |
| 175 is_attached_ = false; | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 void DevToolsAgent::OnDispatchOnInspectorBackend(const std::string& message) { | |
| 180 WebDevToolsAgent* web_agent = GetWebAgent(); | |
| 181 if (web_agent) | |
| 182 web_agent->dispatchOnInspectorBackend(WebString::fromUTF8(message)); | |
| 183 } | |
| 184 | |
| 185 void DevToolsAgent::OnInspectElement(int x, int y) { | |
| 186 WebDevToolsAgent* web_agent = GetWebAgent(); | |
| 187 if (web_agent) { | |
| 188 web_agent->attach(); | |
| 189 web_agent->inspectElementAt(WebPoint(x, y)); | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 void DevToolsAgent::OnAddMessageToConsole(ConsoleMessageLevel level, | |
| 194 const std::string& message) { | |
| 195 WebView* web_view = render_view()->GetWebView(); | |
| 196 if (!web_view) | |
| 197 return; | |
| 198 | |
| 199 WebFrame* main_frame = web_view-> mainFrame(); | |
| 200 if (!main_frame) | |
| 201 return; | |
| 202 | |
| 203 WebConsoleMessage::Level target_level = WebConsoleMessage::LevelLog; | |
| 204 switch (level) { | |
| 205 case CONSOLE_MESSAGE_LEVEL_TIP: | |
| 206 target_level = WebConsoleMessage::LevelTip; | |
| 207 break; | |
| 208 case CONSOLE_MESSAGE_LEVEL_LOG: | |
| 209 target_level = WebConsoleMessage::LevelLog; | |
| 210 break; | |
| 211 case CONSOLE_MESSAGE_LEVEL_WARNING: | |
| 212 target_level = WebConsoleMessage::LevelWarning; | |
| 213 break; | |
| 214 case CONSOLE_MESSAGE_LEVEL_ERROR: | |
| 215 target_level = WebConsoleMessage::LevelError; | |
| 216 break; | |
| 217 } | |
| 218 main_frame->addMessageToConsole( | |
| 219 WebConsoleMessage(target_level, WebString::fromUTF8(message))); | |
| 220 } | |
| 221 | |
| 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. | |
| 226 if (web_agent) | |
| 227 web_agent->didNavigate(); | |
| 228 } | |
| 229 | |
| 230 void DevToolsAgent::OnSetupDevToolsClient() { | |
| 231 new DevToolsClient(static_cast<RenderViewImpl*>(render_view())); | |
| 232 } | |
| 233 | |
| 234 WebDevToolsAgent* DevToolsAgent::GetWebAgent() { | |
| 235 WebView* web_view = render_view()->GetWebView(); | |
| 236 if (!web_view) | |
| 237 return NULL; | |
| 238 return web_view->devToolsAgent(); | |
| 239 } | |
| 240 | |
| 241 bool DevToolsAgent::IsAttached() { | |
| 242 return is_attached_; | |
| 243 } | |
| 244 | |
| 245 } // namespace content | |
| OLD | NEW |