| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/devtools/devtools_agent.h" | 5 #include "content/renderer/devtools/devtools_agent.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/process/process_handle.h" | |
| 12 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 14 #include "content/common/devtools_messages.h" | 13 #include "content/common/devtools_messages.h" |
| 15 #include "content/common/frame_messages.h" | 14 #include "content/common/frame_messages.h" |
| 16 #include "content/common/view_messages.h" | 15 #include "content/common/view_messages.h" |
| 17 #include "content/renderer/devtools/devtools_agent_filter.h" | |
| 18 #include "content/renderer/devtools/devtools_client.h" | 16 #include "content/renderer/devtools/devtools_client.h" |
| 19 #include "content/renderer/render_view_impl.h" | 17 #include "content/renderer/render_frame_impl.h" |
| 18 #include "content/renderer/render_widget.h" |
| 20 #include "ipc/ipc_channel.h" | 19 #include "ipc/ipc_channel.h" |
| 21 #include "third_party/WebKit/public/platform/WebPoint.h" | 20 #include "third_party/WebKit/public/platform/WebPoint.h" |
| 22 #include "third_party/WebKit/public/platform/WebString.h" | 21 #include "third_party/WebKit/public/platform/WebString.h" |
| 23 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | 22 #include "third_party/WebKit/public/web/WebConsoleMessage.h" |
| 24 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | |
| 25 #include "third_party/WebKit/public/web/WebDevToolsAgent.h" | 23 #include "third_party/WebKit/public/web/WebDevToolsAgent.h" |
| 26 #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" | 24 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 27 #include "third_party/WebKit/public/web/WebFrame.h" | |
| 28 #include "third_party/WebKit/public/web/WebSettings.h" | |
| 29 #include "third_party/WebKit/public/web/WebView.h" | |
| 30 | 25 |
| 31 #if defined(USE_TCMALLOC) | 26 #if defined(USE_TCMALLOC) |
| 32 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" | 27 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" |
| 33 #endif | 28 #endif |
| 34 | 29 |
| 35 using blink::WebConsoleMessage; | 30 using blink::WebConsoleMessage; |
| 36 using blink::WebDevToolsAgent; | 31 using blink::WebDevToolsAgent; |
| 37 using blink::WebDevToolsAgentClient; | 32 using blink::WebDevToolsAgentClient; |
| 38 using blink::WebFrame; | 33 using blink::WebLocalFrame; |
| 39 using blink::WebPoint; | 34 using blink::WebPoint; |
| 40 using blink::WebString; | 35 using blink::WebString; |
| 41 using blink::WebCString; | |
| 42 using blink::WebVector; | |
| 43 using blink::WebView; | |
| 44 | 36 |
| 45 using base::trace_event::TraceLog; | 37 using base::trace_event::TraceLog; |
| 46 using base::trace_event::TraceOptions; | 38 using base::trace_event::TraceOptions; |
| 47 | 39 |
| 48 namespace content { | 40 namespace content { |
| 49 | 41 |
| 50 base::subtle::AtomicWord DevToolsAgent::event_callback_; | |
| 51 | |
| 52 namespace { | 42 namespace { |
| 53 | 43 |
| 54 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; | 44 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; |
| 55 | 45 |
| 56 class WebKitClientMessageLoopImpl | 46 class WebKitClientMessageLoopImpl |
| 57 : public WebDevToolsAgentClient::WebKitClientMessageLoop { | 47 : public WebDevToolsAgentClient::WebKitClientMessageLoop { |
| 58 public: | 48 public: |
| 59 WebKitClientMessageLoopImpl() : message_loop_(base::MessageLoop::current()) {} | 49 WebKitClientMessageLoopImpl() : message_loop_(base::MessageLoop::current()) {} |
| 60 virtual ~WebKitClientMessageLoopImpl() { message_loop_ = NULL; } | 50 virtual ~WebKitClientMessageLoopImpl() { message_loop_ = NULL; } |
| 61 virtual void run() { | 51 virtual void run() { |
| 62 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_); | 52 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_); |
| 63 message_loop_->Run(); | 53 message_loop_->Run(); |
| 64 } | 54 } |
| 65 virtual void quitNow() { | 55 virtual void quitNow() { |
| 66 message_loop_->QuitNow(); | 56 message_loop_->QuitNow(); |
| 67 } | 57 } |
| 68 private: | 58 private: |
| 69 base::MessageLoop* message_loop_; | 59 base::MessageLoop* message_loop_; |
| 70 }; | 60 }; |
| 71 | 61 |
| 72 typedef std::map<int, DevToolsAgent*> IdToAgentMap; | 62 typedef std::map<int, DevToolsAgent*> IdToAgentMap; |
| 73 base::LazyInstance<IdToAgentMap>::Leaky | 63 base::LazyInstance<IdToAgentMap>::Leaky |
| 74 g_agent_for_routing_id = LAZY_INSTANCE_INITIALIZER; | 64 g_agent_for_routing_id = LAZY_INSTANCE_INITIALIZER; |
| 75 | 65 |
| 76 } // namespace | 66 } // namespace |
| 77 | 67 |
| 78 DevToolsAgent::DevToolsAgent(RenderFrame* main_render_frame) | 68 DevToolsAgent::DevToolsAgent(RenderFrameImpl* frame) |
| 79 : RenderFrameObserver(main_render_frame), | 69 : RenderFrameObserver(frame), |
| 80 is_attached_(false), | 70 is_attached_(false), |
| 81 is_devtools_client_(false), | 71 is_devtools_client_(false), |
| 82 paused_in_mouse_move_(false), | 72 paused_in_mouse_move_(false), |
| 83 main_render_frame_(main_render_frame) { | 73 frame_(frame) { |
| 84 g_agent_for_routing_id.Get()[routing_id()] = this; | 74 g_agent_for_routing_id.Get()[routing_id()] = this; |
| 85 | 75 frame_->GetWebFrame()->setDevToolsAgentClient(this); |
| 86 main_render_frame_->GetRenderView()->GetWebView()->setDevToolsAgentClient( | |
| 87 this); | |
| 88 } | 76 } |
| 89 | 77 |
| 90 DevToolsAgent::~DevToolsAgent() { | 78 DevToolsAgent::~DevToolsAgent() { |
| 91 g_agent_for_routing_id.Get().erase(routing_id()); | 79 g_agent_for_routing_id.Get().erase(routing_id()); |
| 92 resetTraceEventCallback(); | |
| 93 } | 80 } |
| 94 | 81 |
| 95 // Called on the Renderer thread. | 82 // Called on the Renderer thread. |
| 96 bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) { | 83 bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) { |
| 97 bool handled = true; | 84 bool handled = true; |
| 98 IPC_BEGIN_MESSAGE_MAP(DevToolsAgent, message) | 85 IPC_BEGIN_MESSAGE_MAP(DevToolsAgent, message) |
| 99 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Attach, OnAttach) | 86 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Attach, OnAttach) |
| 100 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Reattach, OnReattach) | 87 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Reattach, OnReattach) |
| 101 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Detach, OnDetach) | 88 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Detach, OnDetach) |
| 102 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DispatchOnInspectorBackend, | 89 IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DispatchOnInspectorBackend, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 116 } | 103 } |
| 117 | 104 |
| 118 void DevToolsAgent::sendProtocolMessage( | 105 void DevToolsAgent::sendProtocolMessage( |
| 119 int call_id, | 106 int call_id, |
| 120 const blink::WebString& message, | 107 const blink::WebString& message, |
| 121 const blink::WebString& state_cookie) { | 108 const blink::WebString& state_cookie) { |
| 122 SendChunkedProtocolMessage( | 109 SendChunkedProtocolMessage( |
| 123 this, routing_id(), call_id, message.utf8(), state_cookie.utf8()); | 110 this, routing_id(), call_id, message.utf8(), state_cookie.utf8()); |
| 124 } | 111 } |
| 125 | 112 |
| 126 long DevToolsAgent::processId() { | |
| 127 return base::GetCurrentProcId(); | |
| 128 } | |
| 129 | |
| 130 int DevToolsAgent::debuggerId() { | |
| 131 return routing_id(); | |
| 132 } | |
| 133 | |
| 134 blink::WebDevToolsAgentClient::WebKitClientMessageLoop* | 113 blink::WebDevToolsAgentClient::WebKitClientMessageLoop* |
| 135 DevToolsAgent::createClientMessageLoop() { | 114 DevToolsAgent::createClientMessageLoop() { |
| 136 return new WebKitClientMessageLoopImpl(); | 115 return new WebKitClientMessageLoopImpl(); |
| 137 } | 116 } |
| 138 | 117 |
| 139 void DevToolsAgent::willEnterDebugLoop() { | 118 void DevToolsAgent::willEnterDebugLoop() { |
| 140 paused_in_mouse_move_ = | 119 if (RenderWidget* widget = frame_->GetRenderWidget()) |
| 141 GetRenderViewImpl()->SendAckForMouseMoveFromDebugger(); | 120 paused_in_mouse_move_ = widget->SendAckForMouseMoveFromDebugger(); |
| 142 } | 121 } |
| 143 | 122 |
| 144 void DevToolsAgent::didExitDebugLoop() { | 123 void DevToolsAgent::didExitDebugLoop() { |
| 145 if (paused_in_mouse_move_) { | 124 if (!paused_in_mouse_move_) |
| 146 GetRenderViewImpl()->IgnoreAckForMouseMoveFromDebugger(); | 125 return; |
| 126 if (RenderWidget* widget = frame_->GetRenderWidget()) { |
| 127 widget->IgnoreAckForMouseMoveFromDebugger(); |
| 147 paused_in_mouse_move_ = false; | 128 paused_in_mouse_move_ = false; |
| 148 } | 129 } |
| 149 } | 130 } |
| 150 | 131 |
| 151 void DevToolsAgent::resetTraceEventCallback() | |
| 152 { | |
| 153 TraceLog::GetInstance()->SetEventCallbackDisabled(); | |
| 154 base::subtle::NoBarrier_Store(&event_callback_, 0); | |
| 155 } | |
| 156 | |
| 157 void DevToolsAgent::setTraceEventCallback(const WebString& category_filter, | |
| 158 TraceEventCallback cb) { | |
| 159 TraceLog* trace_log = TraceLog::GetInstance(); | |
| 160 base::subtle::NoBarrier_Store(&event_callback_, | |
| 161 reinterpret_cast<base::subtle::AtomicWord>(cb)); | |
| 162 if (!!cb) { | |
| 163 trace_log->SetEventCallbackEnabled( | |
| 164 base::trace_event::CategoryFilter(category_filter.utf8()), | |
| 165 TraceEventCallbackWrapper); | |
| 166 } else { | |
| 167 trace_log->SetEventCallbackDisabled(); | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 void DevToolsAgent::enableTracing(const WebString& category_filter) { | 132 void DevToolsAgent::enableTracing(const WebString& category_filter) { |
| 172 TraceLog* trace_log = TraceLog::GetInstance(); | 133 TraceLog* trace_log = TraceLog::GetInstance(); |
| 173 trace_log->SetEnabled( | 134 trace_log->SetEnabled( |
| 174 base::trace_event::CategoryFilter(category_filter.utf8()), | 135 base::trace_event::CategoryFilter(category_filter.utf8()), |
| 175 TraceLog::RECORDING_MODE, TraceOptions()); | 136 TraceLog::RECORDING_MODE, TraceOptions()); |
| 176 } | 137 } |
| 177 | 138 |
| 178 void DevToolsAgent::disableTracing() { | 139 void DevToolsAgent::disableTracing() { |
| 179 TraceLog::GetInstance()->SetDisabled(); | 140 TraceLog::GetInstance()->SetDisabled(); |
| 180 } | 141 } |
| 181 | 142 |
| 182 // static | 143 // static |
| 183 void DevToolsAgent::TraceEventCallbackWrapper( | |
| 184 base::TimeTicks timestamp, | |
| 185 char phase, | |
| 186 const unsigned char* category_group_enabled, | |
| 187 const char* name, | |
| 188 unsigned long long id, | |
| 189 int num_args, | |
| 190 const char* const arg_names[], | |
| 191 const unsigned char arg_types[], | |
| 192 const unsigned long long arg_values[], | |
| 193 unsigned char flags) { | |
| 194 TraceEventCallback callback = | |
| 195 reinterpret_cast<TraceEventCallback>( | |
| 196 base::subtle::NoBarrier_Load(&event_callback_)); | |
| 197 if (callback) { | |
| 198 double timestamp_seconds = (timestamp - base::TimeTicks()).InSecondsF(); | |
| 199 callback(phase, category_group_enabled, name, id, num_args, | |
| 200 arg_names, arg_types, arg_values, flags, timestamp_seconds); | |
| 201 } | |
| 202 } | |
| 203 | |
| 204 // static | |
| 205 DevToolsAgent* DevToolsAgent::FromRoutingId(int routing_id) { | 144 DevToolsAgent* DevToolsAgent::FromRoutingId(int routing_id) { |
| 206 IdToAgentMap::iterator it = g_agent_for_routing_id.Get().find(routing_id); | 145 IdToAgentMap::iterator it = g_agent_for_routing_id.Get().find(routing_id); |
| 207 if (it != g_agent_for_routing_id.Get().end()) { | 146 if (it != g_agent_for_routing_id.Get().end()) { |
| 208 return it->second; | 147 return it->second; |
| 209 } | 148 } |
| 210 return NULL; | 149 return NULL; |
| 211 } | 150 } |
| 212 | 151 |
| 213 // static | 152 // static |
| 214 void DevToolsAgent::SendChunkedProtocolMessage( | 153 void DevToolsAgent::SendChunkedProtocolMessage( |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 WebDevToolsAgent* web_agent = GetWebAgent(); | 220 WebDevToolsAgent* web_agent = GetWebAgent(); |
| 282 if (web_agent) { | 221 if (web_agent) { |
| 283 web_agent->attach(WebString::fromUTF8(host_id)); | 222 web_agent->attach(WebString::fromUTF8(host_id)); |
| 284 web_agent->inspectElementAt(WebPoint(x, y)); | 223 web_agent->inspectElementAt(WebPoint(x, y)); |
| 285 is_attached_ = true; | 224 is_attached_ = true; |
| 286 } | 225 } |
| 287 } | 226 } |
| 288 | 227 |
| 289 void DevToolsAgent::OnAddMessageToConsole(ConsoleMessageLevel level, | 228 void DevToolsAgent::OnAddMessageToConsole(ConsoleMessageLevel level, |
| 290 const std::string& message) { | 229 const std::string& message) { |
| 291 WebView* web_view = main_render_frame_->GetRenderView()->GetWebView(); | 230 WebLocalFrame* web_frame = frame_->GetWebFrame(); |
| 292 if (!web_view) | 231 if (!web_frame) |
| 293 return; | |
| 294 | |
| 295 WebFrame* main_frame = web_view->mainFrame(); | |
| 296 if (!main_frame) | |
| 297 return; | 232 return; |
| 298 | 233 |
| 299 WebConsoleMessage::Level target_level = WebConsoleMessage::LevelLog; | 234 WebConsoleMessage::Level target_level = WebConsoleMessage::LevelLog; |
| 300 switch (level) { | 235 switch (level) { |
| 301 case CONSOLE_MESSAGE_LEVEL_DEBUG: | 236 case CONSOLE_MESSAGE_LEVEL_DEBUG: |
| 302 target_level = WebConsoleMessage::LevelDebug; | 237 target_level = WebConsoleMessage::LevelDebug; |
| 303 break; | 238 break; |
| 304 case CONSOLE_MESSAGE_LEVEL_LOG: | 239 case CONSOLE_MESSAGE_LEVEL_LOG: |
| 305 target_level = WebConsoleMessage::LevelLog; | 240 target_level = WebConsoleMessage::LevelLog; |
| 306 break; | 241 break; |
| 307 case CONSOLE_MESSAGE_LEVEL_WARNING: | 242 case CONSOLE_MESSAGE_LEVEL_WARNING: |
| 308 target_level = WebConsoleMessage::LevelWarning; | 243 target_level = WebConsoleMessage::LevelWarning; |
| 309 break; | 244 break; |
| 310 case CONSOLE_MESSAGE_LEVEL_ERROR: | 245 case CONSOLE_MESSAGE_LEVEL_ERROR: |
| 311 target_level = WebConsoleMessage::LevelError; | 246 target_level = WebConsoleMessage::LevelError; |
| 312 break; | 247 break; |
| 313 } | 248 } |
| 314 main_frame->addMessageToConsole( | 249 web_frame->addMessageToConsole( |
| 315 WebConsoleMessage(target_level, WebString::fromUTF8(message))); | 250 WebConsoleMessage(target_level, WebString::fromUTF8(message))); |
| 316 } | 251 } |
| 317 | 252 |
| 318 void DevToolsAgent::ContinueProgram() { | 253 void DevToolsAgent::ContinueProgram() { |
| 319 WebDevToolsAgent* web_agent = GetWebAgent(); | 254 WebDevToolsAgent* web_agent = GetWebAgent(); |
| 320 if (web_agent) | 255 if (web_agent) |
| 321 web_agent->continueProgram(); | 256 web_agent->continueProgram(); |
| 322 } | 257 } |
| 323 | 258 |
| 324 void DevToolsAgent::OnSetupDevToolsClient() { | 259 void DevToolsAgent::OnSetupDevToolsClient() { |
| 260 DCHECK(!frame_->GetWebFrame() || !frame_->GetWebFrame()->parent()); |
| 325 // We only want to register once per render view. | 261 // We only want to register once per render view. |
| 326 if (is_devtools_client_) | 262 if (is_devtools_client_) |
| 327 return; | 263 return; |
| 328 is_devtools_client_ = true; | 264 is_devtools_client_ = true; |
| 329 new DevToolsClient(main_render_frame_); | 265 new DevToolsClient(frame_); |
| 330 } | 266 } |
| 331 | 267 |
| 332 WebDevToolsAgent* DevToolsAgent::GetWebAgent() { | 268 WebDevToolsAgent* DevToolsAgent::GetWebAgent() { |
| 333 WebView* web_view = main_render_frame_->GetRenderView()->GetWebView(); | 269 WebLocalFrame* web_frame = frame_->GetWebFrame(); |
| 334 if (!web_view) | 270 return web_frame ? web_frame->devToolsAgent() : nullptr; |
| 335 return NULL; | |
| 336 return web_view->devToolsAgent(); | |
| 337 } | |
| 338 | |
| 339 RenderViewImpl* DevToolsAgent::GetRenderViewImpl() { | |
| 340 return static_cast<RenderViewImpl*>(main_render_frame_->GetRenderView()); | |
| 341 } | 271 } |
| 342 | 272 |
| 343 bool DevToolsAgent::IsAttached() { | 273 bool DevToolsAgent::IsAttached() { |
| 344 return is_attached_; | 274 return is_attached_; |
| 345 } | 275 } |
| 346 | 276 |
| 347 } // namespace content | 277 } // namespace content |
| OLD | NEW |